<!--
@ 作者: han2015
@ 时间: 2025-05-12 15:39:13
@ 备注: 文档管理组件
-->
<script lang="ts" setup>
import { getExpirTime, getFileIcon, readableSize,fileType} from "./tools"
import sharePermission from './sharePermission.vue';
import { useUserStore } from "@/store/modules/user";
import { getMatterList,postCreateDir,postDelMatter,postCreateShare,postMatterRename,
  postDelMatBatch,getMySpaces,doCreateSpace,getRecyclingList} from "@/api/doc/index"
import { matterPage,matterInfo,respCreateShare,matterTree, doFileUpload,matterPermit} from "@/api/doc/type"
import { h } from 'vue'
import router from "@/router";
import {
  Delete,View,Download,Share,Search,Edit,
  Avatar,Plus,Grid,List,
  Setting,
  Bell,
} from '@element-plus/icons-vue'
import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,
    UploadFiles,ElPagination,ElTree,TreeNode,ElDropdown,ElDropdownItem} from "element-plus";
import preview from './preview.vue';
import uploadlog from './uploadlog.vue';
import space from './space.vue';
import spacePermission from './spacePermission.vue';
import SvgIcon from "@/components/SvgIcon/index.vue";
import {doDelSpace,doAccessManage,doCreateAiagent} from "@/api/doc/space"
import Space from "./space.vue";
import Logpanel from "./logpanel.vue";

//TODO: add file icons  done!
//TODO: click on table-item， 1）preview on file .....................
//                            2) go into dir-item  done!
//                            3）search file   done!
//TODO: rename matters  done!

//TODO: get share list  done！
//TODO: visit share link  done!

//TODO: select on table items for batch opts  1)delete  done!
//                                            2)share done!
//TODO: test on Pagination    done!

const userStore = useUserStore();
const uid=btoa("p0"+userStore.userInfoCont.userId);
const rawUid="p0"+userStore.userInfoCont.userId
const siteHost=document.location.origin; 
const apiURL=import.meta.env.VITE_APP_BASE_API+"/hxpan/api"

const matterList = ref<matterInfo[]>([])
const searchname=ref("")
const newdirName=ref("") //创建新目录时的目录名
const currentHoverRow=ref("") //table 行的按钮控制
const selectedValue = ref("sixhour") //分享弹窗的世间变量
const tabSelected=ref<matterInfo[]>([]) //table组件多选数据维护
//to support tree mode refactor
const treeData=ref<matterTree[]>([])//{name:'个人空间',uuid:'root',children:[]}
const treeRef = ref();
const currentNode=ref<matterTree>({})  //打开的路径层次
const officeHost=import.meta.env.VITE_OFFICE_HOST
const dynamicVNode = ref<VNode | null>(null) //permission 组件的父组件


const multipleTableRef = ref<TableInstance>()
const paginInfo = ref({ page: 0, total: 0 })

const PRIVATESPACE = ref(true) //是空间状态的控制 2种：私有云盘和共享空间
const SpaceID= ref<{name:string,uuid:string,userUuid:string,manager:boolean,permits:matterPermit}>({})  //当前space的id
const spaceEleRef = ref() //space组件的引用,它与spaceTreeRef没有父子关系，反而是为了处理spaceTree的操作而创建的该变量
const spaceTreeData=ref<matterTree[]>([])//{name:'个人空间',uuid:'root',children:[]}
const spaceTreeRef = ref(); //space的树树组件的引用
let spaceNodeUid="" //用来判断树组件的展开和关闭，如何只是展开和关闭的点击事件不在刷新，通currentNode的作用

const modListOrGrild=ref(true)
const modRecycling=ref(false)
//进度条
const percentage=ref(0)
const onprogress=ref(false)
const tabName = ref('main')
const logTableRef = ref() //上传日志页面的引用


const Departs = computed(() => {
    return `${'p0'+userStore.userInfoCont.userId},${userStore.userInfoCont.company},${userStore.userInfoCont.department},${userStore.userInfoCont.organization}`
})

const uploadFormData = computed(() => {
  return {
    userUuid: uid, // 用户的uuid
    puuid: currentNode.value.uuid, // 父目录的uuid，基目录为root
  }
});
const fileList=ref([])//upload files

