<!--
@ 作者: han2015
@ 时间: 2025-05-12 15:39:13
@ 备注: 共享空间组件
-->
<script lang="ts" setup>
import { getFileIcon, readableSize,fileType} from "./tools"
import sharePermission from './sharePermission.vue';
import spacePermission from './spacePermission.vue';
import { matterPage,matterInfo,matterTree,doFileUpload,matterPermit} from "@/api/doc/type"
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter,
  doAiTraining ,spaceMatterRename} from "@/api/doc/space"
import { h } from 'vue'
import {
  Delete,
  View,
  Download,
  Plus,Search,
  Edit,
  Setting,
  Grid,List,
} from '@element-plus/icons-vue'
import {ElMessage,UploadFile,UploadFiles,ElPagination, ElProgress} from "element-plus";
import aiagent from './agent.vue';
import uploadlog from './uploadlog.vue';
import router from "@/router";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { useOrgMemberStore } from "@/store/modules/orgMember";
const orgMembers = useOrgMemberStore() //为了初始化

const defaultAiAgent=import.meta.env.VITE_DEFAULT_AI_AGENT
const matterList = ref<matterInfo[]>([])
const searchname=ref("") //按文件名查找文件
const newdirName=ref("") //创建新目录时的目录名
const currentHoverRow=ref("") //table 行的按钮控制
const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) //面包屑导航

const tabSelected=ref<matterInfo[]>([]) //table组件多选数据维护
const currentNode=ref<matterInfo>({})  //打开的路径层次
let isNewNode=true //用来减少父组件树的重置

const dynamicVNode = ref<VNode | null>(null) //permission 组件的父组件
const paginInfo = ref({ page: 0, total: 0 })

const CutLevelPermit=ref(0)
const modListOrGrild=ref(true) //列表显示还是栅格显示

const percentage=ref(0)
const onprogress=ref(true)

enum PERMITS {
  FORBID, //0
  VIEW, //1
  DOWNLOAD, //2
  UPLOAD,  //3
  UPANDDOWNLOAD, //4
  EDIT, //5
  MANAGER, //6
}

//-----------AI---------------------
const currentAgent=ref<{model:boolean,name:string,uuid:string,path:string}>({})

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

const props = withDefaults(defineProps<{  
  uid:string,   //当前用户的uuid,注意已经且必须通过base64编码,因为后端获取Identifier后，会base64解码
  rawUid:string,
  //tree:object,
  spaceid:string,
  spacename:string,
  officeHost:string,
  siteHost:string,
  owner:string,
  apiURL:string,
  listOrGrid:boolean,
  ismanager:boolean,
  spacePermit:matterPermit,

  flushSpaceTree:(uuid:string,data:matterTree[])=>void
}>(),{})

//属性变更，特别是为了处理空间切换的状态更新
watch(props,()=>{
  currentNode.value.uuid="root"
  currentNode.value.name="根目录"
  currentAgent.value.path="root"
  onLoadMatterList()
})

const uploadFormData = computed(() => {
  return {
    space: props.spaceid,
    puuid: currentNode.value.uuid, // 父目录的uuid，基目录为root
  }
});

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

//--------------权限控制&添加空间成员-------------
function onAccessManage(){
  //迁移到了manage文件中，暂时不需要了
  dynamicVNode.value = h(sharePermission, {
    uid: props.uid,
    uuid: "",
    spaceid:props.spaceid, //
    confirmFunc: (_list: string[],_infos:string[]) => {
      // 组织权限数据
      //_len=_list.length
      let permited = btoa(_list.join("|"))
      doAccessManage(props.uid,{
        "space":props.spaceid,
        "roles":permited, 
        "owner":props.owner,
        "len":_list.length
      }).then(()=>{
        
      })
    },
    closeFunc: () => {
      dynamicVNode.value=null
    }
  })
}

//文档权限控制管理
function onSpacePManage(row:matterInfo){
  dynamicVNode.value=h(spacePermission,{
    uid:props.rawUid,   //当前用户的uuid
    uuid:row.uuid,  //文档的uuid
    suid:props.owner,
    spaceid:props.spaceid, //空间uuid
    closeFunc:()=>dynamicVNode.value=null
  })
}


//----------------------------------------
//删除
function onDelMatter(row:matterInfo){
  if (row.uuid){
    ElMessageBox.confirm(`确认删除( ${row.name}) ?删除后不可恢复！取消则放弃删除操作。`, "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(()=>{
      doDelSpaceMatter(props.uid,{
        "uuid":row.uuid,
        "space":props.spaceid,
      }).then(()=>{
        currentNode.value.uuid = row.puuid ?? ""
        onLoadMatterList()  
      })
    })
  }
}

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

