--*----
<template>
  <header>
    <div class="top-placeholder">
      <a-row type="flex">
        <a-col :span="23">
          <div style="display: flex">
            <a-button style="margin-bottom: 10px; margin-right: 20px" type="primary" @click="handleMutiAdd" preIcon="ant-design:cloud-upload-outlined"
              >上传</a-button
            >
            <a-input class="search-input" v-model:value="fileName" placeholder="查询名称" allow-clear />
            <a-input class="search-input" v-model:value="labelNames" placeholder="查询标签" allow-clear />
            <a-button style="margin-bottom: 10px; margin-right: 10px" type="primary" @click="handleSearch" preIcon="ant-design:search-outlined"
              >查询</a-button
            >
            <a-button style="margin-bottom: 10px; margin-right: 30px" type="primary" @click="searchReset" preIcon="ant-design:reload-outlined"
              >重置</a-button
            >
          </div>
        </a-col>
        <a-col :span="1">
          <a-button size="small" style="margin-top: 5px" @click="changeShowMode">
            <MenuOutlined v-if="isShowFolder" />
            <AppstoreOutlined v-else />
          </a-button>
        </a-col>
      </a-row>
    </div>
  </header>
  <main>
    <div v-show="isShowFolder">
      <a-row gutter="24">
        <a-col span="4" v-for="(item, index) in mergedData" :key="index">
          <div v-if="item.isFolder" class="folder" @dblclick.stop="handleSelect(item)">
            <FolderFilled style="font-size: 60px; color: #ffe486" />
            <div class="draggable ellipsis" draggable="true"> {{ item.fileName }}</div>
          </div>
          <a-dropdown v-else :trigger="['contextmenu']">
            <div class="folder" @dblclick="showFileContent(item)">
              <span style="font-size: 50px">
                <FileWordTwoTone v-if="item.fileTp == 'doc' || item.fileTp == 'docx'" />
                <FilePdfTwoTone v-else-if="item.fileTp == 'pdf'" />
                <FileTextTwoTone v-else />
              </span>
              <div @dragstart="dragStart" class="draggable ellipsis" draggable="true" style="margin-top: 10px"> {{ item.fileName }}</div>
            </div>
            <template #overlay>
              <a-menu @click="({ key: menuKey }) => onContextFileClick(item, menuKey)">
                <a-menu-item key="edit"><Icon icon="ant-design:edit-outlined" />&nbsp;修改</a-menu-item>
                <a-menu-item key="detail"><Icon icon="ant-design:bars-outlined" />&nbsp;详情</a-menu-item>
                <a-menu-item key="move"><Icon icon="ant-design:swap-outlined" />&nbsp;移动</a-menu-item>
                <a-menu-item style="background: #d9d9d9; height: 1px; padding: 1px" />
                <a-menu-item key="filelink"><Icon icon="ant-design:link-outlined" />&nbsp;关联</a-menu-item>
                <a-menu-item key="editHistory"><Icon icon="ant-design:link-outlined" />&nbsp;历史</a-menu-item>
                <a-menu-item style="background: #d9d9d9; height: 1px; padding: 1px" />
                <a-menu-item key="dowload">
                  <span><Icon icon="ant-design:download-outlined" />&nbsp;下载</span>
                </a-menu-item>
                <a-menu-item key="delete"><Icon icon="ant-design:delete-outlined" />&nbsp;删除</a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </a-col>
      </a-row>
    </div>
    <div v-show="!isShowFolder">
      <BasicTable @register="registerTable">
        <!--插槽:table标题-->
        <template #action="{ record }">
          <template v-if="!record.isFolder">
            <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
          </template>
        </template>
        <template #bodyCell="{ column, record }">
          <template v-if="column.key == 'fileName'">
            <template v-if="record.isFolder">
              <FolderFilled style="color: #ffe486" />
              {{ record.fileName }}
            </template>
            <template v-else-if="record.fileTp == 'doc' || record.fileTp == 'docx'">
              <FileWordTwoTone />
              {{ record.fileName }}
            </template>
            <template v-else-if="record.fileTp == 'pdf'">
              <FilePdfTwoTone />
              {{ record.fileName }}
            </template>
            <template v-else>
              <FileTextTwoTone />
              {{ record.fileName }}
            </template>
          </template>
        </template>
        <!--字段回显插槽-->
        <template #htmlSlot="{ text }">
          <div v-html="text"></div>
        </template>
      </BasicTable>
    </div>
  </main>
  <DocTreeModal @register="registerTreeModal" @success="handleSuccess" />
  <DocFilesModal @register="registerModal" @success="handleSuccess" @edit-success="handleEditSuccess" />
  <DocMutiFilesModal @register="registerMutiModal" @success="handleSuccess" />
  <FileViewerModal @register="registerShowFileContentModal" :useStaticPrefixForDocx="true" />
  <FileList ref="refFileList" />
  <FileHistory ref="refFileHistory" />