//--------------单文件分享-------------
function onShareMatter(row?:matterInfo){
  const showSharePermission=ref(false)
  let permited =""
  let infos=""
  let _len=0
  ElMessageBox({
    title: row?.name+' 请选择分享有效时间',
    message: () => h('div',{style:{ width:'660px'}},[
      h(ElSelect, 
      {
        defaultFirstOption:true,   
        modelValue: selectedValue.value,
        'onUpdate:modelValue': (value) => {
            selectedValue.value = value
        },
        valueKey: "value", 
        fallbackPlacements:['bottom-start'],
        style: { width:'360px' }
    },() => [
      h(ElOption, { label: '六小时',key: 'sixhour', value: 'sixhour' }),
      h(ElOption, { label: '一 天', key: 'oneday', value: 'oneday' }),
      h(ElOption, { label: '三 天', key: 'threeday', value: 'threeday' }),
      h(ElOption, { label: '一 周', key: 'oneweek', value: 'oneweek' }),
      h(ElOption, { label: '一 月', key: 'onemonth', value: 'onemonth' }),
      h(ElOption, { label: '三 月', key: 'threemonth', value: 'threemonth' }),
      h(ElOption, { label: '永 久', key: 'permanent', value: 'permanent' }),
    ]),
    h(ElButton, {
      style: "width:30px;margin:0 10px;",
      icon: Avatar,
      onClick: () => {
      showSharePermission.value = true
      }
    }),
    h(sharePermission, {
      uid: uid,
      uuid: row?.uuid ?? "",
      modelValue: showSharePermission.value,
      confirmFunc: (_list: string[],_infos:string[]) => {
        // 组织权限数据
        _len=_list.length
        permited = btoa(_list.join("|"))
        infos=_infos.join("|"),
        showSharePermission.value = false
      },
      closeFunc: () => {
        showSharePermission.value = false
      }
    })
  ]
  ),
    showCancelButton: true
  }).then(() => {
    let param;
    if (row){
      param={matterUuids:row.uuid,expireInfinity:false,expireTime:"",
        permitList:permited,len:_len,permitInfos:infos}
    }else if (tabSelected.value.length>1){
      param={matterUuids:tabSelected.value.map((item:matterInfo)=>item.uuid).join(","),expireInfinity:false,expireTime:"",
        permitList:permited,len:_len,permitInfos:infos}
    }

    if(param){
      if(selectedValue.value==='permanent'){
        param.expireInfinity=true
      }else{
        param.expireTime=getExpirTime(selectedValue.value)
      }
    
      postCreateShare(uid,param).then((resp)=>{
        showShareMessage(resp.data)
      })
      onLoadMatterList()
      selectedValue.value="sixhour"
    }
  }).catch(() => {
    selectedValue.value='sixhour'
    return
  })
}

function showShareMessage(row:respCreateShare){
  let _shareURL=`${siteHost}/#/doc/share/?uuid=${row.uuid}&code=${row.code}`
  ElMessageBox({
    title: '分享详情',
    customStyle: { '--el-messagebox-width':'800px',padding:'40px'},
    message: () => h('div',{style:{display:'flex','flex-direction':'column','line-height':'34px', width:'600px'}},[
     h(ElText,{style:{'align-self':'flex-start'}},()=>row.name),
     h(ElText,{style:{'align-self':'flex-start'}},()=>"失效时间："+row.expireTime),
     h(ElText,{style:{'align-self':'flex-start'}},()=>"链接："+_shareURL)
    ]),
    confirmButtonText: '复制分享链接',
    showCancelButton: true
  }).then(()=>{
    navigator.clipboard.writeText(_shareURL)
  }).catch(() => {});
}

//----------------------------------------

function onDelNodeMatter(row:matterInfo){
  onDelMatter(row,true)
}
//删除
function onDelMatter(row:matterInfo,dir?:boolean){
  if (row.uuid){
    ElMessageBox.confirm(`确认删除( ${row.name}) ?删除后不可恢复！取消则放弃删除操作。`, "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(()=>{
      postDelMatter(uid,{
        "uuid":row.uuid
      }).then(()=>{
        if (row.dir || dir) {
          const node = treeRef.value.getNode(row.uuid)
          if (node) {
            treeRef.value.remove(node)
          }
          currentNode.value.uuid = row.puuid ?? "root"
        }
        onLoadMatterList()  
      })
    })
  }
}

function onDelMatBatch(){
  ElMessageBox.confirm("确认删除选择的内容?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    postDelMatBatch(uid,{
      "uuids":tabSelected.value.map((item:matterInfo)=>item.uuid).join(",")
    }).then(()=>{
      router.replace({ query: { t: Date.now() } })
    })
  })
}

function onDownload(row:matterInfo){
  ElMessageBox.confirm("确认下载此数据项?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    if (row.uuid){
      let _url= apiURL+`/alien/download/${row.uuid}/${row.name}`
      window.open(_url)
    }
  })
}