//加载目录文件列表
function onLoadMatterList(name?:string){
  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,
    space:props.spaceid,
  };

  if(name){
    _page={
       pageSize: 50,
      orderCreateTime: "DESC",
      orderDir: "DESC",
      deleted:false,
      name:name,
      space:props.spaceid,
    }
  }


  getSpaceMatterList(props.uid,_page).then((resp)=>{
    //page+1 是由于分页的起始index是1，而后端api的分页index起始是0
    paginInfo.value={total:resp.data.totalPages, page:resp.data.page}
    if (props.ismanager) {
      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=CutLevelPermit.value
        }else{
          //如果该文档有设定权限，解析该文档的具体权限
          let _pert: Record<string, number>
          _pert = JSON.parse(item.permits!.data)
          let val=_pert[props.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=props.ismanager
      return copy
    })

    if(isNewNode) {
      //由于支持目录树的原因，所有的空间根目录uuid都是root，这样树组件就有问题，所以用了spaceid作为其uuid
      //但是云盘的根目录是root，所以当uuid是spaceid时，自动替换为root
      if(currentNode.value.uuid=="root") props.flushSpaceTree(props.spaceid,node_data);
      else props.flushSpaceTree(currentNode.value.uuid,node_data);
    }
  })
}
//----------for dir-----------
//该函数仅操作前端，为新文件夹命名
function createDir(){
    matterList.value?.unshift({
      name:"",
      userUuid:props.spaceid,
      puuid:"",
      uuid:"",
      dir:true,
      size:0,
      deleted:false,
    })
}
//该函数为实际创建文件夹的函数
function onCreateDir(){
  doCreateSpaceDir(props.uid,{
    puuid:currentNode.value.uuid,
    name:newdirName.value,
    space:props.spaceid,
  }).then((resp)=> {
    newdirName.value=""
    onLoadMatterList()
  })
  .catch((e)=>{
    ElMessage.error(e.msg)
  })
}

//文件重命名
function onSpaceMatterRename(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!=""){
      spaceMatterRename(props.uid,{
        space:props.spaceid,
        uuid:row.uuid,
        name:newname.value,
      }).then(()=>onLoadMatterList())
    }
  })
}

//------------------------------------------
// @cell-dblclick="handleDoubleClick" 取消了目录双击打开功能
//打开一个目录
function handleDoubleClick(row:matterInfo,ind?:number){
  if(row.dir){
    //设置当前文件夹的权限等级
    if(row.permitVal){
      CutLevelPermit.value=row.permitVal
    }else{
      if (props.ismanager) {
        CutLevelPermit.value=9
      }else{
        let _pert: Record<string, number>
        _pert = JSON.parse(row.permits!.data)
        let val=_pert[props.rawUid.replace("p0","")]
        if(val){
          CutLevelPermit.value = val
        }else{
          CutLevelPermit.value = PERMITS.FORBID //没有权限！！
        }
      }
    }
    
    if(row.agent){
      currentAgent.value={name:row.name,model:false,uuid:row.uuid,path:row.path}
    }else if(row.uuid=="root"){
      currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent,path:"root"}
    }
    isNewNode=true
    //1：如果是当前目录的父组件没必要更新目录树
    //2: 如果当前目录是当前空间根目录，没必要更新目录树
    if(currentNode.value.puuid==row.uuid || row.uuid=="root") isNewNode=false
    currentNode.value=row
    onLoadMatterList()

    /* 由于添加了父级树组件，breadcrumblis的功能废弃
    //table的双击事件也在此方法处理
    if(typeof(ind)==="number"){
      //返回某一级,面包屑组件的点击处理
      if(breadcrumbList.value.length>1){
        breadcrumbList.value=breadcrumbList.value.slice(0,ind+1)
        currentNode.value=breadcrumbList.value[breadcrumbList.value.length-1]
        onLoadMatterList()
      }
    }else{
      //进入下一级
      //如果目录是一个智能体，把当前智能体设置为该目录
      currentNode.value=row
      breadcrumbList.value.push(row)
      onLoadMatterList()
    } 
    */   
  }else{
    onPrivateView(row)
  }
}

function handleMouseEnter(row:any){
  currentHoverRow.value=row.name
}
//上传成功
function handleSingleUpload(response:any){
  handleAiUpload(response.data)
  onLoadMatterList()
}
interface uploadError{
    msg:string
}
//上传失败
function handleSigLoadErr(error: Error, uploadFile: UploadFile, uploadFiles:UploadFiles){
  ElMessage.error(JSON.parse(error.message).msg)
}

