liuQiang 1 jaar geleden
bovenliggende
commit
004554a5f5

+ 8 - 0
src/api/search/search.js

@@ -7,6 +7,14 @@ export function search(query) {
     params: query
   })
 }
+export function searchAll(query) {
+  return request({
+    url: '/es/search',
+    method: 'get',
+    timeout: 10*60*1000,//配置超时时间
+    params: query
+  })
+}
 export function flieSearch(query) {
   return request({
     url: '/biz/info/search',

BIN
src/assets/images/newIndex/yunBlack.png


+ 56 - 4
src/layout/NewIndex.vue

@@ -5,7 +5,15 @@
       :systemPath="systemPath"
       :hasRole="hasRole"
     ></TopMenu>
-    <DefaultPage @openMaxmin="openMaxmin"></DefaultPage>
+    <DefaultPage
+      :showSearch="showSearch"
+      :hightData="hightData"
+      :allData="allData"
+      :hightDataTotal="hightDataTotal"
+      :allDataTotal="allDataTotal"
+      @changeSearch="changeSearch"
+      @openMaxmin="openMaxmin"
+    ></DefaultPage>
     <div class="footer"></div>
   </div>
 </template>
@@ -18,6 +26,8 @@ import { layer } from "@layui/layer-vue";
 import { ElMessage, ElLoading, ElMessageBox } from "element-plus";
 import useUserStore from "@/store/modules/user";
 import usePermissionStore from "@/store/modules/permission";
+import { searchAll } from "@/api/search/search.js";
+import { flieSearch } from "@/api/search/search.js";
 const permissionStore = usePermissionStore();
 const sidebarRouters = computed(() => permissionStore.sidebarRouters);
 const roles = useUserStore().roles;
@@ -28,7 +38,13 @@ const hasRole = ref(
     return super_admin === role || permissionRoles.includes(role);
   })
 );
+const showSearch = ref(false); //是否显示搜索结果界面
 const systemPath = ref({});
+const searchText = ref(""); //搜索框的值
+const hightData = ref([]); // 高级搜索数据
+const allData = ref([]); // 全域搜索数据
+const hightDataTotal = ref(); // 高级搜索数据总数
+const allDataTotal = ref(); // 全域搜索数据总数
 
 // 将标签信息保存到本地
 const openMaxmin = (title, path) => {
@@ -59,7 +75,7 @@ const openMaxmin = (title, path) => {
       shadeClose: false, // 点击遮罩关闭
       area: ["80%", "80%"], //大小
       close: (id) => {
-        console.log(`关闭:${id}`);
+        // console.log(`关闭:${id}`);
         const oldData = JSON.parse(sessionStorage.getItem("tagList"));
         // 删除本地存储中该标签的数据
         const newStorage = oldData.filter((item) => item.id !== id);
@@ -82,7 +98,7 @@ const openMaxmin = (title, path) => {
       shadeClose: false, // 点击遮罩关闭
       area: ["80%", "80%"], //大小
       close: (id) => {
-        console.log(`关闭:${id}`);
+        // console.log(`关闭:${id}`);
         // 删除本地存储中该标签的数据
         const oldData = JSON.parse(sessionStorage.getItem("tagList"));
         const newStorage = oldData.filter((item) => item.id !== id);
@@ -105,7 +121,7 @@ onMounted(() => {
       break;
   }
   if (hasRole.value) {
-    console.log("sidebarRouters", sidebarRouters.value);
+    // console.log("sidebarRouters", sidebarRouters.value);
     const thisItem = sidebarRouters.value.find(
       (item) => item.redirect == "noRedirect"
     ); //拿到系统管理的第一个菜单 判断依据:第一个redirect == "noRedirect"的路由
@@ -122,6 +138,42 @@ onMounted(() => {
     };
   }
 });
+const changeSearch = async (val, text) => {
+  showSearch.value = val;
+  searchText.value = text;
+  if (val) {
+    if (!searchText.value) {
+      return;
+    }
+    const query = {
+      keyword: searchText.value,
+      page: 1,
+      size: 999,
+    };
+    const allQuery = {
+      keyword: searchText.value,
+      isAsc: "asc",
+      orderByColumn: "createTime",
+      pageSize: 99999,
+      pageNum: 1,
+    };
+    //高级搜索
+    searchAll(query).then((res) => {
+      // console.log("hightData", res);
+      if (res.data) {
+        hightData.value = res.data;
+        hightDataTotal.value = res.total;
+      }
+    });
+
+    // 全域搜索
+    flieSearch(allQuery).then((res2) => {
+      allData.value = res2.rows;
+      allDataTotal.value = res2.total;
+      // console.log("allData", res2);
+    });
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 393 - 16
src/layout/components/DefaultPage/DefaultPage.vue

@@ -1,20 +1,115 @@
 <template>
   <div class="main">
-    <div class="search">
-      <input type="text" class="search_input" placeholder="请输入关键字" />
-      <div class="searchBtn">
-        <img src="@/assets/images/newIndex/search.png" alt="" />
-        <span>全域瞬搜</span>
+    <div class="topBox">
+      <div class="upload" v-if="isSearch">
+        <el-upload
+          class="upload-show"
+          :file-list="fileArr"
+          :limit="10"
+          :on-change="upBefore"
+          :show-file-list="false"
+          drag
+          :http-request="onSuccess"
+          multiple
+          element-loading-text="上传中..."
+          element-loading-background="rgba(255, 255, 255, 0.8)"
+          v-loading="loadingUpload"
+        >
+          <img src="@/assets/images/newIndex/yunBlack.png" alt="" />
+          <span class="text1">上传文件</span>
+          <p class="text2">
+            将文件拖到此处或 <span class="blueT">选择文件</span>
+          </p>
+        </el-upload>
+        <div class="right">
+          <div class="line">|</div>
+          <img
+            src="@/assets/images/newIndex/scan.png"
+            @click="scannerFile"
+            class="scanImg"
+            alt=""
+          />
+        </div>
+      </div>
+      <div class="search" :class="{ 'showSearch': isSearch }">
+        <input
+          type="text"
+          class="search_input"
+          v-model="searchText"
+          placeholder="请输入关键字"
+        />
+        <div class="searchBtn" @click="searchBtn">
+          <img src="@/assets/images/newIndex/search.png" alt="" />
+          <span>全域瞬搜</span>
+        </div>
+      </div>
+    </div>
+    <div v-if="isSearch" class="searchBtm">
+      <div class="highSearch">
+        <div class="title">共查询到{{ props.hightDataTotal }}个相关结果</div>
+        <div class="list">
+          <div class="oneBox" v-for="item in hightData" :key="item.id">
+            <span class="fileName">{{ item.content.docInfo.fileName }}</span>
+            <div class="flieTime">
+              <span>创建时间:</span>
+              <span>{{ item.content.docInfo.createTime }}</span>
+              <div class="position">
+                <span>文件位置:</span>
+                <span>{{ item.content.docInfo.dir.dirPath }}</span>
+              </div>
+            </div>
+            <div
+              class="flieContent"
+              v-for="par in item.highlightFields.content"
+              :key="par"
+              v-html="par"
+            ></div>
+          </div>
+        </div>
+      </div>
+      <div class="allSearch">
+        <div class="title"><span>文件名匹配结果</span></div>
+        <div class="num">共查询到{{ props.allDataTotal }}个相关结果</div>
+        <el-table
+          :data="allData"
+          style="width: 100%; "
+          ref="container"
+          height="584"
+          scrollbar-always-on
+          @scroll="handleScroll"
+          @row-click="clickRow"
+        >
+          <el-table-column type="index" width="70" />
+          <el-table-column label="名称" width="200">
+            <template #default="scope">
+              <div class="flie_name" >
+                <img
+                  class="table_icon"
+                  :src="setIcon(scope.row.fileType)"
+                  alt=""
+                  style=""
+                />
+                <span v-html="scope.row.fileName"></span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="space.spaceName"
+            label="所属空间"
+            width="210"
+          />
+          <el-table-column prop="fileType" label="类型" width="100" />
+          <el-table-column prop="createTime" label="时间" width="200" />
+          <el-table-column prop="fileSize" label="大小" width="100">
+            <template #default="scope">
+              <div>{{ formatFileSize(scope.row.fileSize) }}</div>
+            </template>
+          </el-table-column>
+        </el-table>
       </div>
     </div>
-    <div class="btmBox">
+    <div v-else class="btmBox">
       <div class="upFile">
-        <!-- <img
-          src="@/assets/images/newIndex/upFolderLogo.png"
-          class="upImg"
-          alt=""
-        />
-        <span class="text1">上传你的文件</span> -->
         <el-upload
           class="upload-demo"
           :file-list="fileArr"
@@ -37,7 +132,12 @@
         </el-upload>
         <p class="text2">将文件拖到此处或 <span>选择文件</span></p>
         <div class="line"></div>
-        <img src="@/assets/images/newIndex/scan.png" @click="scannerFile" class="scanImg" alt="" />
+        <img
+          src="@/assets/images/newIndex/scan.png"
+          @click="scannerFile"
+          class="scanImg"
+          alt=""
+        />
         <div class="text3">扫描文件</div>
       </div>
       <div class="recent">
@@ -121,7 +221,7 @@
 </template>
 
 <script setup>
-import { onMounted, ref, toRaw, inject } from "vue";
+import { onMounted, ref, toRaw, inject, watchEffect } from "vue";
 import { getInfo, getInfoByDirId } from "@/api/biz/info";
 import { listRecent, getRecent } from "@/api/biz/recent";
 import { setIcon, canPreviewFile } from "@/utils/index.js";
@@ -155,7 +255,46 @@ const scannerFiles = ref([]); //选择的扫描仪的文件
 const openScanMove = ref(false);
 const openScan = ref(false); //控制扫描文档显示
 const scanFileArr = ref([]); //认领的扫描文件数组
-const emit = defineEmits(["openMaxmin"]);
+const isSearch = ref(props.showSearch);
+const searchText = ref(); // 搜索内容
+const hightData = ref([]); // 高级搜索数据
+const allData = ref([]); // 全域搜索数据
+
+const emit = defineEmits(["openMaxmin", "changeSearch"]);
+const props = defineProps({
+  showSearch: {
+    type: Boolean,
+    default: false,
+  },
+  hightData: {
+    type: Array,
+    default: () => [],
+  },
+  allData: {
+    type: Array,
+    default: () => [],
+  },
+  hightDataTotal: {
+    type: Number,
+    default: 0,
+  },
+  allDataTotal: {
+    type: Number,
+    default: 0,
+  },
+});
+//搜索事件
+const searchBtn = () => {
+  // console.log("searchText", searchText.value);
+  if (!searchText.value) {
+    ElMessage({
+      message: "请输入关键字",
+      type: "error",
+    });
+    return;
+  }
+  emit("changeSearch", true, searchText.value);
+};
 // 获取数据
 const getList = async () => {
   const resN = await listRecent({ isFolder: "N" });
@@ -170,7 +309,7 @@ const getList = async () => {
 // 打开最近文件
 const toFile = async (row) => {
   copyFileType.value = row.fileType;
-  console.log("row", row);
+  // console.log("row", row);
   loadingPreview.value = true;
   const filePreview = canPreviewFile(row.fileType);
   if (filePreview) {
@@ -324,6 +463,50 @@ const closeOpenScanMove = () => {
   openScanMove.value = false;
   // refreshFile();
 };
+function formatFileSize(fileSize) {
+  if (fileSize >= 1024 * 1024 * 1024) {
+    // 大于等于1GB,显示GB
+    return (fileSize / (1024 * 1024 * 1024)).toFixed(2) + "GB";
+  } else if (fileSize >= 1024 * 1024) {
+    // 大于等于1MB,显示MB
+    return (fileSize / (1024 * 1024)).toFixed(2) + "MB";
+  } else if (fileSize >= 1024) {
+    // 大于等于1KB,显示KB
+    return (fileSize / 1024).toFixed(2) + "KB";
+  } else {
+    // 小于1KB,显示字节
+    return fileSize + "B";
+  }
+}
+watchEffect(() => {
+  if (props.showSearch) {
+    isSearch.value = true;
+  } else {
+    isSearch.value = false;
+  }
+});
+watch(
+  () => props.hightData,
+  (newValue, oldValue) => {
+    // console.log('iFrameData 发生改变了', newValue, oldValue);
+    hightData.value = newValue;
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+watch(
+  () => props.allData,
+  (newValue, oldValue) => {
+    // console.log('iFrameData 发生改变了', newValue, oldValue);
+    allData.value = newValue;
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
 onMounted(() => {
   getList();
   getSpaceList();
@@ -340,12 +523,88 @@ onMounted(() => {
   width: 100%;
   height: calc(100vh - 160px);
   display: flex;
+  padding: 0 16px;
   flex-direction: column;
   justify-content: center;
   align-items: center;
 }
+.topBox {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  .upload {
+    width: 448px;
+    height: 64px;
+    border-radius: 86px 86px 86px 86px;
+    background-color: #fff;
+    margin-right: 16px;
+    padding: 0 24px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .right {
+      margin-top: 12px;
+      width: 50px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .line {
+        height: 100%;
+        width: 1px;
+        color: #dbdbdb;
+        line-height: 40px;
+      }
+      .scanImg {
+        width: 32px;
+        height: 32px;
+        cursor: pointer;
+      }
+    }
+    img {
+      width: 40px;
+      height: 40px;
+    }
+    .text1 {
+      margin-left: 8px;
+      font-weight: bold;
+      font-size: 18px;
+      color: #030102;
+    }
+    .text2 {
+      margin-left: 24px;
+      font-weight: 400;
+      font-size: 16px;
+      color: #7c808d;
+      .blueT {
+        font-weight: 500;
+        font-size: 16px;
+        color: #2e8bf6;
+        text-decoration-line: underline;
+      }
+    }
+    .upload-show {
+      width: 100px;
+      height: 40px;
+    }
+    :deep(.el-upload) {
+      width: 350px !important;
+      display: flex !important;
+      align-items: center !important;
+      // height: 40px !important;
+    }
+    :deep(.el-upload-dragger) {
+      padding: 0;
+      border: none;
+      display: flex;
+      justify-content: flex-start !important;
+      align-items: center !important;
+      flex-direction: row !important;
+    }
+  }
+}
 .search {
   width: 1232px;
+  // width: 600px;
   height: 64px;
   background-color: #2e8bf6;
   border-radius: 86px 86px 86px 86px;
@@ -373,6 +632,13 @@ onMounted(() => {
     }
   }
 }
+.showSearch {
+  width: 1424px !important;
+  .search_input {
+    width: 1272px !important;
+  }
+}
+// 主页
 .btmBox {
   margin-top: 16px;
   width: 1232px;
@@ -503,6 +769,113 @@ onMounted(() => {
     }
   }
 }
+// 搜索结果页面
+.searchBtm {
+  width: 100%;
+  height: 699px;
+  margin-top: 16px;
+  display: flex;
+  justify-content: space-between;
+  .highSearch {
+    width: 936px;
+    height: 699px;
+    border-radius: 16px 16px 16px 16px;
+    background: #ffffff;
+    padding: 24px;
+    .title {
+      width: 100%;
+      height: 22px;
+      font-weight: 400;
+      font-size: 14px;
+      line-height: 22px;
+    }
+    .list {
+      margin-top: 12px;
+      height: calc(100% - 48px - 12px);
+      overflow-y: auto;
+      .oneBox {
+        width: 100%;
+        // height: 120px;
+        border-bottom: 1px dashed #c1cce3;
+        padding-bottom: 16px;
+        padding-top: 16px;
+
+        .fileName {
+          font-size: 16px;
+          color: #2e6bc8;
+          text-decoration: underline;
+          font-family: Inter-SemiBold;
+        }
+
+        .flieTime {
+          font-size: 12px;
+          font-weight: 400;
+          color: #7c808d;
+          // line-height: 20px;
+          vertical-align: middle;
+          display: flex;
+          align-items: center;
+          margin: 4px 0;
+
+          span {
+            margin-left: 4px;
+          }
+        }
+
+        .flieContent {
+          width: 100%;
+          font-size: 14px;
+          color: #000000;
+          font-weight: 400;
+          line-height: 22px;
+          display: -webkit-box;
+          -webkit-box-orient: vertical;
+          text-overflow: ellipsis;
+          -webkit-line-clamp: 3; //超过3行显示省略号
+          overflow: hidden;
+        }
+      }
+    }
+  }
+  .allSearch {
+    width: 936px;
+    height: 699px;
+    border-radius: 16px 16px 16px 16px;
+    background: #ffffff;
+    padding: 24px;
+    .title {
+      width: 100%;
+      height: 42px;
+      border-bottom: 1px solid #dbdbdb;
+      span {
+        font-weight: bold;
+        font-size: 18px;
+        color: #030102;
+      }
+    }
+    .num {
+      font-size: 14px;
+      font-weight: 400;
+      color: #555d72;
+      margin-top: 12px;
+    }
+    .table_icon {
+      height: 27px;
+      width: 27px;
+      vertical-align: middle;
+    }
+    //表格文本超出隐藏
+:deep(.flie_name,
+.folder) {
+  /*第一步: 溢出隐藏 */
+  overflow: hidden;
+  /* 第二步:让文本不会换行, 在同一行继续 */
+  white-space: nowrap;
+  /* 第三步:用省略号来代表未显示完的文本 */
+  text-overflow: ellipsis;
+}
+  }
+}
 .checkScan {
   background-color: #f5f7f9;
 }
@@ -518,4 +891,8 @@ onMounted(() => {
   flex-direction: column;
   justify-content: center;
 }
+//关键字背景色
+:deep(em) {
+  background: #fff0ba !important;
+}
 </style>

+ 1 - 1
src/views/login.vue

@@ -238,7 +238,7 @@ async function handleLogin() {
           } else {
             // console.log('redirect',redirect.value);
             // router.push({ path: redirect.value || "/home" });
-            router.push({ path: "/home" });
+            router.push({ path: "/index" });
           }
         })
         .catch(() => {