</template>

<script setup lang="ts">
  import { ref, computed, nextTick } from 'vue';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { useModal } from '/@/components/Modal';
  import { useListPage } from '/@/hooks/system/useListPage';
  import DocFilesModal from './components/DocFilesModal.vue';
  import DocMutiFilesModal from './components/DocMutiFilesModal.vue';
  import DocTreeModal from './components/DocTreeModal.vue';
  import FileViewerModal from '/@/components/onlinePreview/FileViewerModal.vue'
  import { columns } from './DocFiles.data';
  import { deleteOne, queryAllList } from './DocFiles.api';
  import { getChildList } from './DocFilesDir.api';
  import FileList from './components/FileList.vue';
  import FileHistory from './components/FileHistory.vue';

  import FileItem from './components/FileItem.vue';
  import FileIcon from './components/FileIcon.vue';

  import { FolderFilled, FileTextTwoTone, MenuOutlined, AppstoreOutlined, FileWordTwoTone, FilePdfTwoTone } from '@ant-design/icons-vue';
  import { Base64 } from 'js-base64';

  // 状态定义
  const fileName = ref('');
  const labelNames = ref('');
  const treeNodeData = ref();
  const mergedData = ref<Recordable[]>([]);
  const loading = ref(false);
  const fileList = ref<Recordable[]>([]);
  const fileDirs = ref();
  const ctp = ref();
  const isShowFolder = ref(true);

  const refFileList = ref();
  const refFileHistory = ref();

  // 注册模态框
  const [registerModal, { openModal }] = useModal();
  const [registerMutiModal, { openModal: openMutiModal }] = useModal();
  const [registerTreeModal, { openModal: openTreeModal }] = useModal();
  const [registerShowFileContentModal, { openModal: openFileContentModel }] = useModal();

  // 表格配置
  const { tableContext } = useListPage({
    tableProps: {
      title: '',
      dataSource: mergedData,
      columns,
      canResize: true,
      size: 'small',
      striped: true,
      scroll: { y: 500 },
      useSearchForm: false,
      showTableSetting: false,
      pagination: false,
      actionColumn: {
        width: 260,
        fixed: 'right',
      },
    },
  });

  const [registerTable, { reload }] = tableContext;

  // 方法定义
  const handleMutiAdd = () => {
    openMutiModal(true, {
      record: { ctp: ctp.value },
      isUpdate: false,
      showFooter: false,
    });
  };

  const handleEdit = (record: Recordable) => {
    openModal(true, {
      record,
      isUpdate: true,
      showFooter: true,
    });
  };

  const handleDetail = (record: Recordable) => {
    openModal(true, {
      record,
      isUpdate: true,
      showFooter: false,
    });
  };

  const handleMove = (record: Recordable) => {
    openTreeModal(true, {
      record,
      isUpdate: true,
      showFooter: false,
    });
  };

  const handleFile = (record: Recordable) => {
    showFileContent(record);
  };

  const handleDelete = async (record: Recordable) => {
    await deleteOne({ id: record.id }, (id) => {
      mergedData.value = mergedData.value.filter((item) => !(item.id === id && !item.isFolder));
    });
  };

  const handleSuccess = async () => {
    fileList.value = await queryAllList({ ctp: treeNodeData.value.key });
    mergedData.value = mergedData.value.filter((item) => item.isFolder).concat(fileList.value);
  };

  const handleEditSuccess = (newValue: Recordable) => {
    const index = mergedData.value.findIndex((obj) => obj.id * 1 == newValue.id * 1);
    if (index !== -1) {
      mergedData.value[index] = newValue;
    }
  };

  // 文件操作
  const onContextFileClick = (item, menuKey: string) => {
    if (menuKey == 'delete') {
      handleDelete(item);
    } else if (menuKey == 'edit') {
      handleEdit(item);
    } else if (menuKey == 'detail') {
      handleDetail(item);
    } else if (menuKey == 'dowload') {
      handleDownloadFile(item);
    } else if (menuKey == 'filelink') {
      handleFileLink(item);
    } else if (menuKey == 'editHistory') {
      handleEditHistory(item);
    } else if (menuKey == 'move') {
      handleMove(item);
    }
  };

  const getTableAction = (record: Recordable) => {
    return [
      {
        label: '修改',
        onClick: () => handleEdit(record),
      },
      {
        label: '移动',
        onClick: () => handleMove(record),
      },
      {
        label: '预览',
        onClick: () => handleFile(record),
      },
    ];
  };

  const getDropDownAction = (record: Recordable) => {
    return [
      {
        label: '详情',
        onClick: () => handleDetail(record),
      },
      {
        label: '关联',
        onClick: () => handleFileLink(record),
      },
      {
        label: '历史',
        onClick: () => handleEditHistory(record),
      },
      {
        label: '删除',
        popConfirm: {
          title: '是否确认删除',
          confirm: () => handleDelete(record),
        },
      },
    ];
  };

  const getFileIconType = (item: Recordable) => {
    if (item?.isFolder) return 'folder';
    if (item?.fileTp === 'doc' || item?.fileTp === 'docx') return 'word';
    if (item?.fileTp === 'pdf') return 'pdf';
    return 'text';
  };

  const setFileCtp = async (data: Recordable) => {
    if (data) {
      ctp.value = data.key;
      treeNodeData.value = data;
      fileDirs.value = data.children;
      fileList.value = await queryAllList({ ctp: data.key });

      if (fileDirs.value) {
        const folderArr = fileDirs.value.map((item: Recordable) => ({
          fileName: item.title,
          label: item.otherData?.label,
          isFolder: true,
          key: item.key,
        }));
        mergedData.value = folderArr.concat(fileList.value);
      } else {
        mergedData.value = fileList.value;
      }
    } else {
      fileList.value = [];
      fileDirs.value = [];
    }
  };

  const emit = defineEmits(['selectFolder']);

  const handleSelect = (item: Recordable) => {
    emit('selectFolder', item);
  };

  const searchData = async () => {
    const paramDirs = { labelNames: labelNames.value };
    const paramFile = { labelNames: labelNames.value };

    paramFile['fileName'] = '*' + fileName.value + '*';
    paramDirs['name'] = '*' + fileName.value + '*';

    fileDirs.value = await getChildList(paramDirs);
    fileList.value = await queryAllList(paramFile);

    if (fileDirs.value) {
      fileDirs.value.forEach((item: Recordable) => {
        item['title'] = item['name'];
        item['fileName'] = item['name'];
        item['isFolder'] = true;
        item['key'] = item['id'];
        item['parentId'] = item['pid'];
      });
      mergedData.value = fileDirs.value.concat(fileList.value);
    } else {
      mergedData.value = fileList.value;
    }
  };

  const handleSearch = async () => {
    if (!fileName.value && !labelNames.value) return;
    await searchData();
  };

  const searchReset = () => {
    fileName.value = '';
    labelNames.value = '';
    setFileCtp(treeNodeData.value);
  };

  const changeShowMode = () => {
    isShowFolder.value = !isShowFolder.value;
  };

  const handleDownloadFile = (item: Recordable) => {
    const globOnlineViewUrl: string = import.meta.env.VITE_GLOB_ONLINE_VIEW_URL;
    const url = globOnlineViewUrl + item.filePath;
    if (url) {
      window.open(url);
    }
  };

  const showFileContent = (item: Recordable) => {
    if (item.filePath) {
      openFileContentModel(true, {
        record: item,
        isUpdate: false,
        showFooter: true,
      });
    }
  };

  const handleFileLink = async (file: Recordable) => {
    await refFileList.value.iniData(file);
  };

  const handleEditHistory = async (file: Recordable) => {
    await refFileHistory.value.iniData(file);
  };

  defineExpose({
    setFileCtp,
  });
</script>

<style lang="less" scoped>
  header {
    height: 50px;
  }
  .top-placeholder {
    height: 50px;
    border-bottom: 1px solid #d9d9d9;
  }
  .search-input {
    max-width: 25%;
    height: 32px;
    margin-right: 10px;
  }
  main {
    height: calc(90vh - 200px);
    overflow-y: auto;
  }
  .folder {
    width: 160px;
    height: 150px;
    margin-top: 20px;
    text-align: -webkit-center;
  }
  .ellipsis:hover {
    overflow: visible;
    text-overflow: inherit;
    display: block;
  }
  .ellipsis {
    /* white-space: nowrap; */
    width: 8em;
    text-overflow: ellipsis;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
  ::-webkit-scrollbar {
    /* 隐藏滚动条 */
    display: none;
  }
</style>
