<!--
@ 作者: han2015
@ 时间: 2025-05-12 15:39:13
@ 备注: 文档管理组件
-->
<script lang="ts" setup>
import { getFileIcon, readableSize,fileType} from "./tools"
import sharePermission from './sharePermission.vue';
import { matterPage,matterInfo} from "@/api/doc/type"
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter,doDelSpace} from "@/api/doc/space"
import { h, proxyRefs } from 'vue'
import {
  Delete,
  View,
  Download,
  Plus,
  Edit,
  Promotion,
  Folder,
} from '@element-plus/icons-vue'
import {ElMessage,UploadFile,UploadFiles,ElPagination} from "element-plus";
import preview from './preview.vue';
import router from "@/router";

const matterList = ref<matterInfo[]>([])
const newdir=ref("") //创建新目录时的目录名
const currentHoverRow=ref("") //table 行的按钮控制
const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) //面包屑导航

const selectedValue = ref("sixhour") //分享弹窗的时间变量

const tabSelected=ref<matterInfo[]>([]) //table组件多选数据维护
const currentNode=ref<matterInfo>({})  //打开的路径层次

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

const props = withDefaults(defineProps<{
  uid:string,   //当前用户的uuid,注意已经过base64编码
  spaceid:string,
  spacename:string,
  officeHost:string,
  siteHost:string,
  owner:string,
  apiURL:string,
  roles:string
}>(),{})

watch(props,()=>{
  onLoadMatterList()
})

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

//--------------权限控制&添加空间成员-------------
function onAccessManage(){
  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 onDeleteSpace(){
  ElMessageBox.confirm(`确认删除空间 ( ${props.spacename}) ? 空间内所有文件将不可恢复！取消则放弃删除操作。`, "警告", {
    confirmButtonText: "确定删除",
    cancelButtonText: "取消",
    type: "warning",
  }).then(()=>{
    doDelSpace(props.uid,{
      "space":props.spaceid,
    }).then(()=>{
      router.replace({ query: { t: Date.now() } })
    })
  })
}

//----------------------------------------
//删除
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,
        "roles":props.roles,
      }).then(()=>{
        currentNode.value.uuid = row.puuid ?? ""
        currentNode.value.name = row.path ? row.path.replace(`/${row.name}`,'').match(/[^/]+$/g)?.pop() :"上级目录"
        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(){
  let _page: matterPage = {
    page: paginInfo.value.page,
    pageSize: 50,
    orderCreateTime: "DESC",
    orderDir: "DESC",
    puuid:currentNode.value.uuid,
    deleted:false,
    space:props.spaceid,
    roles:props.roles,
  };

  getSpaceMatterList(props.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
  })
}
//----------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:newdir.value,
    space:props.spaceid,
    roles:props.roles,
  }).then((resp)=> {
    newdir.value=""
    onLoadMatterList()
  })
  .catch((e)=>{
    ElMessage.error(e.msg)
  })
}
//------------------------------------------

//打开一个目录
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)
        currentNode.value=breadcrumbList.value[breadcrumbList.value.length-1]
        onLoadMatterList()
      }
    }else{
      //进入下一级
      currentNode.value=row
      breadcrumbList.value.push(row)
      onLoadMatterList()
    }    
  }
}

function handleMouseEnter(row:any){
  currentHoverRow.value=row.name
}
//上传成功
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)
}
//-------------------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=`+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=`+encodeURIComponent(_url),"_blank") 
  })
}

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

//渲染完页面再执行
onMounted(() => {
  currentNode.value.uuid="root"
  onLoadMatterList()
});

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

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

<template>
  <div>
    <el-row :gutter="24" style="margin: 12px 0px;">
      <span class="el-breadcrumb" style="font-weight: bold;">[ {{ props.spacename }} ] : </span>
      <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-row>

    <el-row :gutter="24">
      <el-col :span="14">  
        <el-upload class="el-button el-button--default" :file-list="fileList"
          :data="uploadFormData"
          :on-success="handleSingleUpload"
          :on-error="handleSigLoadErr"
          :show-file-list="false"
          :action="apiURL+'/space/upload'" :limit="1">
          <span>上传文件</span>
        </el-upload>
        <el-button @click="createDir">新建目录</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-button-group class="control" v-if="isOwner()" style="margin-right: 10px;margin-left: auto;">
        <el-button  :icon="Plus"  @click="onAccessManage">成员</el-button>
        <el-button  :icon="Delete"  @click="onDeleteSpace">删除</el-button>
      </el-button-group>
    </el-row>

    <el-row :gutter="24" style="height: 84%;overflow-y: auto;">
      <el-table
        stripe
        :data="matterList"
        :header-cell-style="{ background: '#f5f8fd' }"
        style="width: 100%"
        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="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;">
              <el-icon :size="26">
                <component v-if="scope.row.dir" :is="Folder" />
                <component v-else :is="getFileIcon(scope.row.name)" />
              </el-icon>
              <span style="margin-left: 10px">{{ scope.row.name }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column width="250" align="center">
          <template #default="scope">
            <div v-show="currentHoverRow === scope.row.name">
              <el-button size="small" :icon="Promotion" circle ></el-button>
              <el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
              <el-button size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
              <el-button size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
              <el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
            </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>
    </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-if="dynamicVNode">
    <component :is="dynamicVNode" />
  </div>
</template>

<style lang="scss" scoped>

.shareDialog{
  --el-messagebox-width:'800px';
  padding:40px;
  .el-text{
    align-self: flex-start;
  }
}

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

</style>