function getImagePreivewURL(_uuid:string,_name:string){
  return `${apiURL}/alien/preview/${_uuid}/${_name}?ir=fill_100_100`
}

function getImageDownloadURL(_uuid:string,_name:string){
  return `${apiURL}/alien/preview/${_uuid}/${_name}`
}

function onMatterRename(row:matterInfo){
  const newname=ref(row.name)
  ElMessageBox({
    title:"请输入新的文件名",
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    message: () => h(ElInput, {
      style: { width:'360px' },  
      modelValue: newname.value,
      'onUpdate:modelValue': (val) => {
        newname.value = val
      },
    }),
  }).then(() => {
    if(newname.value&&newname.value!=""){
      postMatterRename(uid,{
        uuid:row.uuid,
        name:newname.value,
      }).then(()=>onLoadMatterList())
    }
  })
}

//加载文件列表
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 showRecycling(){
  tabName.value="main"
  modRecycling.value=true
  currentNode.value={} //清空当前节点
  if(!PRIVATESPACE.value) { //共享空间模式要切换到个人空间
    PRIVATESPACE.value=true
  }

  getRecyclingList(uid,{}).then((resp)=>{
    paginInfo.value={total:1,page:0}
    matterList.value=resp.data
  })
}

//获取上传日志
function showlogs(){
  currentNode.value={} //清空当前节点
  if(!PRIVATESPACE.value) { //共享空间模式要切换到个人空间
    PRIVATESPACE.value=true
  }

  logTableRef.value.loadLogList()
}

//恢复删除文件
function restoreMatter(row:matterInfo){
  if (row.uuid){
    ElMessageBox.confirm(`确认要恢复( ${row.name}) ?`, "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(()=>{
      postDelMatter(uid,{
        "uuid":row.uuid,
        "restore":"true",
      }).then(()=>{
        ElMessage({
          message: '已成功恢复文件，请在个人空间查看。',
          type: 'success',
          plain: true,
        })
      })
    })
  }
}

//加载目录文件列表
function onLoadMatterList(){
  //重置进度条
  percentage.value=0 
  onprogress.value=false

  let _page: matterPage = {
    page: paginInfo.value.page,
    pageSize: 50,
    orderCreateTime: "DESC",
    orderDir: "DESC",
    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
    //2025-08-07: 保持space一样，文件夹一并显示
    // .filter((item)=>{
    //   return !item.dir
    // })
  })
}
//----------for dir-----------
function createDir(){
  if(matterList.value.length>0){
    //防止多次新建目录
    if (matterList.value[0].name=="") return;
  }
  matterList.value?.unshift({
    name:"",
    userUuid:uid,
    puuid:"",
    uuid:"",
    dir:true,
    size:0,
    deleted:false,
  })
}

function onCreateDir(){
  postCreateDir(uid,{
    userUuid:uid,
    puuid:currentNode.value.uuid,
    name:newdirName.value,
  }).then((resp)=> {
    newdirName.value=""
    //调用tree的append方法
    treeRef.value.append(
      {uuid:resp.data.uuid,dir:false,name:resp.data.name,puuid:resp.data.puuid},
      currentNode.value.uuid
    )
    matterList.value?.shift() //删除头部的空位
    matterList.value?.push(resp.data) //把新建的添加到最后
  })
  .catch((e)=>{
    ElMessage.error(e.msg)
  })
}

function onDBclickMatter(row:matterInfo){
  if(row.dir){
    onNodeClick(row as matterTree,null,null,null)
  }else{
    onPrivateView(row)
  }
}

//树节点展开
function onNodeExpand(node: TreeNode, resolve: (data: matterTree[]) => void, reject: () => void) {
    modRecycling.value=false
    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",
        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((val) => {
          const copy = structuredClone(val)
          copy.dir = !copy.dir
          return copy
        })

        resolve(node_data)
    }).catch(() => reject())
    
}
//树节点单击
function onNodeClick(data:matterTree,node:TreeNode,self:any,env:any){
  tabName.value="main"
  modRecycling.value=false
  if(!PRIVATESPACE.value) {
    PRIVATESPACE.value=true
  }
  if (data){
    if (currentNode.value.uuid === data.uuid) return;
    //const cuuid = data.uuid
    currentNode.value = data
  }else{
    currentNode.value={uuid:"root"}
  }

  onLoadMatterList()
  return
  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
      }
  })
}

function updateListOrGrid(val:boolean){
  modListOrGrild.value=val
  if(val){
    localStorage.setItem("listOrGrid","true")
  }else{
    localStorage.setItem("listOrGrid","false")
  }
}