//自定义上传，目的是支持多文件上传, 使用原生组件，是为了解决并发问题
async function onCustomUpload(e:Event){
  const files = e.target!.files??[]
  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("space",uploadFormData.value.space)
  fields.append("puuid",uploadFormData.value.puuid)
  fields.append("file",ff)
  
  const res = await doFileUpload(fields,'/hxpan/api/space/upload')
  if(res.code!=200){
    console.log(ff.name+"上传失败! ")
    throw new Error(ff.name+"上传失败!<br> ")
  }

  //上传后继续AI服务训练
  handleAiUpload(res.data)
}

//文件夹上传，原理：自定义的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!)  //item.path?.endsWith(_dir)
    })
    if(newnodes.length>0){
      puuid=newnodes[0].uuid
    }else{
      console.log(_path+"上传失败! ")
      throw new Error(_path +" 上传失败!<br> ")
    }
  }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/space/upload')
  if(res.code!=200){
    console.log(_path+"上传失败! ")
    throw new Error(_path+"上传失败!<br> ") 
  }

  //上传后继续AI服务训练，是不是需要上传，在handleAiUpload里面有检测
  handleAiUpload(res.data)

}

//创建多级目录，并返回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 doCreateSpaceDir(props.uid,{
      puuid:uuid,
      name:dirs[i],
      space:props.spaceid,
    }).then((resp)=> {
     uuid=resp.data.uuid //第一级别的uuid, 是第二级的puuid
     list.push(resp.data)
    })
  }
  return list
}

//-------------------------AI section--------------

function handleAiUpload(info:matterInfo){
  //只有当前路径是智能体，上传文件才会进行训练
  if (info.path?.startsWith(currentAgent.value.path)){
    doAiTraining(`/agents/${currentAgent.value.uuid}/updates`,{"matter":info.uuid}).then(resp=>{
      ElMessage({
        message: '已成功安排训练',
        type: 'success',
        plain: true,
      })
    })
  }else{
    console.log("当前路径没有智能体,不需要训练")
  }
}

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

//-------------------edit & preive file for space---------------------
//文件预览
function onPrivateView(row:matterInfo){
  const _type=fileType(row.name!)
  if(_type!==""){ //office file
    const info =btoa(encodeURIComponent(`${row.name}`)) //预览模式不需要绝对路径，只核对一下文件名即可
    const _url=`${props.siteHost}${props.apiURL}/space/download/${row.uuid}/${row.name}?space=${props.spaceid}`
    //前半部分内容是为了校验信息，主要内容是fileurl
    window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank")
  }else{
    alert("暂不支持该类型预览")
  }
}

//onlyoffice在线编辑
async function onlyOfficeEdit(row:matterInfo){
  const _type=fileType(row.name!)
  if(_type===""){
    alert("暂不支持该类型编辑")
    return 
  }
 
  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=`${props.siteHost}${props.apiURL}/space/download/${row.uuid}/${row.name}?space=${props.spaceid}`
    window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&verify=${_verify}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank") 
  }).catch(()=>{
    console.log("close")
  })
}

function getSpaceImageViewURL(_uuid:string,_name:string){
  return `${props.apiURL}/space/download/${_uuid}/${_name}?space=${props.spaceid}&ir=fill_100_100&`
}

function getSpaceImageDURL(_uuid:string,_name:string){
  return `${props.apiURL}/space/download/${_uuid}/${_name}?space=${props.spaceid}`
}

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

//渲染完页面再执行
onMounted(() => {
  currentNode.value.uuid="root"
  //设置默认的AI智能体
  currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent,path:"root"}
  
  let val =localStorage.getItem("listOrGrid") 
  if(val&&val=="false"){
    modListOrGrild.value=false
  }else{
    modListOrGrild.value=true
  }

  if (props.ismanager) {
    CutLevelPermit.value=PERMITS.MANAGER
  }else{
    let _pert: Record<string, number>
    _pert = JSON.parse(props.spacePermit.data)
    let val=_pert[props.rawUid.replace("p0","")]
    if(val){
      CutLevelPermit.value = val
    }else{
      CutLevelPermit.value = PERMITS.FORBID //没有权限！！
    }
  }
  
  onLoadMatterList()
});

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

defineExpose({handleDoubleClick,onDelMatter,onSpaceMatterRename})

//判断是不是空间的所有者
function isOwner(){
  return props.uid===btoa(props.owner)
}
</script>

