Bläddra i källkod

Merge branch 'liuqiang' into v3

liuQiang 1 år sedan
förälder
incheckning
c291d98f2c

+ 93 - 14
src/components/LeftList/LeftList.vue

@@ -4,8 +4,10 @@
       class="treebox"
       :data="treeData"
       :props="defaultProps"
-      :default-expand-all="true"
-      @node-click="handleNodeClick"
+      :accordion="false"
+      node-key="id"
+      :default-expand-all="false"
+      :default-expanded-keys="curArr"
     >
       <template #default="{ node, data }">
         <span class="custom-tree-node" @click="checkoutNode(node, data)">
@@ -41,9 +43,15 @@ const props = defineProps({
     type: Number,
     default: 0,
   },
+  ListtreeData: {
+    type: Array,
+    default: () => [],
+  },
 });
-const emit = defineEmits(["folderClick"]);
+const emit = defineEmits(["listfolderClick"]);
 const treeData = ref();
+console.log("treeData", treeData.value);
+const curArr = ref([]); //默认展开一级目录
 const defaultProps = ref({
   label: "label",
   value: "id",
@@ -67,23 +75,94 @@ function getFileTree() {
       return nodes;
     }
     // 调用递归函数获取所有节点的 id
-    const arr = getAllNodeIds(treeData.value);
-    console.log("treedataarr", arr);
-    console.log("treeData", treeData.value);
+    getAllNodeIds(treeData.value);
+    // console.log("treedataarr", arr);
+    // console.log("treeData", treeData.value);
   });
 }