//文件预览
function onPrivateView(row:matterInfo){
  if(row.dir){
    alert("目录不支持预览")
    return
  }

  let _token=document.cookie.match(/hxpan=([\w-]*)/)
  if (_token&&_token.length>1){
    _token=_token[1]
  }

  const _type=fileType(row.name!)
  if(_type!==""){ //office file
    const info =btoa(encodeURIComponent(`${row.name}`)) //预览模式不需要绝对路径，只核对一下文件名即可
    const _url=`${siteHost}${apiURL}/alien/download/${row.uuid}/${row.name}?access_token=${_token}`
    //前半部分内容是为了校验信息，主要内容是fileurl
    window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank")
    return
  }

  const a = `${row.uuid}${row.name}`
  const _url=`${siteHost}${apiURL}/alien/download/${row.uuid}/${row.name}?access_token=${_token}&fullfilename=${a}`

  dynamicVNode.value=h(preview,{
    url:`${officeHost}/kkpreview/onlinePreview?url=`+window.btoa(unescape(encodeURIComponent(_url))),
    closeFunc:()=>dynamicVNode.value=null
  })
}

//onlyoffice在线编辑
async function onlyOfficeEdit(row:matterInfo){
  const _type=fileType(row.name!)
  if(_type===""){
    alert("暂不支持该类型编辑")
    return 
  }
  
  let _token=document.cookie.match(/hxpan=([\w-]*)/)
  if (_token&&_token.length>1){
    _token=_token[1]
  }

  ElMessageBox.confirm("线上资源有限，确定继续线上编辑吗", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    //office file
    //base64 encode for MASK
    const _verify = btoa(row.uuid.match(/(\w+-\w+)/)![0]+"true") //增加一个权限验证的标记
    const info =btoa(encodeURIComponent(`${row.userUuid}/root${row.path}`)) //编辑模式必须要全路径
    const _url=`${siteHost}${apiURL}/alien/download/${row.uuid}/${row.name}?access_token=${_token}`
    window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&verify=${_verify}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank") 
  })
}

//--------------UPGRADE: multy file upload section----------------

//自定义上传，目的是支持多文件上传, 使用html原生组件，是为了解决并发问题
async function onCustomUpload(e:Event){
  const files = e.target!.files??[]
  onprogress.value=true
  const count=files.length
  let result=""
   for(let index = 0; index < count; index++){
    onprogress.value=true
    const ff = files[index]
    await handleSingleFile(ff).catch((err)=>{
      console.log(err)
      result+=err
    })
    percentage.value = Number(((index + 1) / count).toPrecision(2)) * 100
  }
  if(result!=""){
    dynamicVNode.value=h(uploadlog,{
      content:result
    })
  }

  onLoadMatterList() //刷新
}


async function handleSingleFile(ff:File){
  const fields=new FormData()
  fields.append("userUuid",uploadFormData.value.userUuid)
  fields.append("puuid",uploadFormData.value.puuid)
  fields.append("file",ff)
  
  const res = await doFileUpload(fields,'/hxpan/api/matter/upload')
  if(res.code!=200){
    console.log(ff.name+"上传失败! ")
    throw new Error(ff.name+"上传失败!<br> ")
  }
}

//文件夹上传，原理：自定义的input组件，一次拿到所有需要上传的文件列表，然后依次上传
//能减少并发问题
async function uploadFolder(e:Event){
  onprogress.value=true
  const files = e.target!.files??[]
  const count=files.length
  let result=""
  for(let index = 0; index < count; index++){
    onprogress.value=true
    const f = files[index]
    await handleFolderFile(f).catch((err)=>{
      console.log(err)
      result+= (f as File).name+"上传失败<br>"
    })
    percentage.value =  Number(((index + 1) / count).toPrecision(2)) * 100
  }
  if(result!=""){
    dynamicVNode.value=h(uploadlog,{
      content:result
    })
  }
  
  onLoadMatterList() //刷新
}