<template>
    <el-row :gutter="24" style="margin: 12px 0px;">
      <span class="el-breadcrumb" style="font-weight: bold; align-content: center;">[ {{ props.spacename }} ] : </span>
      <el-breadcrumb separator="/" style="align-content: center;">
        <el-breadcrumb-item v-for="(item,index) in breadcrumbList" 
          :key="index" @click="handleDoubleClick(item,index)">
          <span style="font-weight: bold;cursor: pointer;">{{ item.name }}</span>
        </el-breadcrumb-item>
      </el-breadcrumb>
      <span v-if="currentNode.uuid!='root'" 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="onLoadMatterList(searchname)"></el-button>
      </el-col>
    </el-row>

    <el-row :gutter="24">
      <el-col :span="14" v-if="CutLevelPermit>=PERMITS.UPLOAD">  
        <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>
      </el-col>
      <el-button style="margin-left: auto;" @click="()=>currentAgent.model=true">AI助手</el-button>
      
      <!-- <el-button-group v-if="isOwner()" class="control" style="margin: 0 10px;">
        <el-button  :icon="Plus"  @click="onAiAgent">创建智能体</el-button>
      </el-button-group> -->
      <el-button-group style="margin-right:20px;">
        <el-button  :icon="List"  @click="updateListOrGrid(true)"></el-button>
        <el-button  :icon="Grid"  @click="updateListOrGrid(false)"></el-button>
      </el-button-group>
    </el-row>
    
    <el-dialog v-model="onprogress"  width="50%" title="上传进度">
        请勿关闭页面。。。
       <el-progress style="width: 90%;" :text-inside="true" :stroke-width="26" :percentage="percentage" />
    </el-dialog>
   
    <el-row :gutter="24" style="overflow-y: auto;height: 90%;">
      <el-table v-if="modListOrGrild"
        stripe
        :data="matterList"
        :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="handleDoubleClick(scope.row)" >
              <svg-icon v-if="scope.row.dir" icon-class="folder-icon"  :size="30"/>
              <el-image v-else-if="getFileIcon(scope.row.name)==='img'" style="width: 30px;" :preview-src-list="[getSpaceImageDURL(scope.row.uuid,scope.row.name)]"  :src="getSpaceImageViewURL(scope.row.uuid,scope.row.name)" />
              <svg-icon v-else :icon-class="getFileIcon(scope.row.name)+'-icon'" :size="30" />
              <span style="margin-left: 10px">{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column width="350">
          <template #default="scope" >
              <el-tag v-if="scope.row.agent"  effect="dark" size="small" type="success" round >智能体</el-tag>
              <div v-show="currentHoverRow === scope.row.name" style="display:inline; margin-left:15px">
                <el-button v-if="getFileIcon(scope.row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
                <el-button v-if="scope.row.permitVal>=PERMITS.DOWNLOAD" size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
                <span v-if="scope.row.permitVal>=PERMITS.MANAGER" class="manager_span" >
                  <el-button v-if="!scope.row.dir" size="small" circle @click="handleAiUpload(scope.row)">AI</el-button>
                  <el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
                  <el-button size="small" :icon="Setting" circle @click="onSpacePManage(scope.row)"></el-button>
                </span>
                <span v-if="scope.row.permitVal>=PERMITS.EDIT"  class="manager_span">
                  <el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
                  <el-button size="small" circle @click="onSpaceMatterRename(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="handleDoubleClick(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="[getSpaceImageDURL(row.uuid,row.name)]"  :src="getSpaceImageViewURL(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>
              <el-tag v-if="row.agent"  effect="dark" size="small" type="success" round >智能体</el-tag>
            </div>
          </div>
          <ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''">
            <li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
            <li v-if="row.permitVal! >= PERMITS.DOWNLOAD"  @click="onDownload(row)">下载</li>
            <span v-if="row.permitVal! >= PERMITS.EDIT" >
              <li  @click="onlyOfficeEdit(row)">编辑</li>
              <li  @click="onSpaceMatterRename(row)">重命名</li>
            </span>
            <span v-if="row.permitVal! >= PERMITS.MANAGER" >
              <li  @click="onDelMatter(row)">删除</li>
              <li  @click="onSpacePManage(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>

  <aiagent :agent="currentAgent" :userid="uid" :closefunc="()=>{currentAgent.model=false}"></aiagent>

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

<style lang="scss" scoped>

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

.table-grid{
  display: flex;
  flex-wrap: wrap; /* 关键属性，允许子元素自动换行 */
  align-content: flex-start;
  .grid-item{
    position: relative;
    width: 134px;
    height: 135px;
    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; /* 悬停时的背景色 */
      }
    }
  }
}

.manager_span{
  margin-left: 10px;
}

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

</style>

<style lang="scss">
    .el-table--default .el-table__cell{
      padding: 10px 0;
    }
</style>