-const checkoutNode =async  (node, data) => {
-  console.log("treeData", treeData.value);
-  console.log("data", data);
-  const res = await getDir(data.id)
-  emit('folderClick',res.data)
-  console.log('res',res);
+const checkoutNode = async (node, data) => {
+  // console.log("treeData", treeData.value);
+  console.log("node", node);
+  // console.log("data", data);
+  let thisNode;
+  function getLevel2(nodes) {
+    if (nodes?.level === 2) {
+      // console.log(2);
+      // console.log("nodes", nodes);
+      thisNode = toRaw(nodes);
+    } else {
+      if (!nodes.parent) {
+        return;
+      }
+      // console.log("level", nodes.level);
+      getLevel2(nodes.parent);
+    }
+  }
+  getLevel2(node);
+  console.log("thisNode", thisNode);
+  console.log("node", node);
+  const res = await getDir(data.id);
+  let resThis;
+  if (thisNode) {
+    resThis = await getDir(thisNode.data.id);
+  }
+  emit("listfolderClick", res.data, resThis?.data);
+  // console.log("res", res);
+  // console.log("resThis", resThis);
 };
 const setImg = (remark) => {
   return setListImg(remark);
 };
+const getTopDir = async () => {
+  const res = await documents.getTop(3);
+  console.log("topres", res);
+  curArr.value.push(res.dirId);
+  return;
+  // let userMe;
+  // userMe = [res];
+  // documents
+  //   .getALLdocumentByType(
+  //     {
+  //       parentId: userMe[0].dirId - 0,
+  //       spaceId: userMe[0].spaceId,
+  //       isAsc: "asc",
+  //       orderByColumn: "createTime",
+  //       pageNum: 1,
+  //       pageSize: 999,
+  //     },
+  //     3
+  //   )
+  //   .then((res) => {
+  //     const folderArr = res.rows;
+  //   curArr.value = folderArr.map((item) => {
+  //       const obj = {
+  //         label: item.dirName,
+  //         value: item.dirId,
+  //         remark: "",
+  //         disable: false,
+  //       };
+  //       return obj
+  //     });
+  //     console.log("curArr.value", curArr.value);
+  //   });
+};
+watch(
+  () => props.ListtreeData,
+  (newValue, oldValue) => {
+    treeData.value = newValue;
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+defineExpose({
+  getFileTree, // test是向外暴露的方法
+});
 onMounted(() => {
-  getFileTree();
+  getTopDir();
+
+  // getFileTree();
 });
 </script>
 
@@ -109,7 +188,7 @@ onMounted(() => {
     font-size: 14px;
     line-height: 22px;
     margin-left: 5px;
-    max-width: 300px;
+    max-width: 150px;
     /*第一步: 溢出隐藏 */
     overflow: hidden;
     /* 第二步:让文本不会换行, 在同一行继续 */

+ 245 - 27
src/components/ListShow/ListShow.vue

@@ -35,7 +35,7 @@
         :data="tableData"
         style="width: 100%; height: calc(88vh - 48px)"
         ref="container"
-        @row-click="clickRow"
+        @row-contextmenu="rightClick"
       >
         <el-table-column label="名称">
           <template #default="scope">
@@ -64,34 +64,191 @@
 
 <script setup>
 import { onMounted, ref, watch, nextTick, inject } from "vue";
+//---------------导入图片--------------------------
+import file_DOC from "@/assets/images/fileType/file_DOC.png";
+import file_pdf from "@/assets/images/fileType/file_pdf.png";
+import file_PPT from "@/assets/images/fileType/file_PPT.png";
+import file_TXT from "@/assets/images/fileType/file_TXT.png";
+import file_XLSX from "@/assets/images/fileType/file_XLSX.png";
+import file_pic from "@/assets/images/fileType/file_pic.png";
+import file_audio from "@/assets/images/fileType/file_audio.png";
+import file_video from "@/assets/images/fileType/file_video.png";
+import file_zip from "@/assets/images/fileType/file_zip.png";
+//----------------------------------------
 const searchType = ref("all");
-const baseData = ref();
-const tableData = ref()
+const baseData = ref(); //拿到的全部数据
+const typeData = ref(); //当前分类下的数据
+const tableData = ref(); // 表格展示的数据
+const searchFire = ref();
+const copyFileType = ref();
 
+const props = defineProps({
+  fileList: {
+    type: Array,
+    default: () => [],
+  },
+});
+const emit = defineEmits(["handleRowClick"]);
 // 切换搜索分类
 const changeSearchType = (name) => {
-  // let baseDataObj = toRaw(baseData.value);
+  let baseDataObj = props.fileList;
   // console.log("baseDataObj", baseDataObj);
-  // if (name == "all") {
-  //   tableData.value = baseDataObj;
-  // } else {
-  //   // 获取分类具体数据
-  //   console.log(name, "name");
-  //   console.log(searchFor.value, "searchFor");
-  //   const typeArr = setType(name);
-  //   console.log(typeArr, "类型");
-  //   tableData.value = toRaw(baseDataObj).filter((item) => {
-  //     console.log(item, "遍历");
-  //     return (
-  //       typeArr.includes(item.fileType) &&
-  //       (item.space.spaceType == searchFor.value || searchFor.value == "")
-  //     );
-  //   });
-  //   console.log(tableData.value, "数组");
-  // }
+  if (name == "all") {
+    tableData.value = baseDataObj;
+  } else {
+    // 获取分类具体数据
+    // console.log("name", name);
+    const typeArr = setType(name);
+    // console.log(typeArr, "类型");
+    typeData.value = toRaw(baseDataObj).filter((item) => {
+      return typeArr.includes(item.fileType);
+    });
+    tableData.value = typeData.value;
+    // console.log(tableData.value, "数组");
+  }
+};
+//搜索框模糊搜索事件
+const fileBlur = () => {
+  const arr = typeData.value;
+  tableData.value = arr.filter((item) => {
+    if (item.fileName.includes(searchFire.value)) {
+      return item;
+    }
+  });
 };
 
+const rightClick = (row, col, e)=>{
+  emit('handleRowClick',row,null,e)
+}
+
 //工具函数
+//对mouseCli数组进行筛选,实现菜单的区分显示
+const filterMouseCli = () => {
+  const canPreviewArray = [
+    ".doc",
+    ".dps",
+    ".et",
+    ".wps",
+    ".docm",
+    ".docx",
+    ".dot",
+    ".dotm",
+    ".dotx",
+    ".epub",
+    ".fodt",
+    ".htm",
+    ".html",
+    ".mht",
+    ".odt",
+    ".ott",
+    ".pdf",
+    ".rtf",
+    ".txt",
+    ".djvu",
+    ".xps",
+    ".csv",
+    ".fods",
+    ".ods",
+    ".ots",
+    ".xls",
+    ".xlsm",
+    ".xlsx",
+    ".xlt",
+    ".xltm",
+    ".xltx",
+    ".fodp",
+    ".odp",
+    ".otp",
+    ".pot",
+    ".potm",
+    ".potx",
+    ".pps",
+    ".ppsm",
+    ".ppsx",
+    ".ppt",
+    ".pptm",
+    ".pptx",
+  ];
+  const typeArr = [".png", ".jpg", ".jpeg", ".JPG", ".PNG", ".mp3", ".mp4"];
+  const imgTypeArr = [".png", ".jpg", ".jpeg", ".JPG", ".PNG"];
+  const canEditArr = [
+    ".doc",
+    ".docm",
+    ".docx",
+    ".dot",
+    ".dotm",
+    ".dotx",
+    ".txt",
+    ".djvu",
+    ".xps",
+    ".csv",
+    ".fods",
+    ".ods",
+    ".ots",
+    ".xls",
+    ".xlsm",
+    ".xlsx",
+    ".xlt",
+    ".xltm",
+    ".xltx",
+    ".fodp",
+    ".odp",
+    ".otp",
+    ".doc",
+    ".docm",
+    ".docx",
+    ".dot",
+    ".dotm",
+    ".dotx",
+    ".epub",
+    ".fodt",
+    ".htm",
+    ".html",
+    ".mht",
+    ".odt",
+    ".ott",
+    ".rtf",
+    ".txt",
+    ".djvu",
+    ".xps",
+    ".wps",
+    ".dps",
+    ".et",
+    ".pptx",
+  ];
+  let arr = [];
+  if (
+    !(
+      typeArr.includes(copyFileType.value) ||
+      canPreviewArray.includes(copyFileType.value)
+    )
+  ) {
+    arr = mouseCli.value.filter((item) => item.name !== "预览");
+  } else {
+    arr = toRaw(mouseCli.value);
+  }
+  if (!canEditArr.includes(copyFileType.value)) {
+    arr = arr.filter(
+      (item) =>
+        item.name !== "在线编辑" &&
+        item.name !== "协作" &&
+        item.name !== "历史版本"
+    );
+  }
+  if (clickRow.value.isFiled === "Y") {
+    arr = arr.filter(
+      (item) => item.name !== "在线编辑" && item.name !== "协作"
+    );
+  }
+  if (!imgTypeArr.includes(copyFileType.value)) {
+    arr = arr.filter((item) => item.name !== "文字识别");
+  }
+  // console.log('arr',arr);
+  if (thisFolderRole.value) {
+    arr = rightMenuRole(toRaw(thisFolderRole.value), arr);
+  }
+  return arr;
+};
 // 设置图标
 const setIcon = (fileType) => {
   switch (fileType) {
@@ -180,6 +337,18 @@ function formatFileSize(fileSize) {
     return fileSize + "B";
   }
 }
+watch(
+  () => props.fileList,
+  (newValue, oldValue) => {
+    tableData.value = newValue;
+    changeSearchType(searchType.value);
+    // console.log("watchtableData", tableData.value);
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
 </script>
 
 <style lang="scss" scoped>
@@ -223,6 +392,58 @@ function formatFileSize(fileSize) {
   }
 }
 
+.setCli {
+  width: 156px;
+  max-height: auto;
+  position: absolute;
+  top: -70px;
+  left: 300px;
+  flex-wrap: 400;
+  background-color: white;
+  border: 1px solid gray;
+  border-radius: 4px;
+  z-index: 3;
+  overflow-y: auto;
+  // font-size: 16px;
+}
+
+.setCli1 {
+  width: 156px;
+  height: auto;
+  position: absolute;
+  background-color: white;
+  border: 1px solid gray;
+  border-radius: 4px;
+  z-index: 100;
+  overflow-y: auto;
+}
+
+.chooseSet {
+  width: 140px;
+  height: 30px;
+  line-height: 30px;
+  margin: 5px auto;
+  font-size: 13px;
+  cursor: pointer;
+  // display: flex;
+  // align-items: center;
+  // position: relative;
+  img {
+    margin-right: 4px;
+    vertical-align: middle;
+  }
+}
+
+.chooseSet:hover {
+  width: 140px;
+  height: 30px;
+  line-height: 30px;
+  margin: 5px auto;
+  font-size: 13px;
+  background-color: #f5f7f9;
+  /* color: white; */
+}
+
 .table_box {
   height: calc(88vh - 48px);
   // border: 1px solid #000;
@@ -248,14 +469,11 @@ function formatFileSize(fileSize) {
   background-color: #2e6bc8;
 }
 
-
-
 :deep(.el-table__inner-wrapper::before) {
   background-color: #fff !important;
 }
 
-:deep(.el-collapse,
-.el-collapse-item__wrap) {
+:deep(.el-collapse, .el-collapse-item__wrap) {
   border: none;
 }
 
@@ -275,13 +493,13 @@ function formatFileSize(fileSize) {
   height: 24px !important;
 }
 
-:deep(.el-collapse-item__arrow ){
+:deep(.el-collapse-item__arrow) {
   position: relative;
   color: #2e6bc8;
   right: 97%;
 }
 
-:deep(.el-table td.el-table__cell ){
+:deep(.el-table td.el-table__cell) {
   border: none;
   font-size: 14px !important;
   font-weight: 400 !important;

+ 80 - 22
src/components/Pdf2Word/Pdf2Word.vue

@@ -4,7 +4,7 @@
     <div v-if="thisStep === 'start'" class="up_box">
       <div class="left_box">
         <div class="upimg_box boder_box">
-          <el-upload
+          <!-- <el-upload
             v-if="!showImg"
             class="avatar-uploader"
             :drag="true"
@@ -17,6 +17,18 @@
           >
             <img src="@/assets/images/Frame427319159.png" class="avatar" />
             <span>将文件拖入框内/点击按钮上传文件</span>
+          </el-upload> -->
+          <el-upload
+            v-if="!showImg"
+            class="avatar-uploader"
+            :drag="true"
+            :http-request="test"
+            accept=".pdf, .PDF"
+            :show-file-list="false"
+            :before-upload="beforeUp"
+          >
+            <img src="@/assets/images/Frame427319159.png" class="avatar" />
+            <span>将文件拖入框内/点击按钮上传文件</span>
           </el-upload>
           <div v-else class="img_show">
             <img :src="toRaw(showImg)" class="avatar" />
@@ -25,10 +37,8 @@
         <div class="sunmit_btn">
           <el-upload
             class="avatar-uploader"
-            :action="actionUrl"
-            :headers="headersObj"
+            :http-request="test"
             :show-file-list="false"
-            :on-success="handleAvatarSuccess"
             :before-upload="beforeUp"
           >
             <span>选择本地文件</span>
@@ -50,7 +60,7 @@
         </div>
         <div class="sunmit_btn" @click="addlibraryImg">添加文库文件</div>
       </div>
-      <el-button @click="test">测试</el-button>
+      <!-- <el-button @click="test">测试</el-button> -->
     </div>
     <div v-if="thisStep === 'loading'" class="load-box">
       <div class="light_box">
@@ -118,6 +128,7 @@ import Loading from '@/components/Loading/Loading.vue'
 import PicTree from '@/components/PicTree/PicTree.vue' //选择文件发送的列表
 import { picTree, pdfTree } from '@/api/search/search.js'
 import { ocrRemark, preview } from '@/api/common/common.js'
+import { getInfo } from '@/api/biz/info.js'
 import Cookies from 'js-cookie'
 import axios from 'axios'
 const textData = ref('') //解析出来的文字
@@ -148,38 +159,82 @@ watch(
   }
 )
 
-const test=function(){
-	const url=`${window.location.origin}${import.meta.env.VITE_APP_BASE_API}/api/test`;
+const test=function(file){
+  console.log('file',file);
+	const url=`${window.location.origin}${import.meta.env.VITE_APP_BASE_API}/biz/info/pdf2word`;
+	 return axios({
+	        method:'post',
+	        url:url,
+	        responseType:'blob',
+          data:file,
+          headers:{
+            "Authorization":Cookies.get('Admin-Token'),
+            'Content-Type': 'multipart/form-data'
+          }
+	    }).then(function(res){
+        console.log('testres',res);
+	        // if(res.headers['content-disposition'] !== undefined){
+	            let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' })
+	            let fileName = decodeURI(res.headers['content-disposition']) 
+	          if (fileName) { 
+	            // fileName = fileName.substring(fileName.indexOf('=') + 1)
+	            // fileName = fileName.substring(0,fileName.lastIndexOf('.'))
+				// alert(fileName)
+	          }
+	          const elink = document.createElement('a') 
+            console.log('fileName',fileName);
+	          elink.download = fileName.replace(new RegExp('"', 'g'), '')+'.docx'
+	          elink.style.display = 'none'
+	          elink.href = URL.createObjectURL(blob) 
+	          document.body.appendChild(elink) 
+	          elink.click() 
+	          URL.revokeObjectURL(elink.href) 
+	          document.body.removeChild(elink) 
+            loadingPreview.value = false
+	        // }
+	    })
+}
+const fileId2Word=function(fileId){
+  console.log('fileId',fileId);
+	const url=`${window.location.origin}${import.meta.env.VITE_APP_BASE_API}/biz/info/pdf2word/${fileId}`;
 	 return axios({
 	        method:'get',
 	        url:url,
-	        responseType:'blob'
+	        responseType:'blob',
+          headers:{
+            "Authorization":Cookies.get('Admin-Token'),
+            'Content-Type': 'multipart/form-data'
+          }
 	    }).then(function(res){
-	        if(res.headers['content-disposition'] !== undefined){
+        console.log('testres',res);
+	        // if(res.headers['content-disposition'] !== undefined){
 	            let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' })
 	            let fileName = decodeURI(res.headers['content-disposition']) 
 	          if (fileName) { 
-	            fileName = fileName.substring(fileName.indexOf('=') + 1)
-				alert(fileName)
+	            // fileName = fileName.substring(fileName.indexOf('=') + 1)
+	            // fileName = fileName.substring(0,fileName.lastIndexOf('.'))
+				// alert(fileName)
 	          }
 	          const elink = document.createElement('a') 
-	          elink.download = fileName 
+            console.log('fileName',fileName);
+	          elink.download = fileName.replace(new RegExp('"', 'g'), '')+'.docx'
 	          elink.style.display = 'none'
 	          elink.href = URL.createObjectURL(blob) 
 	          document.body.appendChild(elink) 
 	          elink.click() 
 	          URL.revokeObjectURL(elink.href) 
 	          document.body.removeChild(elink) 
-	        }
+            loadingPreview.value = false
+	        // }
 	    })
 }
 
 onMounted(async () => {})
 
 const handleAvatarSuccess = (msg, file) => {
-  console.log('re', msg)
+  // console.log('re', msg)
   const flieData = toRaw(file)
-  console.log('file', flieData)
+  // console.log('file', flieData)
   // setTimeout(() => {
   //   downLoadfile(flieData.raw,file);
   // }, 500);
@@ -228,13 +283,16 @@ const addlibraryImg = async () => {
 //确定选中图片
 const fileChangeMsg = async (val) => {
   console.log('val', toRaw(val))
-  const data = toRaw(val)
-  const imgRes = await preview(data.id)
-  thisStep.value = 'loading'
-  showImg.value = URL.createObjectURL(imgRes)
-  const res = await ocrRemark(data.remark)
-  thisStep.value = 'end'
-  textData.value = res.msg
+  loadingPreview.value = true
+  fileId2Word(val.remark)
+  // const res = await getInfo(val.id)
+  // const data = toRaw(val)
+  // const imgRes = await preview(data.id)
+  // thisStep.value = 'loading'
+  // showImg.value = URL.createObjectURL(imgRes)
+  // const res = await ocrRemark(data.remark)
+  // thisStep.value = 'end'
+  // textData.value = res.msg
   // console.log("res", res);
   // console.log("imgRes", imgRes);
 }

+ 2 - 0
src/layout/indexCommon.vue

@@ -520,6 +520,7 @@ const needRepass =async ()=>{
       }
 }
 const clickPath = (index, items) => {
+  console.log('items',items);
   items = toRaw(items);
   localStorage.setItem("inChat", items.path == "/index" ? 1 : 0)
   // toFileData.value = null
@@ -845,6 +846,7 @@ provide("addFolderAdd", addFolderAdd);
 provide("addFileTab", addFileTab);
 provide("upFirstFolderData", upFirstFolderData);
 provide("upFileData", upFileData);
+provide("clickPath", clickPath);
 // TODO 删除tab事件
 const closeTab = (item, index, e) => {
   e.preventDefault();

+ 298 - 180
src/views/myfile/MyFile.vue

@@ -22,12 +22,12 @@
                             <Search />
                         </el-icon>
                         <div class="left_changeShow">
-                            <img v-if="leftShowList" src="@/assets/images/squre.png" @click="changeLeftShow" alt="">
+                            <img v-if="leftShowList == 1" src="@/assets/images/squre.png" @click="changeLeftShow" alt="">
                             <img v-else src="@/assets/images/Frame_187.png" @click="changeLeftShow" alt="">
                         </div>
                     </div>
                     <!-- v-for盒子 -->
-                    <div v-if="leftShowList"
+                    <div v-if="leftShowList == 1"
                         style="display: flex;justify-content: flex-start;align-items: flex-start;flex-wrap: wrap;align-content: flex-start;overflow-y: auto;">
                         <template v-for="(item, index) in fileMenu" :key="index">
                             <div class="setBox">
@@ -62,7 +62,7 @@
                             </div>
                         </template>
                     </div>
-                    <LeftList v-else :spaceType="3" @folderClick="folderClick"></LeftList>
+                    <LeftList v-else :spaceType="3" :ListtreeData="ListtreeData" @listfolderClick="listfolderClick"></LeftList>
                 </div>
                 <div class="expansion">
                     <div class="top_box">
@@ -96,7 +96,7 @@
                     <!-- 众多功能 -->
                     <div class="manyUse">
                         <div class="useMenu">
-                            <div v-if="thisFolder.dirType == '1' && pathLabelData.length"
+                            <div v-if="thisFolder.dirType == '1' && (pathLabelData.length || leftShowList == 0)  && thisFolder.parentId != 0"
                                 style="display: flex;width: 92px;height: 32px;justify-content: flex-start;align-items: center;line-height: 18px;">
                                 <div style="margin-left: 5px;">
                                     <img src="../../assets/images/upload.png" style="width: 24px;height: 24px;" alt="">
@@ -192,192 +192,211 @@
                             <span>使用右键进行文件操作</span>
                        </div>
                     </div>
-                    <div v-if="leftShowList">
-                    <!-- 面包屑功能栏 -->
-                    <div class="breadBox">
-                        <!-- 左侧 -->
-                        <div style="display: flex;justify-content: space-around;align-items: center;margin-left: 10px;">
-                            <!-- 前进后退 -->
-                            <!-- <div style="display: flex;justify-content: space-around;align-items: center;">
-                                <img style="display:block;width: 11px;height: 11px;" :src="blueLeft" alt=""
-                                    @click="arrowLift">
-                                <img style="display:block;width: 16px;height: 16px;" :src="grayRight" alt="">
-                            </div> -->
-                            <!-- 面包屑 -->
-                            <div class="topPath">
-                                <!-- <el-icon><ArrowDown /></el-icon> -->
-                                <span @click="backTopPath">{{ topPath }}</span>
-                                <PathLabel v-if="!loadingPreview" @folderClick="folderClick" :pathLabelData='pathLabelData'></PathLabel>
-                                <!-- <BreadMenu></BreadMenu> -->
+                    <div v-show="leftShowList == 1">
+                        <!-- 面包屑功能栏 -->
+                        <div class="breadBox">
+                            <!-- 左侧 -->
+                            <div style="display: flex;justify-content: space-around;align-items: center;margin-left: 10px;">
+                                <!-- 前进后退 -->
+                                <!-- <div style="display: flex;justify-content: space-around;align-items: center;">
+                                    <img style="display:block;width: 11px;height: 11px;" :src="blueLeft" alt=""
+                                        @click="arrowLift">
+                                    <img style="display:block;width: 16px;height: 16px;" :src="grayRight" alt="">
+                                </div> -->
+                                <!-- 面包屑 -->
+                                <div class="topPath">
+                                    <!-- <el-icon><ArrowDown /></el-icon> -->
+                                    <span @click="backTopPath">{{ topPath }}</span>
+                                    <PathLabel v-if="!loadingPreview" @folderClick="folderClick" :pathLabelData='pathLabelData'></PathLabel>
+                                    <!-- <BreadMenu></BreadMenu> -->
+                                </div>
                             </div>
-                        </div>
-                        <!-- 右侧 -->
-                        <div>
-                             <img
-                                src="@/assets/images/sort.png"
-                                @click="changeSort"
-                                v-if="isAsc == 'asc'"
+                            <!-- 右侧 -->
+                            <div>
+                                <img
+                                    src="@/assets/images/sort.png"
+                                    @click="changeSort"
+                                    v-if="isAsc == 'asc'"
+                                    alt=""
+                                />
+                                <img
+                                    src="@/assets/images/Frame_188.png"
+                                    @click="changeSort"
+                                    v-else
+                                    alt=""
+                                />
+                                <!-- //控制宫格展示 -->
+                                <img
+                                v-if="fileGrid"
+                                src="@/assets/images/squre.png"
+                                class="shouzhi palace-grid"
                                 alt=""
-                            />
-                            <img
-                                src="@/assets/images/Frame_188.png"
-                                @click="changeSort"
+                                @click="changeShow(true)"
+                                />
+                                <img
                                 v-else
+                                src="@/assets/images/Frame_187.png"
+                                class="shouzhi palace-grid"
                                 alt=""
-                            />
-                            <!-- //控制宫格展示 -->
-                            <img
-                              v-if="fileGrid"
-                              src="@/assets/images/squre.png"
-                              class="shouzhi palace-grid"
-                              alt=""
-                              @click="changeShow(true)"
-                            />
-                            <img
-                              v-else
-                              src="@/assets/images/Frame_187.png"
-                              class="shouzhi palace-grid"
-                              alt=""
-                              @click="changeShow(false)"
-                            />
-                            <!-- <img :src="squre" alt="" @click="gridChange" class="shouzhi"> -->
-                        </div>
-                    </div>
-                <!-- </div> -->
-                <!-- 展示文件夹盒子 -->
-                <!-- 文件夹 -->
-                <div class="showBox">
-                    <div class="detailBox file-jia" @click="mouseClick">
-                        <el-collapse v-model="folder" >
-                            <el-collapse-item name="1" class="custom-collapse-item">
-                                <template #title>
-                                    <span class="file-title">文件夹</span>
-                                </template>
-                                <el-table v-if="fileGrid == 1" height="37vh" :data="folderList" style="width: 100%" :scrollbar-always-on="true"
-                                    @selection-change="handleSelectionChange1" :single-select="true" @row-click="folderClick"
-                                    @row-contextmenu="folderRClick" ref="taskTableRef">
-                                    <el-table-column type="selection" width="55" />
-                                    <el-table-column label="名称" :show-overflow-tooltip="true" width="600">
-                                        <template #default="scope">
-                                            <span style="display: flex;align-items: center;">
-                                                <el-icon v-if="scope.row.isFavorite == 'N'" @click.stop="collectByStar(scope.row,true)" style="margin-right: 7px;">
-                                                    <Star />
-                                                </el-icon>
-                                                <img v-else @click.stop="delCollect(scope.row,true)" src="../../assets/images/yellowstar.png" alt="">
-                                                <img src="../../assets/images/fileBox.png" style="width: 20px;height: 24px;margin-right: 5px;"
-                                                    alt="">
-                                                    <span class="shouzhi">{{ scope.row.dirName }}</span>
-                                                </span>
-                                            </template>
-                                        </el-table-column>
-                                        <el-table-column prop="createTime" label="时间" width="280" />
-                                        <el-table-column label="加密等级">
-                                            <template #default="scope">
-                                                <span>
-                                                    {{setTablelevel(scope.row.encryptLevel)}}
-                                                </span>
-                                            </template>
-                                        </el-table-column>
-                                    </el-table>
-                                    <PlaceGridFolder v-else @folderClick="folderClick" :folderList="folderList" :restName="restName"
-                                        :collectFolder="collectFolder" @collectByStar="collectByStar" @delCollect="delCollect" @setScroll="setScroll" @folderRClick="folderRClick" :getAllTop="getAllTop" @folderBack="folderBack" :thisFolder="thisFolder">
-                                    </PlaceGridFolder>
-                                </el-collapse-item>
-                            </el-collapse>
-                            <!-- 右键唤出的菜单 -->
-                            <div class="right_menu shouzhi" v-if="folderVisible"
-                                :style="{ left: folderleft + 'px', top: foldertop + 'px' }">
-                                <!-- <div class="menu_item" @click="folderClick(null, null)">
-                                    <img src="@/assets/images/trash.png" alt="" />
-                                    <span>打开</span>
-                                </div> -->
-                                <div class="menu_item" @click="restName(null, null)">
-                                    <img src="@/assets/images/textbox.png" alt="" />
-                                    <span>重命名</span>
-                                </div>
-                                <div class="menu_item" @click="collectFolder">
-                                    <img src="@/assets/images/collect.png" alt="" />
-                                    <span>收藏</span>
-                                </div>
+                                @click="changeShow(false)"
+                                />
+                                <!-- <img :src="squre" alt="" @click="gridChange" class="shouzhi"> -->
                             </div>
                         </div>
-                        <!-- 文件 -->
-                        <div class="fileTable">
-                            <el-collapse v-model="files">
-                                <el-collapse-item name="2" class="custom-collapse-item">
+                    <!-- </div> -->
+                    <!-- 展示文件夹盒子 -->
+                    <!-- 文件夹 -->
+                        <div class="showBox">
+                            <div class="detailBox file-jia" @click="mouseClick">
+                            <el-collapse v-model="folder" >
+                                <el-collapse-item name="1" class="custom-collapse-item">
                                     <template #title>
-                                       <span class="file-title">文件</span>
+                                        <span class="file-title">文件夹</span>
                                     </template>
-                                    <el-table v-el-table-infinite-scroll="setScroll" :infinite-scroll-distance="30"
-                                        :infinite-scroll-disabled="tableBeEnd" v-if="fileGrid == 1" :height="fileHeight"
-                                        :data="fileList" :scrollbar-always-on="true" style="width: 100%;"
-                                        @row-contextmenu="handleRowClick" @selection-change="handleSelectionChange"
-                                        @row-click="mouseClick" :default-sort="{ prop: 'createTime', order: 'descending' }">
+                                    <el-table v-if="fileGrid == 1" height="37vh" :data="folderList" style="width: 100%" :scrollbar-always-on="true"
+                                        @selection-change="handleSelectionChange1" :single-select="true" @row-click="folderClick"
+                                        @row-contextmenu="folderRClick" ref="taskTableRef">
                                         <el-table-column type="selection" width="55" />
-                                        <el-table-column label="名称" width="600">
+                                        <el-table-column label="名称" :show-overflow-tooltip="true" width="600">
                                             <template #default="scope">
-                                                <span
-                                                    style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;display: flex;align-items: center;">
-                                                    <el-icon v-if="scope.row.isFavorite == 'N'"
-                                                        @click.stop="collectByStar(scope.row, false)"
-                                                        style="margin-right: 7px;">
+                                                <span style="display: flex;align-items: center;">
+                                                    <el-icon v-if="scope.row.isFavorite == 'N'" @click.stop="collectByStar(scope.row,true)" style="margin-right: 7px;">
                                                         <Star />
                                                     </el-icon>
-                                                    <img v-else @click.stop="delCollect(scope.row, false)"
-                                                        src="../../assets/images/yellowstar.png" alt=""
-                                                        style="margin-right: 5px;">
-                                                    <img :src="setImg(scope.row.fileType)" style="width:22px;height:22px;" alt="">
-                                                    <el-tooltip class="box-item" effect="dark" placement="top"
-                                                        :show-after="1000" :content="scope.row.fileName">
-                                                        <!-- <template #content> {{ scope.row.encryptLevel == 'L1'?'敏感':(scope.row.encryptLevel == 'L2'?'涉密':(scope.row.encryptLevel == 'L3'?'机密':'绝密')) }} </template> -->
-                                                        <span class="shouzhi">{{ scope.row.fileName }}</span>
-                                                    </el-tooltip>
-                                                    <!-- <span class="shouzhi">{{ scope.row.fileName }}</span> -->
-                                                </span>
-                                            </template>
-                                        </el-table-column>
-                                        <el-table-column prop="createTime" label="时间" sortable width="280" />
-                                        <el-table-column prop="fileType" label="类型" />
-                                        <el-table-column label="大小">
-                                            <template #default="scope">
-                                                <span>
-                                                    {{ formatFileSize(scope.row.fileSize) }}
-                                                </span>
-                                            </template>
-                                        </el-table-column>
-                                    </el-table>
-                                    <PalaceGridFile v-else :fileHeight="fileHeight" :getAllTop="getAllTop" @navBack="navBack"
-                                        @lastBB="lastBB"  @collectByStar="collectByStar" @delCollect="delCollect" @setScroll="setScroll" @handleRowClick="handleRowClick" @onlineCase="onlineCase" @shareBack="shareBack" :thisFolder="thisFolder" :fileList="fileList"></PalaceGridFile>
-                                </el-collapse-item>
-                            </el-collapse>
-                            <div class="setCli" v-if="cliCC" :style="{ left: xz + 'px', top: yz - 260 + 'px' }">
-                                <template v-for="(item, index) in filterMouseCli()" :key="index">
-                                    <p @click="chooseSet(item, index, 1)" class="chooseSet">
-                                        <img :src="item.img" alt="">
-                                        {{ item.name }}
-                                        <span v-if=" item.name == '协作' ? true : false"
-                                            style="color: #7084B4;float: right;position: relative;" class="arrow">></span>
-                                    </p>
-                                </template>
+                                                    <img v-else @click.stop="delCollect(scope.row,true)" src="../../assets/images/yellowstar.png" alt="">
+                                                    <img src="../../assets/images/fileBox.png" style="width: 20px;height: 24px;margin-right: 5px;"
+                                                        alt="">
+                                                        <span class="shouzhi">{{ scope.row.dirName }}</span>
+                                                    </span>
+                                                </template>
+                                            </el-table-column>
+                                            <el-table-column prop="createTime" label="时间" width="280" />
+                                            <el-table-column label="加密等级">
+                                                <template #default="scope">
+                                                    <span>
+                                                        {{setTablelevel(scope.row.encryptLevel)}}
+                                                    </span>
+                                                </template>
+                                            </el-table-column>
+                                        </el-table>
+                                        <PlaceGridFolder v-else @folderClick="folderClick" :folderList="folderList" :restName="restName"
+                                            :collectFolder="collectFolder" @collectByStar="collectByStar" @delCollect="delCollect" @setScroll="setScroll" @folderRClick="folderRClick" :getAllTop="getAllTop" @folderBack="folderBack" :thisFolder="thisFolder">
+                                        </PlaceGridFolder>
+                                    </el-collapse-item>
+                                </el-collapse>
+                                <!-- 右键唤出的菜单 -->
+                                <div class="right_menu shouzhi" v-if="folderVisible"
+                                    :style="{ left: folderleft + 'px', top: foldertop + 'px' }">
+                                    <!-- <div class="menu_item" @click="folderClick(null, null)">
+                                        <img src="@/assets/images/trash.png" alt="" />
+                                        <span>打开</span>
+                                    </div> -->
+                                    <div class="menu_item" @click="restName(null, null)">
+                                        <img src="@/assets/images/textbox.png" alt="" />
+                                        <span>重命名</span>
+                                    </div>
+                                    <div class="menu_item" @click="collectFolder">
+                                        <img src="@/assets/images/collect.png" alt="" />
+                                        <span>收藏</span>
+                                    </div>
+                                </div>
                             </div>
-                            <div class="setCli1" v-if="anyP" :style="{ left: xz + 155 + 'px', top: yz + 'px' }">
-                                <p @click="chooseSet1(0)" class="chooseSet">
-                                    <img src="../../assets/images/user.png" alt="">
-                                    选择人员
-                                </p>
-                                <p class="chooseSet" @click="goLock" v-if="clickRow.isActor === 'Y' && clickRow.isFiled != 'Y'">
-                                    <img src="../../assets/images/archiveTray.png" alt="">
-                                    归档
-                                </p>
+                            <!-- 文件 -->
+                            <div class="fileTable">
+                                <el-collapse v-model="files">
+                                    <el-collapse-item name="2" class="custom-collapse-item">
+                                        <template #title>
+                                        <span class="file-title">文件</span>
+                                        </template>
+                                        <el-table v-el-table-infinite-scroll="setScroll" :infinite-scroll-distance="30"
+                                            :infinite-scroll-disabled="tableBeEnd" v-if="fileGrid == 1" :height="fileHeight"
+                                            :data="fileList" :scrollbar-always-on="true" style="width: 100%;"
+                                            @row-contextmenu="handleRowClick" @selection-change="handleSelectionChange"
+                                            @row-click="mouseClick" :default-sort="{ prop: 'createTime', order: 'descending' }">
+                                            <el-table-column type="selection" width="55" />
+                                            <el-table-column label="名称" width="600">
+                                                <template #default="scope">
+                                                    <span
+                                                        style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;display: flex;align-items: center;">
+                                                        <el-icon v-if="scope.row.isFavorite == 'N'"
+                                                            @click.stop="collectByStar(scope.row, false)"
+                                                            style="margin-right: 7px;">
+                                                            <Star />
+                                                        </el-icon>
+                                                        <img v-else @click.stop="delCollect(scope.row, false)"
+                                                            src="../../assets/images/yellowstar.png" alt=""
+                                                            style="margin-right: 5px;">
+                                                        <img :src="setImg(scope.row.fileType)" style="width:22px;height:22px;" alt="">
+                                                        <el-tooltip class="box-item" effect="dark" placement="top"
+                                                            :show-after="1000" :content="scope.row.fileName">
+                                                            <!-- <template #content> {{ scope.row.encryptLevel == 'L1'?'敏感':(scope.row.encryptLevel == 'L2'?'涉密':(scope.row.encryptLevel == 'L3'?'机密':'绝密')) }} </template> -->
+                                                            <span class="shouzhi">{{ scope.row.fileName }}</span>
+                                                        </el-tooltip>
+                                                        <!-- <span class="shouzhi">{{ scope.row.fileName }}</span> -->
+                                                    </span>
+                                                </template>
+                                            </el-table-column>
+                                            <el-table-column prop="createTime" label="时间" sortable width="280" />
+                                            <el-table-column prop="fileType" label="类型" />
+                                            <el-table-column label="大小">
+                                                <template #default="scope">
+                                                    <span>
+                                                        {{ formatFileSize(scope.row.fileSize) }}
+                                                    </span>
+                                                </template>
+                                            </el-table-column>
+                                        </el-table>
+                                        <PalaceGridFile v-else :fileHeight="fileHeight" :getAllTop="getAllTop" @navBack="navBack"
+                                            @lastBB="lastBB"  @collectByStar="collectByStar" @delCollect="delCollect" @setScroll="setScroll" @handleRowClick="handleRowClick" @onlineCase="onlineCase" @shareBack="shareBack" :thisFolder="thisFolder" :fileList="fileList"></PalaceGridFile>
+                                    </el-collapse-item>
+                                </el-collapse>
+                                <!-- <div class="setCli" v-if="cliCC" :style="{ left: xz + 'px', top: yz - 260 + 'px' }">
+                                    <template v-for="(item, index) in filterMouseCli()" :key="index">
+                                        <p @click="chooseSet(item, index, 1)" class="chooseSet">
+                                            <img :src="item.img" alt="">
+                                            {{ item.name }}
+                                            <span v-if=" item.name == '协作' ? true : false"
+                                                style="color: #7084B4;float: right;position: relative;" class="arrow">></span>
+                                        </p>
+                                    </template>
+                                </div>
+                                <div class="setCli1" v-if="anyP" :style="{ left: xz + 155 + 'px', top: yz + 'px' }">
+                                    <p @click="chooseSet1(0)" class="chooseSet">
+                                        <img src="../../assets/images/user.png" alt="">
+                                        选择人员
+                                    </p>
+                                    <p class="chooseSet" @click="goLock" v-if="clickRow.isActor === 'Y' && clickRow.isFiled != 'Y'">
+                                        <img src="../../assets/images/archiveTray.png" alt="">
+                                        归档
+                                    </p>
+                                </div> -->
                             </div>
                         </div>
                     </div>
-                    </div>
-                    <ListShow v-else></ListShow>
+                    <ListShow v-show="leftShowList == 0" :fileList="fileList" @handleRowClick="handleRowClick"></ListShow>
 
                 </div>
             </div>
-
+            <div class="setCli" v-if="cliCC" :style="{ left: xz + 'px', top: yz - 260 + 'px' }">
+                <template v-for="(item, index) in filterMouseCli()" :key="index">
+                    <p @click="chooseSet(item, index, 1)" class="chooseSet">
+                        <img :src="item.img" alt="">
+                        {{ item.name }}
+                        <span v-if=" item.name == '协作' ? true : false"
+                            style="color: #7084B4;float: right;position: relative;" class="arrow">></span>
+                    </p>
+                </template>
+            </div>
+            <div class="setCli1" v-if="anyP" :style="{ left: xz + 155 + 'px', top: yz + 'px' }">
+                <p @click="chooseSet1(0)" class="chooseSet">
+                    <img src="../../assets/images/user.png" alt="">
+                    选择人员
+                </p>
+                <p class="chooseSet" @click="goLock" v-if="clickRow.isActor === 'Y' && clickRow.isFiled != 'Y'">
+                    <img src="../../assets/images/archiveTray.png" alt="">
+                    归档
+                </p>
+            </div>
             <!-- 扩容弹窗 -->
             <div>
                 <SpaceBig v-if="spaces" :spaces="spaces" :impSpaceId="impSpaceId" @getSpaceC="getSpaceC"></SpaceBig>
@@ -734,6 +753,7 @@ export default {
         const addFileTab = inject("addFileTab");
         const addFolderAdd = inject("addFolderAdd");
         const upFileData = inject("upFileData");
+        const clickPath = inject("clickPath");
         const spaceName = ref()
         const filePageNum = ref(1) //获取文件分页
         const tableBeEnd = ref(true)//控制下拉是否到底
@@ -758,7 +778,9 @@ export default {
         const inputTitle = ref()//验证框标题
         const isCode = ref(false)// 验证的类型
         const isAsc = ref("desc");
-        const leftShowList = ref(false)
+        const leftShowList = ref(localStorage.getItem('leftShowList') ||1)
+        const thisFirst = ref()
+        const ListtreeData = ref()
         const changeSort = async () => {
             isAsc.value == "asc" ? (isAsc.value = "desc") : (isAsc.value = "asc");
             refreshFile()
@@ -864,11 +886,35 @@ export default {
                 })
         }
         function getSpaceList() {
+            getFileTree()
+            // ListShowRef.value?.getFileTree()
             myfile.fileType(3).then(res => {
                 useSpace.value = res.data.usedCap
                 allSpace.value = res.data.spaceCap
             })
         }
+        //获取文件树
+        function getFileTree() {
+        documents.fileTree(3).then((res) => {
+            res.disabled = true;
+            ListtreeData.value = [res];
+            function getAllNodeIds(nodes) {
+            nodes.forEach((node) => {
+                if (node.remark) {
+                node.remark = JSON.parse(node.remark);
+                }
+                if (node.children && node.children.length > 0) {
+                getAllNodeIds(node.children);
+                }
+            });
+            return nodes;
+            }
+            // 调用递归函数获取所有节点的 id
+            getAllNodeIds(ListtreeData.value);
+            // console.log("treedataarr", arr);
+            // console.log("treeData", treeData.value);
+        });
+        }
         function changeFile(row, num) {
             // 创建标签
              const labelItem = {
@@ -1453,10 +1499,13 @@ export default {
         }
 
         // 文件夹每行点击事件
-        function folderClick(row, list,e,jump) {
+        function folderClick(row, list,e,jump,firstData) {
+            // console.log('firstData',firstData);
+            // console.log('list',list);
+            // console.log('row',row);
             // console.log('rightRow',row);
             // 如果label没有值说明点的是一级目录
-            if(!pathLabelData.value[0]){
+            if(!pathLabelData.value[0] && leftShowList.value == 1){
                  // 创建标签
                 const addData = {
                     path: '/myfile' + row.dirId,
@@ -1545,6 +1594,54 @@ export default {
                 }
             })
         }
+        // 左边树节点每行点击事件
+        function listfolderClick(row,firstData) {
+            thisFolder.value = row
+            if (row.isEncrypt === "Y") {
+                getLeveldetailFn(row.encryptLevel)
+            } else {
+                thisFolderRole.value = null
+            }
+            console.log('row',row);
+            newDirId.value = row.dirId
+            newSpaceId.value = row.spaceId
+            clickFileData.value = row
+             const query = `${newDirId.value}?isAsc=${isAsc.value}&orderByColumn=createTime&pageSize=9999&pageNum=1`
+            documents.getALLdocumentByType({
+                parentId: newDirId.value - 0,
+                spaceId: newSpaceId.value - 0,
+                isAsc: isAsc.value,
+                orderByColumn: "createTime"
+            }, 3).then(res => {
+                folderList.value = res.rows
+                if (res.rows.length === 0) {
+                    myfile.getById(query).then(res => {
+                        // console.log('res = ',res);
+                        if (res.code === 200) {
+                            tableTotal.value = res.total
+                            if (res.rows.length < res.total) {
+                                //第一次拿到的数据少于总数开启下拉事件
+                                tableBeEnd.value = false
+                            }
+                            fileList.value = JSON.parse(JSON.stringify(res.rows))
+                        }
+                    // console.log('folderClickshijian1',tableTotal.value,tableBeEnd.value);
+                    })
+                } else {
+                    myfile.getById(query).then(res => {
+                        if (res.code === 200) {
+                            tableTotal.value = res.total
+                            if (res.rows.length < res.total) {
+                                //第一次拿到的数据少于总数开启下拉事件
+                                tableBeEnd.value = false
+                            }
+                            fileList.value = JSON.parse(JSON.stringify(res.rows))
+                        }
+                        // console.log('fileList',fileList.value);
+                    })
+                }
+            })
+        }
         // 确认文件重命名
         function sureChangeName() {
             myfile.editNewMenu({
@@ -1802,7 +1899,7 @@ export default {
             if(edit){
                 getFirstFolder()
             }
-            if (toRaw(thisFolder.value).dirId && !leftNewFile.value) {//如果点开了文件夹
+            if (toRaw(thisFolder.value)?.dirId && !leftNewFile.value) {//如果点开了文件夹
                 folderClick()
                 console.log(111);
             } else {
@@ -2101,7 +2198,20 @@ export default {
             }
         }
         const changeLeftShow = ()=>{
-            leftShowList.value = leftShowList.value?false:true
+            console.log('changeLeftShow',leftShowList.value);
+            leftShowList.value = leftShowList.value == 1?0:1
+            console.log('changeLeftShow-',leftShowList.value);
+            thisFolder.value = {}
+            localStorage.setItem('leftShowList',leftShowList.value)
+            if(!leftShowList.value){
+                console.log('toList');
+                 // 创建标签
+                const addData = {
+                    path: '/myfile',
+                    label: '我的文件'
+                }
+                clickPath(null,addData)
+            }
         }
         watch(() => folder.value, async(newValue, oldValue) => {
             // console.log('iFrameData 发生改变了', newValue, oldValue);
@@ -2157,6 +2267,7 @@ export default {
         });
         onMounted(() => {
             // if(!thisFolder.value){
+            leftShowList.value = localStorage.getItem('leftShowList') ||0
             getAllTop()
             // }
             getSpaceList()
@@ -2171,11 +2282,12 @@ export default {
             changePageSizeFn()
             window.addEventListener("click", closeRMenu, true);
             window.addEventListener("click", mouseClick, true);
-            // console.log('onMounted');
+            console.log('leftShowList',leftShowList.value);
+            console.log('onMounted');
         })
         // 组件显示
         onActivated(() => {
-            // console.log('onActivated.query',route.query);
+            console.log('onActivated.query',route.query);
             loadingPreview.value = true
             //给pagesize复制
 
@@ -2191,7 +2303,7 @@ export default {
             setTimeout(() => {
                 if (route.query.clickRowId) {
                     const newRow = JSON.parse(route.query.clickRowId)
-                    // console.log('newRow',newRow);
+                    console.log('newRow',newRow);
                     myfile.getDir(newRow).then(res => {
                         // console.log('tores',res);
                         thisFolder.value = res.data
@@ -2205,6 +2317,7 @@ export default {
                         refreshFile()
                     })
                 }
+                leftShowList.value = localStorage.getItem('leftShowList') ||0
                 loadingPreview.value = false
             }, 500)
 
@@ -2452,7 +2565,12 @@ export default {
             isAsc,
             changeSort,
             leftShowList,
-            changeLeftShow
+            changeLeftShow,
+            thisFirst,
+            listfolderClick,
+            clickPath,
+            ListtreeData,
+            getFileTree
         }
     },
     watch: {