async function handleFolderFile(option:File){
  //根据路径，来判断需不需要重建目录
  const _path = option.webkitRelativePath
  const _dir=_path.replace(/\/[^/]+\w+$/,"") //只保留文件夹目录,[^/]就是用来限制，只能是最后一个目录
  const node = matterList.value.filter((item)=>{
    return item.dir && _dir.endsWith(item.name!)
  })

  let puuid=""
  //说明是新的目录，需要新建；如果存在，直接上传文件即可
  if(node.length==0){
    const subs= await doCreateMultyDir(_dir,currentNode.value.uuid)
    matterList.value.push(...subs) //这里如果子文件夹多的时候，可能会造成第一级路径多次创建，只是造成资源浪费，问题不大
    
    const newnodes=matterList.value.filter((item)=>{
      return item.dir && _dir.endsWith(item.name!)
    })
    
    if(newnodes.length>0){
      puuid=newnodes[0].uuid
    }else{
      console.log(_path+"上传失败! ")
      throw new Error(_path +" 上传失败!<br> ")
      return
    }
  }else{
    puuid=node[0].uuid
  }
  
  const fields = new FormData()
  fields.append('file', option)
  fields.append("space",uploadFormData.value.space)
  fields.append("puuid",puuid)
  const res = await doFileUpload(fields,'/hxpan/api/matter/upload')
  if(res.code!=200){
    console.log(_path+"上传失败! ")
    throw new Error(_path +" 上传失败!<br> ")
  }
}

//创建多级目录，并返回matterinfos数组
async function doCreateMultyDir(path:string,uuid:string){
  const list=[];
  const dirs=path.split("/")
  for(let i=0;i<dirs.length;i++){
    const node = matterList.value.filter((item)=>{
      return item.dir && dirs[i].endsWith(item.name!)
    })
    if(node.length>0) {
      uuid = node[0].uuid
      continue;
    }
    await postCreateDir(uid,{
      userUuid:uid,
      puuid:uuid,
      name:dirs[i],
    }).then((resp)=> {
     uuid=resp.data.uuid //第一级别的uuid, 是第二级的puuid
     list.push(resp.data)
    })
  }
  return list
}

function handleMouseEnter(row:any){
  currentHoverRow.value=row.uuid
}
//上传成功
function handleSingleUpload(response:any){
  fileList.value=[]
  onLoadMatterList()
}

interface uploadError{
    msg:string
}
//上传失败
function handleSigLoadErr(error: Error, uploadFile: UploadFile, uploadFiles:UploadFiles){
  ElMessage.error(JSON.parse(error.message).msg)
}
//-----------------------------------------------------------


//-------------------space feature---------------------
function onNewSpace(){
  tabName.value="main"
  const newname=ref("")
  ElMessageBox({
    title:"请输入空间名称",
    customStyle: { bottom:'200px'},
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    message: () => h(ElInput, {
      style: { width:'360px' },  
      modelValue: newname.value,
      'onUpdate:modelValue': (val) => {
        newname.value = val
      },
    }),
  }).then(() => {
    if(newname.value!==""){
      doCreateSpace(uid,newname.value).then((resp)=>{
        //spaceTreeRef.value.append({name:resp.data.name,uuid:resp.data.uuid,dir:false,userUuid:resp.data.userUuid})
        router.replace({ query: { t: Date.now() } }) //直接刷新
      })
    }
  })
}

function onSpaceNodeClick(data:matterTree,node:TreeNode,self:any,env:any){
  tabName.value="main"
  if(PRIVATESPACE.value) { //如果打开了个人空间，突然点击共享空间，要及时切换状态
    PRIVATESPACE.value=false
    modRecycling.value=false
  }
  //如果在单个组件上重复点击，不在刷新请求
  if(spaceNodeUid==data.uuid) return;
  spaceNodeUid=data.uuid

  if(data.uuid.startsWith("s0") && data.uuid!=SpaceID.value.uuid){ //切换空间
    SpaceID.value={
      name: data.name ?? "",
      uuid: data.uuid ?? "",
      userUuid: data.userUuid ?? "",
      manager: data.manager ?? false,
      permits:data.permits ?? { id: 0, MatterUuid: '', data: '{}' }
    }; 
    PRIVATESPACE.value=false;
  }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
    }
    //打开具体的节点
    spaceEleRef.value.handleDoubleClick(matter)
  }
}

function flushSpaceTree(uuid:string,data:matterTree[]){
  if(uuid==="root") uuid=SpaceID.value.uuid
  spaceTreeRef.value.updateKeyChildren(uuid,data)
}

//空间成员管理
function onAccessManage(){
  dynamicVNode.value = h(sharePermission, {
    uid: uid,
    uuid: "",
    spaceid:SpaceID.value.uuid, //
    confirmFunc: (_list: string[],_infos:string[]) => {
      // 组织权限数据
      //_len=_list.length
      let permited = btoa(_list.join("|"))
      doAccessManage(uid,{
        "space":SpaceID.value.uuid,
        "roles":permited, 
        "owner":SpaceID.value.userUuid,
        "len":_list.length
      }).then(()=>{
        
      })
    },
    closeFunc: () => {
      dynamicVNode.value=null
    }
  })
}

//删除空间
function onDeleteSpace(row:matterInfo){
  ElMessageBox.confirm(`确认删除空间 ( ${row.name}) ? 空间内所有文件将不可恢复！取消则放弃删除操作。`, "警告", {
    confirmButtonText: "确定删除",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    doDelSpace(uid,{
      "space":row.uuid,
    }).then(()=>{
      router.replace({ query: { t: Date.now() } })
    })
  })
}

//删除空间matter
function onDelSpaceMatter(row:matterInfo){
  if(row.puuid){
    spaceEleRef.value.onDelMatter(row)
  }else{
    onDeleteSpace(row)
  }
}
//空间权限控制管理
function onSpacePManage(row:matterInfo){
  dynamicVNode.value=h(spacePermission,{
    uid:rawUid,   //当前用户的uuid
    uuid:row.uuid,  //文档的uuid
    suid:SpaceID.value.userUuid,
    spaceid:SpaceID.value.uuid, //空间uuid
    closeFunc:()=>dynamicVNode.value=null
  })
}

//处理空间智能体创建
function onAiAgent(row:matterInfo){
  if(row.agent){
    alert("当前目录已经是智能体目录")
    return
  }
  
  ElMessageBox.confirm(`确认创建智能体( ${row.name}) ?`, "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    doCreateAiagent(uid,{
      space:SpaceID.value.uuid,
      matter:row.uuid
    }).then(()=>{
      router.replace({ query: { t: Date.now() } })
    })
  })
}

//------------------------------------------------------
//http://172.20.2.87:6010/api/alien/preview/5a10aaf6-396e-4d9a-7e87-3c5c8029d4db/123.png?ir=fill_100_100
//渲染完页面再执行
onMounted(() => {
  // treeRef.value.append(
  //   {name:'个人空间',uuid:'root',dir:false},
  //   currentNode.value.uuid
  // )

  currentNode.value={uuid:"root"}
  //加载我的空间列表
  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})
    })
  })
  let val =localStorage.getItem("listOrGrid") 
  if(val&&val=="false"){
    modListOrGrild.value=false
  }else{
    modListOrGrild.value=true
  }
});

const handleSelectionChange = (val:matterInfo[]) => {
  tabSelected.value = val
}

</script>

<template>
  <el-dialog v-model="onprogress"  width="50%" title="上传进度">
      请勿关闭页面。。。
      <el-progress style="width: 90%;" :text-inside="true" :stroke-width="26" :percentage="percentage" />
  </el-dialog>
  <div style="display:grid;grid-template-columns:1fr 4fr; width: 100%;height: 100%;">
  <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
      :props="{label: 'name',children:'children',isLeaf:'dir'}"
      :load="onNodeExpand"
      :default-expanded-keys="['root']"
      @node-click="onNodeClick"
    >
    <template #default="{ node, data }">
      <div class="tree-item">
        <span>{{ node.label }}</span>
        <el-dropdown>
          <el-button  size="small" :icon="Setting"  circle ></el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onDelNodeMatter(data)}">删除</el-dropdown-item>
              <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onMatterRename(data)}">重命名</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </template>
    </el-tree>
    <div class="area_header">
      <el-icon :size="20"><Collection /></el-icon> <span class="area_name" > 共享空间</span> 
      <el-button v-if="userStore.userInfoCont.department==102" size="small" style="margin: 0 5px 0 auto;" :icon="Plus"  @click="onNewSpace"> </el-button>
    </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>
        <el-dropdown v-if="data.manager">
          <el-button  size="small" :icon="Setting"  circle ></el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item v-if="!data.puuid" @click="(e)=>{ e.stopPropagation(); onAccessManage()}">成员管理</el-dropdown-item>
              <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onSpacePManage(data)}">权限管理</el-dropdown-item>
              <el-dropdown-item v-if="data.puuid" @click="(e)=>{ e.stopPropagation(); onAiAgent(data)}">创建智能体</el-dropdown-item>
              <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onDelSpaceMatter(data)}">删除</el-dropdown-item>
              <el-dropdown-item @click="(e)=>{ e.stopPropagation(); spaceEleRef.onSpaceMatterRename(data)}">重命名</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </template>
    </el-tree>
    <div class="area_header" @click="tabName='logs';showlogs()">
      <el-icon :size="20"><Bell /></el-icon><span class="area_name" > 上传日志</span> 
    </div>
    <div class="area_header" @click="showRecycling">
      <el-icon :size="20"><Delete /></el-icon><span class="area_name" > 回收站</span> 
    </div>
  </div>

<el-tabs  v-model="tabName">
  <el-tab-pane name="main">
  <div v-if="PRIVATESPACE" class="app_container">
    <el-row v-if="modRecycling"><span style="margin: 12px 0px;font-weight: bold;font-size: 20px;"> 回收站 </span>  </el-row>
    <el-row v-else :gutter="24" style="margin: 12px 0px;">
      <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;align-content: center;">根目录</span>/
      </el-link> 
      <span style="font-weight: bold;margin:0 5px;align-content:center;">{{ currentNode.name }}</span>
      
      <el-col :span="6" class="search">
        <el-input placeholder="搜索文件" v-model="searchname" @blur="searchname===''?onLoadMatterList():''"/>
        <el-button :icon="Search" @click="onSearchFile(searchname)"></el-button>
      </el-col>
    </el-row>

    <el-row v-if="!modRecycling" :gutter="24">
      <el-col :span="14">
        <div class="el-button el-button--default" style="position: relative;">
          <input type="file"  style="position: absolute;opacity: 0;width: 50px;"
          @change="onCustomUpload" multiple  />
          文件上传
        </div>

        <div class="el-button el-button--default" style="position: relative;">
          <input type="file" style="position: absolute;opacity: 0;width: 50px;"
          @change="uploadFolder"
          webkitdirectory
          multiple
          />
          文件夹上传
        </div>
        <el-button @click="createDir">新建目录</el-button>
        <span v-if="tabSelected.length>1" style="margin:12px">
          <el-button  @click="onShareMatter()">分享</el-button>
          <el-button  @click="onDelMatBatch">删除</el-button>
        </span>
      </el-col>
      <el-button-group style="margin:0 50px 0 auto;">
        <el-button  :icon="List"  @click="updateListOrGrid(true)"></el-button>
        <el-button  :icon="Grid"  @click="updateListOrGrid(false)"></el-button>
      </el-button-group>
    </el-row>

    <el-row :gutter="24" style="overflow-y: auto; height: 90%;">
      <el-table v-if="modListOrGrild"
        stripe
        :data="matterList"
        ref="multipleTableRef"
        :header-cell-style="{ background: '#f5f8fd' }"
        style="width: 100%"
        row-key="uuid"
        :row-style ="() => ({ lineHeight: '36px' })"
        @selection-change="handleSelectionChange"
        @cell-mouse-enter="handleMouseEnter">
        <!-- <el-table-column type="selection" width="50" /> -->
        <el-table-column width="450" property="name" label="文件名">
          <template #default="scope">
            <input v-if="scope.row.name===''"  v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;"  @change="onCreateDir" />
            <div v-else style="display: flex; align-items: center;" @dblclick="onDBclickMatter(scope.row)">
              <svg-icon v-if="scope.row.dir" icon-class="folder-icon"  size="30px"/>
              <el-image v-else-if="getFileIcon(scope.row.name)==='img'" style="width: 30px;" :preview-src-list="[getImageDownloadURL(scope.row.uuid,scope.row.name)]"  :src="getImagePreivewURL(scope.row.uuid,scope.row.name)" />
              <svg-icon v-else :icon-class="getFileIcon(scope.row.name)+'-icon'" size="30px" />

              <span style="margin-left: 10px">{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column width="360" align="center">
          <template #default="scope">
            <div v-show="currentHoverRow === scope.row.uuid">
              <span v-if="scope.row.deleted">
                 <el-button type="text" @click="restoreMatter(scope.row)">恢复</el-button>
              </span>
              <span v-else>
                <el-button size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
                <el-button size="small" :icon="Share" circle @click="onShareMatter(scope.row)"></el-button>
                <el-button size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
                <el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
                <el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
                <el-button size="small" circle @click="onMatterRename(scope.row)">改</el-button>
              </span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="size" width="100" :formatter="readableSize" label="大小"  />
  
        <el-table-column prop="updateTime" label="修改日期">
          <template #default="scope">
            <span v-if="scope.row.updateTime">{{ scope.row.updateTime.slice(0,16) }}</span>
          </template>
        </el-table-column>
      </el-table>
      <div class="table-grid" v-else>
        <div class="grid-item" v-for="row in matterList">
          <div class="grid">
            <div  v-if="row.name===''">
              <svg-icon  icon-class="folder-icon" size="80px"/>
              <input  v-model="newdirName" type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;"  @change="onCreateDir" />
            </div>
  
            <div v-else class="grid-box" @dblclick="onDBclickMatter(row)" @contextmenu.prevent="handleMouseEnter(row)" >
              <svg-icon v-if="row.dir" icon-class="folder-icon" size="80px"/>
              <el-image v-else-if="getFileIcon(row.name)==='img'" style="width: 80px;" :preview-src-list="[getImageDownloadURL(row.uuid,row.name)]"  :src="getImagePreivewURL(row.uuid,row.name)" />
              <svg-icon v-else :icon-class="getFileIcon(row.name)+'-icon'" size="80px"/>
              <span style="margin: 5px 0;text-wrap-mode:nowrap;">{{ row.name }}</span>
            </div>
          </div>
          <ul v-if="row.name!=''"  class="grid-menus" v-show="currentHoverRow === row.uuid" @mouseleave="currentHoverRow=''">
            <span v-if="row.deleted">
              <li @click="restoreMatter(row)">恢复</li>
            </span>
            <span v-else>
              <li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
              <li @click="onShareMatter(row)">分享</li>
              <li @click="onDownload(row)">下载</li>
              <li @click="onlyOfficeEdit(row)">编辑</li>
              <li @click="onDelMatter(row)">删除</li>
              <li @click="onMatterRename(row)">重命名</li>
            </span>
          </ul>
        </div>
      </div>
    </el-row>

    <el-row v-if="paginInfo.total>1" style="justify-content: center;">
       <el-pagination size="small" background layout="prev, pager, next" :current-page="paginInfo.page+1"  @current-change="(value:number)=>{paginInfo.page=value-1;onLoadMatterList();}" :page-count="paginInfo.total" class="mt-4"/>
    </el-row>
  </div>
  <div v-else class="app_container">
    <space ref="spaceEleRef" :uid="uid" :raw-uid="rawUid" :listOrGrid="modListOrGrild"
      :spaceid="SpaceID.uuid" :roles="Departs" :spacename="SpaceID.name" :space-permit="SpaceID.permits"
      :owner="SpaceID.userUuid" :ismanager="SpaceID.manager"
      :officeHost="officeHost" :site-host="siteHost" :api-u-r-l="apiURL"
      :flushSpaceTree="flushSpaceTree"></space> 
  </div>
  </el-tab-pane>
  <el-tab-pane name="logs">
    <Logpanel ref="logTableRef" :uid="uid" />
  </el-tab-pane>  
</el-tabs>

  <div v-if="dynamicVNode">
    <component :is="dynamicVNode" />
  </div>
  
  </div>
</template>

<style lang="scss" scoped>
.menus_tree{
  display: flex;
  flex-direction: column;
   padding: 20px 0px 0px 15px;
   height: 100%;
   overflow-y: auto;
   .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: 12px 7px;
  background-color: white;
  align-items: center;
  .area_name{
    align-content: center;
    margin-left: 8px;
    color: #686854;
    font-weight: bold;
  }
}

.tree-item{
  display: flex;
  width: 100%;
  button{
    display: none;
    margin: 0 5px 0 auto;
  }
}
.tree-item:hover button{
  display: block;
}

.el-dropdown{
   margin: 0 5px 0 auto;
}

.app_container {
  padding: 10px 30px 0px 30px;
  height: calc(100% - 10px);
  overflow: hidden;
  overflow-y: auto;
  position: relative;
}

.search{
    margin-left: auto;
    margin-right: 26px;
    display:inherit;
}
.shareDialog{
  --el-messagebox-width:'800px';
  padding:40px;
  .el-text{
    align-self: flex-start;
  }
}

.spaceitem{
  height: 50px;
  align-content: center;
  padding: 14px;
  color: #606266;
  font-weight:bold;
}

.dynamic-width-message-box-byme .el-message-box__message{
  width: 100%;
}

.el-overlay-message-box{
  top: 200x;
  bottom: auto;
}

.table-grid{
  display: flex;
  flex-wrap: wrap; /* 关键属性，允许子元素自动换行 */
  align-content: flex-start;
  .grid-item{
    position: relative;
    width: 134px;
    height: 145px;
    margin: 5px;
    .grid-box{
      display: flex;
      flex-direction: column;
      overflow: hidden;
      align-items: center;
      text-align:center;
    }
    .grid-menus{
      position: absolute;
      top: 10px;
      left: 72px;
      background-color: #ffffff;
      width: 60px;
      line-height: 27px;
      text-align: center;
      color: #878989;
      z-index: 90;
      box-shadow:0px 0px 12px rgba(0,0,0,0.12);
      li{
        cursor: pointer;
        border-bottom: 1px solid #ccc;
      }
    }
    .grid{
      :hover {
        background-color: #c4c4c4; /* 悬停时的背景色 */
      }
    }
  }
}


</style>
<style>
:root{
  --el-index-normal:auto;
}

.el-tabs__header{
  display: none;
}
</style>