Browse Source

删除pdf2

songxy 2 tháng trước cách đây
mục cha
commit
b9d9910b55

+ 0 - 172
ais_search_zj/web/src/components/pdf2/PDFReader.vue

@@ -1,172 +0,0 @@
-<template>
-  <div style="width: 100%; height: 100%; position: relative; overflow: hidden">
-    <iframe
-      :src="src"
-      width="100%"
-      height="100%"
-      style="position: relative; border: none"
-      ref="iframeRef"
-      @load="onLoad"
-    ></iframe>
-  </div>
-</template>
-
-<script setup>
-import { message } from 'ant-design-vue';
-import { ref, computed } from 'vue';
-const emits = defineEmits(['match']);
-const iframeRef = ref(null);
-const tryIndex = ref(0);
-const props = defineProps({
-  src: String
-});
-
-// 计算 iframe 的源 URL
-const src = computed(() => {
-  let sanitizedSrc = props.src.replaceAll('&', '%26');
-  return `/lib/pdfjs/web/viewer.html?file=${sanitizedSrc}&t=${new Date().getTime()}`;
-});
-
-// iframe 加载完成后的处理
-const onLoad = () => {
-  setTimeout(() => {
-    const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-    // 确保 PDF.js 的对象已加载
-    if (!doc || !doc.defaultView.PDFViewerApplication) {
-      console.error('PDF.js 未正确加载');
-      return;
-    }
-    const style = doc.createElement('style');
-    style.textContent = `
-   #viewerContainer{
-     overflow-x: hidden;
-   }
-    ::-webkit-scrollbar {
-    /*width: 0;宽度为0隐藏*/
-    width: 6px;
-  }
-  ::-webkit-scrollbar-thumb {
-    border-radius: 6px;
-    height: 60px;
-    background-color: darkgrey;
-  }
-  ::-webkit-scrollbar-track {
-    background: transparent;
-  }
-    `;
-    doc.head.appendChild(style);
-  }, 500);
-};
-
-// 调用 PDF.js 的查找方法
-const searchText = (txt) => {
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  if (!doc || !doc.defaultView.PDFViewerApplication) {
-    console.error('PDF 未正确加载');
-    return;
-  }
-
-  const PDFViewerApplication = doc.defaultView.PDFViewerApplication;
-
-  // 确保文本查找控件可用
-  if (!PDFViewerApplication.findBar || !PDFViewerApplication.findController) {
-    console.error('PDF 查找功能未正确初始化');
-    return;
-  }
-  // 设置搜索关键字并触发搜索
-  // PDFViewerApplication.findBar.open(); // 打开查找工具栏(可选)
-
-  // 确保 findBar 存在
-  const findBar = PDFViewerApplication.findBar;
-  if (!findBar) {
-    // console.error("findBar 未找到");
-    return;
-  }
-  PDFViewerApplication.findBar.open(); // 打开查找工具栏
-  // 隐藏工具条但不关闭查找功能
-  findBar.bar.classList.add('hidden');
-
-  // 填充搜索框并触发搜索
-  const findInput = findBar.findField; // 获取搜索输入框
-  findInput.value = txt;
-
-  // 手动触发输入事件,模拟用户操作
-  const event = new Event('input', { bubbles: true, cancelable: true });
-  findInput.dispatchEvent(event);
-
-  // 监听查找结果
-  const findController = PDFViewerApplication.findController;
-  const checkMatch = setTimeout(() => {
-    // 检查当前匹配数量
-    const matchCount = findController?._matchesCountTotal;
-
-    if (matchCount === 0) {
-      clearTimeout(checkMatch);
-      // 弹框提示
-      if (tryIndex.value == 0) {
-        tryIndex.value = 1;
-        searchText(txt.substring(5));
-      } else {
-        if (txt) {
-          message.info('未匹配到相关内容!');
-        }
-      }
-      return;
-    }
-
-    if (matchCount > 0) {
-      emits('match', matchCount);
-      clearTimeout(checkMatch);
-    }
-  }, 500);
-};
-
-// 移除高亮(可选功能)
-const removeSourceHighlight = () => {
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  if (!doc || !doc.defaultView.PDFViewerApplication) {
-    // console.error("PDF.js 未正确加载");
-    return;
-  }
-
-  const PDFViewerApplication = doc.defaultView.PDFViewerApplication;
-
-  // 清空查找结果
-  PDFViewerApplication.findController.executeCommand('find', {
-    query: ''
-  });
-};
-const findNextBtn = () => {
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  if (!doc || !doc.defaultView.PDFViewerApplication) {
-    console.error('PDF 未正确加载');
-    return;
-  }
-  const PDFViewerApplication = doc.defaultView.PDFViewerApplication;
-  const findBar = PDFViewerApplication.findBar;
-  findBar.findNextButton.click();
-};
-const findPreBtn = () => {
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  if (!doc || !doc.defaultView.PDFViewerApplication) {
-    console.error('PDF 未正确加载');
-    return;
-  }
-  const PDFViewerApplication = doc.defaultView.PDFViewerApplication;
-  const findBar = PDFViewerApplication.findBar;
-  findBar.findPreviousButton.click();
-};
-
-defineExpose({
-  searchText,
-  removeSourceHighlight,
-  findNextBtn,
-  findPreBtn
-});
-</script>
-

+ 0 - 46
ais_search_zj/web/src/components/pdf2/PDFViewer.vue

@@ -1,46 +0,0 @@
-<template>
-<div style="width: 100%; height: 100%; position: relative;">
-  <iframe v-if="type === 'pdf'" :src="src" width="100%" height="100%" style="position: relative;border: medium none;">
-
-  </iframe>
-
-  <div class="close-icon" @click=" emits('close')">
-    <CloseOutlined />
-  </div>
-</div>
-</template>
-<script setup>
-import { CloseOutlined, FullscreenOutlined } from '@ant-design/icons-vue';
-const emits = defineEmits(['close'])
-const props = defineProps({
-  src: String,
-})
-const type = ref('pdf')
-
-watch(props.src, v => {
-  if(v) {
-    if(v.endsWith('.pdf')) {
-      type.value = 'pdf'
-    } else if(v.endsWith('.txt')) {
-      type.value = 'txt'
-    }
-  }
-})
-
-
-const src = computed(() => {
-  return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=`+ new Date().getTime();
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-})
-
-</script>
-
-<style scoped lang="scss">
-.close-icon {
-  position: absolute;
-
-  top: 8px;
-  right: 12px;
-  cursor: pointer;
-}
-</style>

+ 0 - 764
ais_search_zj/web/src/components/pdf2/PDFViewerSearch.vue

@@ -1,764 +0,0 @@
-<template>
-  <div style="width: 100%; height: 100%; position: relative; overflow: hidden">
-    <iframe
-      v-if="type === 'pdf'"
-      :src="src"
-      width="100%"
-      scrolling="no"
-      height="100%"
-      style="position: relative; border: medium none"
-      ref="iframeRef"
-      @load="onLoad"
-    >
-    </iframe>
-    <div class="close-icon" @click="emits('close')" v-if="false">
-      <CloseOutlined />
-    </div>
-  </div>
-</template>
-<script setup>
-import { CloseOutlined } from '@ant-design/icons-vue';
-import { message } from 'ant-design-vue';
-import { nextTick } from 'vue';
-const iframeRef = ref(null);
-const emits = defineEmits(['close', 'outline', 'search', 'load']);
-const searchList = ref([]);
-const pageContent = ref([]);
-const pageText = ref([]);
-const props = defineProps({
-  src: String
-});
-const type = ref('pdf');
-
-watch(
-  () => props.src,
-  (v) => {
-    if (v.endsWith('.pdf')) {
-      type.value = 'pdf';
-    } else if (v.endsWith('.txt')) {
-      type.value = 'txt';
-    }
-  },
-  { immediate: true }
-);
-
-const onLoad = () => {
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-  //待定
-  // var toolbar = doc.getElementsByClassName('toolbar');
-  // if (toolbar && toolbar.length > 0) {
-  // toolbar[0].style.display = 'none';
-  // }
-  setTimeout(() => {
-    const script = doc.createElement('script');
-    script.textContent = `
-  window.addEventListener('message', (event) => {
-  const message = event.data;
-  if (message.action === 'locateElement') {
-    const element= document.getElementById('hightlight-'+message.index);
-    debugger;
-    if(element!=null&&element.offsetParent){
-    setTimeout(() => {
-        element.scrollIntoView({ behavior: 'smooth', block: 'center' })
-    }, 10);
-    }
-  }
-  if (message.action === 'mlLocateElement') {
-
-    const elements= document.getElementsByClassName(message.className);
-    if(elements!=null){
-     setTimeout(() => {
-        elements[message.index].scrollIntoView({ behavior: 'smooth', block: 'center' })
-      }, 50);
-    }
-  }
-  });`;
-    doc.body.appendChild(script);
-    const style = doc.createElement('style');
-    style.textContent = `
-  #outerContainer{
-   overflow: hidden;
-  }
-   #page-container{
-  overflow: hidden;
-   }
-   #viewerContainer{
-     overflow: hidden;
-   }
-  .canvasWrapper {
-  position: relative;
-  /* display: flex;
-  justify-content: center; */
-}
-
-.textLayer {
-  text-align: initial;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  overflow: hidden;
-  opacity: 1;
-  line-height: 1;
-  text-size-adjust: none;
-  forced-color-adjust: none;
-}
-.textLayer span,
-.textLayer br {
-  color: transparent;
-  position: absolute;
-  white-space: pre;
-  cursor: text;
-  transform-origin: 0% 0%;
-}
-.highlight-layer {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  pointer-events: none;
-  opacity: 0.15;
-  overflow: hidden;
-}
-.flash {
-  animation: flashing 0.6s;
-  animation-iteration-count: 2;
-}
-@keyframes flashing {
-  0% {
-    opacity: 0;
-  }
-  100% {
-    opacity: 0.15;
-  }
-}
-.highlight {
-  background-color: #0076fa;
-  position: absolute;
-}
-  `;
-    doc.head.appendChild(style);
-  }, 400);
-  setTimeout(() => {
-    var el = doc.getElementsByClassName('page');
-    // var singleHeight = 1263;
-       var singleHeight = 1000;
-    if (iframeRef.value.height != singleHeight * el.length) {
-      iframeRef.value.height = singleHeight * el.length;
-    }
-    setTimeout(() => {
-      pageText.value = [];
-      pageContent.value = [];
-      //获取每页数据
-      var textDivs = doc.getElementsByClassName('textLayer');
-      if (textDivs) {
-        for (var i = 0; i < textDivs.length; i++) {
-          var item = { page: i + 1, txt: textDivs[i].innerText };
-          var items = [];
-          for (var j = 0; j < textDivs[i].children.length; j++) {
-            var citem = {
-              str: textDivs[i].children[j].innerText,
-              width: textDivs[i].children[j].getBoundingClientRect().width,
-              top: textDivs[i].children[j].getBoundingClientRect().top,
-              height: textDivs[i].children[j].getBoundingClientRect().height
-            };
-            items.push(citem);
-          }
-          pageContent.value.push({ page: i + 1, items: items });
-          pageText.value.push(item);
-        }
-      }
-    }, 1000);
-  }, 1000);
-};
-const src = computed(() => {
-  // return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();
-  return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();
-
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-});
-const scrollTo = (item) => {
-  nextTick(() => {
-    setTimeout(() => {
-      if (item.top) {
-        locateElement(item.cs, item.index, 1);
-      } else {
-        //搜索
-        locateElement(item.cs, item.index);
-        //改变选中颜色 其他黄色
-        searchList.value.forEach((citem, cindex) => {
-          const iframeDocument =
-            iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-          const highlightedSpan = iframeDocument.getElementById('hightlight-' + cindex);
-          if (cindex == item.index) {
-            highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
-              'lightblue',
-              'yellow'
-            );
-          } else {
-            highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
-              'yellow',
-              'lightblue'
-            );
-          }
-        });
-      }
-    }, 10);
-  });
-};
-const locateElement = (className, index, type) => {
-  const message = {
-    action: type ? 'mlLocateElement' : 'locateElement',
-    className: className,
-    index: index
-  };
-  iframeRef.value.contentWindow.postMessage(message, '*');
-};
-const gotoElement = (element) => {
-  nextTick(() => {
-    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
-  });
-};
-const highlightText = (str) => {
-  setTimeout(() => {
-    removeHighlight();
-    heightSingle(str);
-  }, 100);
-};
-const goLocation = (txt, flag) => {
-  removeHighlight();
-  searchList.value = [];
-  heightSingle(txt, flag);
-};
-//ai 问答
-const goSourceLocation = (content, type) => {
-  //获取页面
-  removeSourceHightLight();
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  var pageNumber = 0;
-  if (content.indexOf('-') > -1 && content.indexOf('-') < 3) {
-    content = content.substring(content.indexOf('-') + 1);
-  }
-  var text = content;
-  var ptText = text.replaceAll('\n', '');
-  ptText = ptText.replaceAll(' ', '');
-  console.log(ptText);
-  pageText.value.forEach((item) => {
-    item.txt = item.txt.replaceAll('\n', '');
-    item.txt = item.txt.replaceAll(' ', '');
-    console.log('==页=' + item.txt);
-    console.log('==t=' + ptText);
-    if (ptText.length > 30) {
-      if (item.txt.indexOf(ptText.substring(30, 48)) > -1) {
-        pageNumber = item.page;
-      }
-    } else {
-      if (item.txt.indexOf(ptText.substring(0, 18)) > -1) {
-        pageNumber = item.page;
-      }
-    }
-  });
-  text = text.replaceAll('\n', '');
-  text = text.replaceAll(' ', '');
-  if (text.endsWith('。') || text.endsWith(',') || text.endsWith('、')) {
-    text = text.substring(0, text.length - 1);
-  }
-  if (pageNumber == 0) {
-    message.info('未匹配到相关内容!');
-    return;
-  }
-  //'left: 133.17px; top: 152.408px; font-size: 31.3597px; font-family: sans-serif; transform: scaleX(1.01878);'
-  var arr = doc.getElementsByClassName('textLayer')[pageNumber - 1].getElementsByTagName('span');
-  if (arr) {
-    var hightList = [];
-    var startIndex = 0;
-    var endIndex = 0;
-    var thirdIndex = 0;
-    startIndex = getStartIndex(arr, text, text.length);
-    endIndex = getEndIndex(arr, text, text.length, startIndex);
-    if (startIndex && endIndex && endIndex < startIndex) {
-      endIndex = startIndex + text.length;
-    }
-    var currentPageIndex = 0;
-    var nextArr = [];
-    var thirdArr = [];
-    if (endIndex == undefined) {
-      currentPageIndex = arr.length;
-      if (doc.getElementsByClassName('textLayer')[pageNumber]) {
-        nextArr = doc.getElementsByClassName('textLayer')[pageNumber].getElementsByTagName('span');
-        endIndex = getEndIndex(nextArr, text, text.length, startIndex);
-        if (endIndex == undefined && doc.getElementsByClassName('textLayer')[pageNumber + 1]) {
-          thirdArr = doc
-            .getElementsByClassName('textLayer')
-            [pageNumber + 1].getElementsByTagName('span');
-          thirdIndex = getEndIndex(thirdArr, text, text.length, 0);
-        }
-      } else {
-        endIndex = undefined;
-      }
-    } else {
-      currentPageIndex = endIndex;
-      if (type == 1) {
-        if (endIndex && startIndex && endIndex > startIndex + content.length) {
-          currentPageIndex = startIndex + content.length;
-        }
-        //中间标点匹配问题
-        // var len = startIndex + content.length + 5;
-        // if (startIndex && endIndex && endIndex > (startIndex + content.length + 5)) {
-        //   currentPageIndex = len;
-        // }
-      }
-    }
-    if (!startIndex) {
-      startIndex = 0;
-    }
-    for (var i = startIndex; i < currentPageIndex + 1; i++) {
-      var element = arr[i];
-      if (!element) {
-        break;
-      }
-      var hItem = {};
-      var cssText = element.style.cssText;
-
-      var spanText = element.innerText;
-      var s = spanText.replaceAll(' ', '');
-      var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;
-
-      console.log(spanText);
-      if (
-        text.includes(spanText) ||
-        (s && text.includes(s)) ||
-        (d && text.includes(d)) ||
-        (spanText.substring(2) && text.includes(spanText.substring(2)))
-      ) {
-        var topLabel = cssText.split('top: ')[1].split(';')[0];
-        var leftLabel = cssText.split('left: ')[1].split(';')[0];
-        var currentItems = [];
-        pageContent.value.forEach((item) => {
-          if (item.page == pageNumber) {
-            currentItems = item.items;
-          }
-        });
-        for (var m = 0; m < currentItems.length; m++) {
-          //  citem.str=citem.str.replaceAll(' ','');
-          var citem = currentItems[m];
-          if (citem.str == spanText) {
-            hItem.width = parseFloat(citem.width);
-            hItem.height = parseFloat(citem.height);
-            hItem.text = spanText;
-            hItem.left = leftLabel;
-            hItem.top = topLabel;
-            hightList.push(hItem);
-            if (hightList.length == 1) {
-              gotoElement(element);
-            }
-            if (text.endsWith(citem.str)) {
-              break;
-            }
-          }
-        }
-      }
-    }
-    if (type == 1 && hightList.length == 0) {
-      message.info('未匹配到相关内容!');
-    }
-    // if (type == 2) {
-    var nextHightList = [];
-    //跨页 目前只考虑跨1页
-    if (endIndex != undefined) {
-      for (var i = 0; i < nextArr.length; i++) {
-        var element = nextArr[i];
-        var hItem = {};
-        var cssText = element.style.cssText;
-        var spanText = element.innerText;
-        console.log(spanText);
-        if (text.includes(spanText)) {
-          var topLabel = cssText.split('top: ')[1].split(';')[0];
-          var leftLabel = cssText.split('left: ')[1].split(';')[0];
-          var currentItems = [];
-          pageContent.value.forEach((item) => {
-            if (item.page == pageNumber + 1) {
-              currentItems = item.items;
-            }
-          });
-          for (var l = 0; l < currentItems.length; l++) {
-            var citem = currentItems[l];
-            if (citem.str == spanText) {
-              hItem.width = parseFloat(citem.width);
-              hItem.height = parseFloat(citem.height);
-              hItem.text = spanText;
-              hItem.left = leftLabel;
-              hItem.top = topLabel;
-              nextHightList.push(hItem);
-              if (text.endsWith(citem.str)) {
-                break;
-              }
-            }
-          }
-        }
-        if (text.endsWith(spanText)) {
-          break;
-        }
-      }
-    } else {
-      //跨页 目前只考虑跨2页
-      for (var i = 0; i < nextArr.length; i++) {
-        var element = nextArr[i];
-        var hItem = {};
-        var cssText = element.style.cssText;
-        var spanText = element.innerText;
-        console.log(spanText);
-
-        var topLabel = cssText.split('top: ')[1].split(';')[0];
-        var leftLabel = cssText.split('left: ')[1].split(';')[0];
-        var currentItems = [];
-        pageContent.value.forEach((item) => {
-          if (item.page == pageNumber + 1) {
-            currentItems = item.items;
-          }
-        });
-        for (var l = 0; l < currentItems.length; l++) {
-          var citem = currentItems[l];
-          if (citem.str == spanText) {
-            hItem.width = parseFloat(citem.width);
-            hItem.height = parseFloat(citem.height);
-            hItem.text = spanText;
-            hItem.left = leftLabel;
-            hItem.top = topLabel;
-            nextHightList.push(hItem);
-            if (text.endsWith(citem.str)) {
-              break;
-            }
-          }
-        }
-      }
-      var thirdHightList = [];
-      if (thirdIndex != 0 && thirdIndex != undefined) {
-        for (var z = 0; z < thirdIndex + 1; z++) {
-          var element = thirdArr[z];
-          var hItem = {};
-          var cssText = element.style.cssText;
-          var spanText = element.innerText;
-          console.log(spanText);
-          if (text.includes(spanText)) {
-            var topLabel = cssText.split('top: ')[1].split(';')[0];
-            var leftLabel = cssText.split('left: ')[1].split(';')[0];
-            var currentItems = [];
-            pageContent.value.forEach((item) => {
-              if (item.page == pageNumber + 2) {
-                currentItems = item.items;
-              }
-            });
-            for (var l = 0; l < currentItems.length; l++) {
-              var citem = currentItems[l];
-              if (citem.str == spanText) {
-                hItem.width = parseFloat(citem.width);
-                hItem.height = parseFloat(citem.height);
-                hItem.text = spanText;
-                hItem.left = leftLabel;
-                hItem.top = topLabel;
-                thirdHightList.push(hItem);
-                if (text.endsWith(citem.str)) {
-                  break;
-                }
-              }
-            }
-          }
-          if (text.endsWith(spanText)) {
-            break;
-          }
-        }
-      }
-    }
-
-    //渲染
-    var canvas = doc.getElementsByClassName(`page`)[pageNumber - 1];
-    const hightDiv = document.createElement('div');
-    hightDiv.className = 'highlight-layer flash';
-    hightList.forEach((it) => {
-      const hDiv = document.createElement('div');
-      hDiv.className = 'highlight';
-      // 设置内联样式
-      hDiv.style.width = it.width + 'px';
-      hDiv.style.height = it.height * 1.4 + 'px';
-      hDiv.style.left = it.left;
-      hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
-      hightDiv.appendChild(hDiv);
-    });
-    canvas.appendChild(hightDiv);
-    if (nextHightList && nextHightList.length > 0) {
-      //渲染
-      var nextCanvas = doc.getElementsByClassName(`page`)[pageNumber];
-      const hightDiv = document.createElement('div');
-      hightDiv.className = 'highlight-layer flash';
-      nextHightList.forEach((it) => {
-        const hDiv = document.createElement('div');
-        hDiv.className = 'highlight';
-        // 设置内联样式
-        hDiv.style.width = it.width + 'px';
-        hDiv.style.height = it.height * 1.4 + 'px';
-        hDiv.style.left = it.left;
-        hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
-        hightDiv.appendChild(hDiv);
-      });
-      nextCanvas.appendChild(hightDiv);
-    }
-    if (thirdHightList && thirdHightList.length > 0) {
-      //渲染
-      var thirdCanvas = doc.getElementsByClassName(`page`)[pageNumber + 1];
-      const hightDiv = document.createElement('div');
-      hightDiv.className = 'highlight-layer flash';
-      thirdHightList.forEach((it) => {
-        const hDiv = document.createElement('div');
-        hDiv.className = 'highlight';
-        // 设置内联样式
-        hDiv.style.width = it.width + 'px';
-        hDiv.style.height = it.height * 1.4 + 'px';
-        hDiv.style.left = it.left;
-        hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
-        hightDiv.appendChild(hDiv);
-      });
-      thirdCanvas.appendChild(hightDiv);
-    }
-    // }
-  }
-};
-//交集
-function commonContent(str1, str2) {
-  let result = '';
-  for (let i = 0; i < str1.length; i++) {
-    if (str2.includes(str1[i])) {
-      result += str1[i];
-    }
-  }
-  return result;
-}
-const getStartIndex = (arr, text, total) => {
-  var indexs = [];
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    console.log('===' + spanText);
-
-    if (
-      (spanText && text.startsWith(spanText)) ||
-      (spanText && spanText.substring(2) && spanText && text.startsWith(spanText.substring(2))) ||
-      (spanText.indexOf('。') > -1 &&
-        spanText.split('。')[1] &&
-        text.startsWith(spanText.split('。')[1])) ||
-      (spanText.endsWith('。') &&
-        spanText.split('。')[0] &&
-        text.startsWith(spanText.split('。')[0]))
-    ) {
-      indexs.push(i);
-      //   return i;
-    }
-  }
-  if (indexs.length == 0) {
-    return 0;
-  } else if (indexs.length == 2) {
-    console.log(JSON.stringify(indexs));
-    return indexs[0] == 0 ? indexs[1] : indexs[0];
-  } else {
-    return indexs[0];
-  }
-  //todo 有问题
-  // if (count == arr.length) {
-  //   start.value = start.value + 1;
-  //   text = text.substring(start.value, total);
-  //   getStartIndex(arr, text, total);
-  // }
-};
-const getEndIndex = (arr, text, total, startIndex) => {
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    var e = '';
-    if (spanText.endsWith('。')) {
-      spanText = spanText.substring(0, spanText.lastIndexOf('。'));
-    }
-    if (spanText.indexOf('。') > -1) {
-      e = spanText.substring(0, spanText.lastIndexOf('。'));
-    }
-    console.log('===' + spanText);
-    if (
-      (spanText && text.endsWith(spanText) && spanText.length > 0) ||
-      (spanText && spanText.indexOf(text) > -1) ||
-      (e && text.endsWith(e))
-    ) {
-      return i;
-    }
-  }
-};
-const heightSingle = (str, flag) => {
-  const iframeDocument = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  const searchText = str;
-  var highlightColor = 'lightblue';
-
-  // 使用DOM操作在iframe中搜索并高亮文本
-  const textNodes = iframeDocument.evaluate(
-    ".//text()[contains(., '" + searchText + "')]",
-    iframeDocument,
-    null,
-    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
-    null
-  );
-  var firstFlag = false;
-  for (let i = 0, length = textNodes.snapshotLength; i < length; i++) {
-    const content = textNodes.snapshotItem(i);
-    const textNode = content.textContent;
-
-    const regex = new RegExp(searchText, 'gi');
-    var newContent = textNode.replace(regex, (match) => {
-      if (match == searchText) {
-        if (!firstFlag) {
-          firstFlag = true;
-          highlightColor = 'yellow';
-        } else {
-          highlightColor = 'lightblue';
-        }
-        return `<span  id='hightlight-${searchList.value.length}' style="background-color: ${highlightColor};color: #333;margin-top:-3px;border-radius: 3px;">${match}</span>`;
-      }
-    });
-    if (content.parentNode) {
-      var n = content.parentNode;
-      console.log('====' + n.offsetTop);
-      newContent = '<' + newContent.split('<')[1] + '</span>';
-      var h = content.parentNode.innerHTML;
-      if (!flag) {
-        content.parentNode.innerHTML = h.replace(searchText, newContent);
-      }
-      if (n) {
-        searchList.value.push({
-          cs: n.parentNode.className,
-          index: searchList.value.length,
-          n: n.parentNode
-        });
-        if (searchList.value.length == 1) {
-          // if (!flag) {
-          //   locateElement(searchList.value[0].cs, 0);
-          // }
-          gotoElement(n);
-        }
-        //大纲只定位一次
-        if (flag) {
-          break;
-        }
-      }
-    }
-    if (!flag) {
-      if (i == textNodes.snapshotLength - 1) {
-        //查询结束
-        emits('search', searchList.value);
-      }
-    }
-  }
-};
-const removeSourceHightLight = () => {
-  //获取页面 ai定位移除
-  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-
-  const arr = doc.getElementsByClassName('highlight-layer');
-  const l = arr.length;
-  for (let i = l - 1; i >= 0; i--) {
-    if (arr[i] != null) {
-      arr[i].parentNode.removeChild(arr[i]);
-    }
-  }
-};
-const removeHighlight = () => {
-  removeSourceHightLight();
-  if (searchList.value) {
-    searchList.value.forEach((item, index) => {
-      const iframeDocument =
-        iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
-      const highlightedSpan = iframeDocument.getElementById('hightlight-' + index);
-      if (highlightedSpan != null) {
-        const span = highlightedSpan;
-        console.log(span.innerHTML);
-        setTimeout(() => {
-          span.parentNode.replaceChild(document.createTextNode(span.textContent), span);
-        }, 10);
-      }
-    });
-  }
-  searchList.value = [];
-  emits('search', searchList.value);
-};
-defineExpose({ highlightText, removeHighlight, scrollTo, goLocation, goSourceLocation, location });
-</script>
-
-<style scoped lang="scss">
-.close-icon {
-  position: absolute;
-
-  top: 8px;
-  right: 12px;
-  cursor: pointer;
-}
-</style>
-<style>
-/* 不能用scoped,因为动态创建的元素不会被编译带上hash */
-/* 不加上这些css修饰,元素会错位,样式来自vue-pdf-embed这个库 */
-.canvasWrapper {
-  position: relative;
-  /* display: flex;
-  justify-content: center; */
-}
-.page {
-  position: relative;
-  box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.08);
-  margin: 30px auto;
-}
-.textLayer {
-  text-align: initial;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  overflow: hidden;
-  opacity: 0.2;
-  line-height: 1;
-  text-size-adjust: none;
-  forced-color-adjust: none;
-}
-.textLayer span,
-.textLayer br {
-  color: transparent;
-  position: absolute;
-  white-space: pre;
-  cursor: text;
-  transform-origin: 0% 0%;
-}
-.highlight-layer {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  pointer-events: none;
-  opacity: 0.15;
-  overflow: hidden;
-}
-.flash {
-  animation: flashing 0.6s;
-  animation-iteration-count: 2;
-}
-@keyframes flashing {
-  0% {
-    opacity: 0;
-  }
-  100% {
-    opacity: 0.15;
-  }
-}
-.highlight {
-  background-color: #0076fa;
-  position: absolute;
-}
-</style>

+ 0 - 406
ais_search_zj/web/src/components/pdf2/PdfCanvas.vue

@@ -1,406 +0,0 @@
-<template>
-  <div class="pdf-container">
-    <div class="header">
-      <div class="title">{{ title }}</div>
-      <div class="full-screen" @click="fullScreen">
-        <FullscreenOutlined color="red" />
-      </div>
-      <div class="close-icon" @click="emits('close')">
-        <CloseOutlined />
-      </div>
-    </div>
-    <div ref="pdfRef" class="pdf-viewer"></div>
-  </div>
-</template>
-<script setup>
-import { CloseOutlined, FullscreenOutlined } from '@ant-design/icons-vue';
-import { ref, watch } from 'vue';
-import PdfjsWorker from 'pdfjs-dist/build/pdf.worker.js?worker';
-const emits = defineEmits(['close']);
-const props = defineProps({
-  src: { type: String, required: true },
-  content: { type: String, required: true },
-  num: { type: Number, required: false }
-});
-const pdfRef = ref(null);
-const height = ref(0);
-const start = ref(0);
-const pageContent = ref([]);
-const pageText = ref([]);
-// 侦听props的src改变,则立即切换渲染pdf
-watch(
-  () => props.src,
-  () => {
-    setTimeout(() => init(), 1);
-  },
-  { immediate: true }
-);
-const title = computed(() => {
-  ;
-  return decodeURI(decodeURI(props.src))
-    .replace(window.AppGlobalConfig.knowledgeDocUrlProxy, '')
-    .replace('+', ' ');
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-});
-// 渲染pdf
-async function init() {
-  var pdfDom = document.getElementsByClassName('pdf-viewer')[0];
-  while (pdfDom.firstChild) {
-    pdfDom.removeChild(pdfDom.firstChild);
-  }
-  // 异步加载pdf.js
-  const PDFJS = await import('pdfjs-dist/build/pdf.js');
-  if (typeof window !== 'undefined' && 'Worker' in window) {
-    PDFJS.GlobalWorkerOptions.workerPort = new PdfjsWorker();
-  }
-  // 加载文档
-  let loadingTask = PDFJS.getDocument({ url: props.src });
-  loadingTask.__PDFDocumentLoadingTask = true;
-  pageContent.value = [];
-  const pdf = await loadingTask.promise; // 使用await等待加载完毕
-  // 循环渲染每一页
-  for (let i = 1; i <= pdf.numPages; i++) {
-    const page = await pdf.getPage(i);
-    await renderPage(page, PDFJS, i);
-  }
-  console.log('pdf页面全部渲染完毕', pdf.numPages, pdf);
-  pageText.value = [];
-  //获取每页数据
-  var textDivs = document.getElementsByClassName('textLayer');
-  if (textDivs) {
-    for (var i = 0; i < textDivs.length; i++) {
-      var item = { page: i + 1, txt: textDivs[i].innerText };
-      pageText.value.push(item);
-    }
-  }
-  if (props.content) {
-    goLocation();
-  }
-}
-
-const fullScreen = () => {
-  const pdfSrc = props.src.replace(window.AppGlobalConfig.knowledgeDocUrlProxy, window.AppGlobalConfig.knowledgeDocUrlProxy2)
-  window.open(`/aisearch/lib/pdfjs/web/viewer.html?file=${decodeURI(pdfSrc)}&t=` + new Date().getTime(), '_blank')
-}
-
-
-const goLocation = () => {
-  //获取页面
-  var pageNumber = 0;
-  var text = props.content;
-
-  var ptText = text.replaceAll('\n', '');
-  ptText = ptText.replaceAll(' ', '');
-  console.log(ptText);
-  pageText.value.forEach((item) => {
-    item.txt = item.txt.replaceAll('\n', '');
-    item.txt = item.txt.replaceAll(' ', '');
-    console.log(item.txt);
-    if (item.txt.indexOf(ptText.substring(0, 18)) > -1) {
-      pageNumber = item.page;
-    }
-  });
-  text = text.replaceAll('\n', '');
-  text = text.replaceAll(' ', '');
-  if (text.endsWith('。') || text.endsWith(',') || text.endsWith('、')) {
-    text = text.substring(0, text.length - 1);
-  }
-  //'left: 133.17px; top: 152.408px; font-size: 31.3597px; font-family: sans-serif; transform: scaleX(1.01878);'
-  var arr = document
-    .getElementsByClassName('textLayer')
-    [pageNumber - 1].getElementsByTagName('span');
-  if (arr) {
-    var hightList = [];
-    var startIndex = 0;
-    var endIndex = 0;
-    startIndex = getStartIndex(arr, text, text.length);
-    endIndex = getEndIndex(arr, text, text.length, startIndex);
-    var currentPageIndex = 0;
-    var nextArr = [];
-    if (endIndex == undefined) {
-      currentPageIndex = arr.length;
-      nextArr = document
-        .getElementsByClassName('textLayer')
-        [pageNumber].getElementsByTagName('span');
-      endIndex = getEndIndex(nextArr, text, text.length, startIndex);
-    } else {
-      currentPageIndex = endIndex;
-    }
-    for (var i = startIndex; i < currentPageIndex; i++) {
-      var element = arr[i];
-      var hItem = {};
-      var cssText = element.style.cssText;
-      var spanText = element.innerText;
-      console.log(spanText);
-      if (text.includes(spanText)) {
-        var topLabel = cssText.split('top: ')[1].split(';')[0];
-        topLabel = topLabel.substring(0, topLabel.length - 2);
-        var currentItems = [];
-        pageContent.value.forEach((item) => {
-          if (item.page == pageNumber) {
-            currentItems = item.items;
-          }
-        });
-        for (var m = 0; m < currentItems.length; m++) {
-          var citem = currentItems[m];
-          if (citem.str == spanText) {
-            hItem.width = parseFloat(citem.width);
-            hItem.height = parseFloat(citem.height);
-            hItem.text = spanText;
-            hItem.left = parseFloat(cssText.substring(6, cssText.indexOf('px')));
-            hItem.top = parseFloat(topLabel);
-            hightList.push(hItem);
-            if (text.endsWith(citem.str)) {
-              break;
-            }
-          }
-        }
-      }
-    }
-    var nextHightList = [];
-    //跨页 目前只考虑跨1页
-    if (endIndex != undefined) {
-      for (var i = 0; i < nextArr.length; i++) {
-        var element = nextArr[i];
-        var hItem = {};
-        var cssText = element.style.cssText;
-        var spanText = element.innerText;
-        console.log(spanText);
-        if (text.includes(spanText)) {
-          var topLabel = cssText.split('top: ')[1].split(';')[0];
-          topLabel = topLabel.substring(0, topLabel.length - 2);
-          var currentItems = [];
-          pageContent.value.forEach((item) => {
-            if (item.page == pageNumber + 1) {
-              currentItems = item.items;
-            }
-          });
-          for (var l = 0; l < currentItems.length; l++) {
-            var citem = currentItems[l];
-            if (citem.str == spanText) {
-              hItem.width = parseFloat(citem.width);
-              hItem.height = parseFloat(citem.height);
-              hItem.text = spanText;
-              hItem.left = parseFloat(cssText.substring(6, cssText.indexOf('px')));
-              hItem.top = parseFloat(topLabel);
-              nextHightList.push(hItem);
-              if (text.endsWith(citem.str)) {
-                break;
-              }
-            }
-          }
-        }
-        if (text.endsWith(spanText)) {
-          break;
-        }
-      }
-    }
-    //定位
-    pdfRef.value.scrollTop = height.value * (pageNumber - 1) + hightList[0]['top'];
-    //渲染
-    var canvas = document.getElementsByClassName(`page`)[pageNumber - 1];
-    const hightDiv = document.createElement('div');
-    hightDiv.className = 'highlight-layer flash';
-    hightList.forEach((it) => {
-      const hDiv = document.createElement('div');
-      hDiv.className = 'highlight';
-      // 设置内联样式
-      hDiv.style.width = it.width * 2 + 'px';
-      hDiv.style.height = it.height * 2 + 'px';
-      hDiv.style.left = it.left + 'px';
-      hDiv.style.top = it.top + 'px';
-      hightDiv.appendChild(hDiv);
-    });
-    canvas.appendChild(hightDiv);
-    if (nextHightList && nextHightList.length > 0) {
-      //渲染
-      var nextCanvas = document.getElementsByClassName(`page`)[pageNumber];
-      const hightDiv = document.createElement('div');
-      hightDiv.className = 'highlight-layer flash';
-      nextHightList.forEach((it) => {
-        const hDiv = document.createElement('div');
-        hDiv.className = 'highlight';
-        // 设置内联样式
-        hDiv.style.width = it.width * 2 + 'px';
-        hDiv.style.height = it.height * 2 + 'px';
-        hDiv.style.left = it.left + 'px';
-        hDiv.style.top = it.top + 'px';
-        hightDiv.appendChild(hDiv);
-      });
-      nextCanvas.appendChild(hightDiv);
-    }
-  }
-};
-const getStartIndex = (arr, text, total) => {
-  var count = 0;
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    console.log('===' + spanText);
-    if (text.startsWith(spanText)) {
-      return i;
-    } else {
-      count++;
-    }
-  }
-  if (count == arr.length) {
-    start.value = start.value + 1;
-    text = text.substring(start.value, total);
-    getStartIndex(arr, text, total);
-  }
-};
-const getEndIndex = (arr, text, total, startIndex) => {
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    console.log('===' + spanText);
-    if (text.endsWith(spanText) && spanText.length > 1) {
-      return i;
-    }
-  }
-};
-const renderPage = (page, PDFJS, num) => {
-  return new Promise(async (resolve, reject) => {
-    // 先渲染图片
-    let pixelRatio = 1;
-    const viewport = page.getViewport({ scale: 2 });
-    const canvas = document.createElement('canvas');
-    const context = canvas.getContext('2d');
-    canvas.id = `page-${num}`;
-    canvas.height = viewport.height * pixelRatio;
-    console.log('==height', canvas.height);
-    height.value = canvas.height;
-    canvas.width = viewport.width * pixelRatio;
-    const renderContext = {
-      canvasContext: context,
-      viewport: viewport,
-      transform: [pixelRatio, 0, 0, pixelRatio, 0, 0]
-    };
-    await page.render(renderContext).promise;
-    // 再渲染文字
-    const textContent = await page.getTextContent();
-    pageContent.value.push({ page: num, items: textContent.items });
-    const textLayer = document.createElement('div');
-    PDFJS.renderTextLayer({
-      textContent: textContent,
-      container: textLayer,
-      viewport: viewport,
-      transform: [pixelRatio, 0, 0, pixelRatio, 0, 0],
-      textDivs: []
-    });
-    textLayer.className = 'textLayer';
-    // 将文字覆盖在图片上
-    const canvasWrapper = document.createElement('div');
-    canvasWrapper.className = 'canvasWrapper';
-    const pageDiv = document.createElement('div');
-    pageDiv.className = 'page';
-    canvasWrapper.appendChild(canvas);
-    pageDiv.appendChild(canvasWrapper);
-    pageDiv.appendChild(textLayer);
-    pdfRef.value.appendChild(pageDiv);
-    resolve();
-  });
-};
-</script>
-<style scoped lang="scss">
-.pdf-container {
-  width: 100%;
-  height: 100%;
-  position: relative;
-  .header {
-    height: 40px;
-    position: relative;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    border-bottom: 1px solid #eee;
-
-    .title {
-      font-size: 18px;
-      font-weight: bolder;
-    }
-    .close-icon {
-      position: absolute;
-      top: 10px;
-      right: 21px;
-      cursor: pointer;
-    }
-
-    .full-screen {
-      position: absolute;
-      top: 10px;
-      right: 51px;
-      cursor: pointer;
-      color: #0C6FF7;
-    }
-  }
-}
-.pdf-viewer {
-  width: 100%;
-  height: calc(100% - 40px);
-  position: relative;
-  border: 0px solid #ccc;
-  overflow-y: auto;
-}
-</style>
-<style>
-/* 不能用scoped,因为动态创建的元素不会被编译带上hash */
-/* 不加上这些css修饰,元素会错位,样式来自vue-pdf-embed这个库 */
-.canvasWrapper {
-  position: relative;
-  /* display: flex;
-  justify-content: center; */
-}
-.page {
-  position: relative;
-  box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.08);
-  margin: 30px auto;
-}
-.textLayer {
-  text-align: initial;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  overflow: hidden;
-  opacity: 0.2;
-  line-height: 1;
-  text-size-adjust: none;
-  forced-color-adjust: none;
-}
-.textLayer span,
-.textLayer br {
-  color: transparent;
-  position: absolute;
-  white-space: pre;
-  cursor: text;
-  transform-origin: 0% 0%;
-}
-.highlight-layer {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  pointer-events: none;
-  opacity: 0.15;
-  overflow: hidden;
-}
-.flash {
-  animation: flashing 0.6s;
-  animation-iteration-count: 2;
-}
-@keyframes flashing {
-  0% {
-    opacity: 0;
-  }
-  100% {
-    opacity: 0.15;
-  }
-}
-.highlight {
-  background-color: #0076fa;
-  position: absolute;
-}
-</style>

+ 0 - 153
ais_search_zj/web/src/components/pdf2/TxtViewer.vue

@@ -1,153 +0,0 @@
-
-
-<template>
-  <div class="header">
-    <div class="title" :title="title">{{ title }}</div>
-    <div class="full-screen" @click="fullScreen">
-      <FullscreenOutlined color="red" />
-    </div>
-    <div class="close-icon" @click="emits('close')">
-      <CloseOutlined />
-    </div>
-  </div>
-  <div :text-src="src" class="text">
-    <p style="white-space: pre-wrap" v-html="content"></p>
-  </div>
-</template>
-<script setup>
-import axios from 'axios';
-import { CloseOutlined, FullscreenOutlined } from '@ant-design/icons-vue';
-const emits = defineEmits(['close']);
-
-const props = defineProps({
-  src: String,
-  txt: String
-});
-
-const content = ref('');
-
-watch(props.src, (v) => {
-  if (v) {
-    getContent(v);
-  }
-});
-
-const src = computed(() => {
-  getContent(props.src);
-  return `${props.src}`;
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-});
-
-const fullScreen = () => {
-  const pdfSrc = props.src.replace(window.AppGlobalConfig.knowledgeDocUrlProxy, window.AppGlobalConfig.knowledgeDocUrlProxy2)
-  window.open(`/aisearch/#/viewer/txt?file=${encodeURIComponent(pdfSrc)}`, '_blank')
-}
-
-const title = computed(() => {
-  return decodeURI(decodeURI(props.src))
-    .replace(window.AppGlobalConfig.knowledgeDocUrlProxy, '')
-    .replace('+', ' ');
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-});
-//高亮+定位
-const goLocation = () => {
-  var text = props.txt.replaceAll('\n\n', '\r\n');
-  text = text.replaceAll('\n', '\r\n');
-  text = text.replaceAll('\r\r', '\r');
-  if (text.startsWith(' \r\n')) {
-    text = text.replace(' \r\n', '');
-  }
-  if (text.endsWith('\r\n')) {
-    text = text.substring(0, text.length - 2);
-  }
-  if (text && content.value.indexOf(text) > -1) {
-    var pre = content.value.substring(0, content.value.indexOf(text));
-    var end = content.value.substring(
-      content.value.indexOf(text) + text.length,
-      content.value.length
-    );
-    var middle = "<span class='heightlight flash' id='hightlight'>" + text + '</span>';
-    content.value = pre + middle + end;
-    setTimeout(() => {
-       var hightlightDiv = document.getElementById('hightlight');
-       hightlightDiv.scrollIntoView({ behavior: "smooth" } );
-    }, 1500);
-  }
-};
-const getContent = (_src) => {
-  content.value = '';
-  axios
-    .get(_src, {
-      responseType: 'text'
-    })
-    .then((res) => {
-      content.value = res.data;
-      if (props.txt) {
-        goLocation();
-      }
-    });
-};
-</script>
-<style scoped lang="scss">
-.header {
-  height: 40px;
-  position: relative;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  border-bottom: 1px solid #eee;
-
-  .title {
-    margin-left: 20px;
-    font-size: 18px;
-    font-weight: bolder;
-    max-width: 90%;
-    white-space: nowrap;
-    /*超出的空白区域不换行*/
-    overflow: hidden;
-    /*超出隐藏*/
-    text-overflow: ellipsis;
-  }
-  .close-icon {
-    position: absolute;
-    top: 10px;
-    right: 21px;
-    cursor: pointer;
-  }
-
-  .full-screen {
-    position: absolute;
-    top: 10px;
-    right: 51px;
-    cursor: pointer;
-    color: #0C6FF7;
-  }
-}
-.text {
-  width: calc(100% - 30px);
-  margin-left: 20px;
-  overflow-y: auto;
-  padding: 20px;
-  max-height: calc(100vh - 310px);
-  border: 1px solid #ccc;
-}
-</style>
-<style >
-.heightlight {
-  background-color: #0076fa;
-  color: white;
-  line-height: 30px;
-}
-.flash {
-  animation: flashing 0.6s;
-  animation-iteration-count: 2;
-}
-@keyframes flashing {
-  0% {
-    opacity: 0.8;
-  }
-  100% {
-    opacity: 0.15;
-  }
-}
-</style>

+ 0 - 500
ais_search_zj/web/src/components/pdf2/WordViewer.vue

@@ -1,500 +0,0 @@
-<template>
-  <div class="word-container">
-    <!-- <button @click="ints">点点就会高亮</button> -->
-
-      <div class="header">
-      <div class="title">{{ title }}</div>
-        <div class="full-screen" @click="fullScreen">
-          <FullscreenOutlined color="red" />
-        </div>
-      <div class="close-icon" @click="emits('close')">
-        <CloseOutlined />
-      </div>
-    </div>
-    <div ref="word" id="fileShow" class="words"></div>
-    <div class="spin" v-if="loading">
-      <a-spin></a-spin>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import axios from 'axios';
-import { CloseOutlined, FullscreenOutlined } from '@ant-design/icons-vue';
-import { defineProps, ref, onMounted, watch, toRefs } from 'vue';
-import { renderAsync } from 'docx-preview'; //要安装 npm install docx-preview
-import JSZip from 'jszip'; //要安装 npm install jszip
-import { number } from 'echarts';
-window.JSZip = JSZip;
-const emits = defineEmits(['close']);
-const loading = ref(true);
-const props = defineProps({
-  src: { type: String, required: true },
-  content: { type: String, required: true },
-  num: { type: Number, required: false },
-  index: { type: Number, required: true }
-});
-const pageContent = ref([]);
-const pageText = ref([]);
-watch(
-  () => props.index,
-  () => {
-    setTimeout(() => inti(), 1);
-  },
-  { immediate: true }
-);
-
-watch(
-  () => props.src,
-  () => {
-    setTimeout(() => inti(), 1);
-  },
-  { immediate: true }
-);
-
-watch(
-  () => props.num,
-  () => {
-    setTimeout(() => inti(), 1);
-  },
-  { immediate: true }
-);
-const title = computed(() => {
-  return decodeURI(decodeURI(props.src))
-    .replace(window.AppGlobalConfig.knowledgeDocUrlProxy, '')
-    .replace('+', ' ');
-  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
-});
-// word预览
-const inti = () => {
-  axios
-    .get(props.src, { responseType: 'blob' })
-    .then((response) => {
-      const url = window.URL.createObjectURL(new Blob([response.data]));
-      const previewContainer = document.getElementById('fileShow');
-      renderAsync(new Blob([response.data]), previewContainer); //渲染
-      setTimeout(() => {
-        pageText.value = [];
-        pageContent.value = [];
-        //获取每页数据
-        var textDivs = document.getElementsByClassName('docx');
-        if (textDivs) {
-          for (var i = 0; i < textDivs.length; i++) {
-            var item = { page: i + 1, txt: textDivs[i].innerText };
-            var items = [];
-            for (var j = 0; j < textDivs[i].children.length; j++) {
-              var citem = {
-                str: textDivs[i].children[j].innerText,
-                width: textDivs[i].children[j].getBoundingClientRect().width,
-                top: textDivs[i].children[j].getBoundingClientRect().top,
-                height: textDivs[i].children[j].getBoundingClientRect().height
-              };
-              items.push(citem);
-            }
-            pageContent.value.push({ page: i + 1, items: items });
-            pageText.value.push(item);
-          }
-          loading.value = false;
-          setTimeout(() => {
-            if (props.content) {
-              goSourceLocation(props.content);
-              //   ints();
-            }
-          }, 100);
-        }
-      }, 2000);
-    })
-    .catch((error) => {
-      console.error(error);
-    });
-};
-//
-const searchNum = ref(0);
-const indexNum = ref(0);
-const ints = () => {
-  // 多个关键词高亮,循环调用高亮方法
-  let data = [
-    '图1-1国土部门的土地利用规划体系资料来源:张占录.土地利用规划学[M].北京:中国人民大学出版社,2006.(一)土地利用总体规划土地利用总体规划是指人民政府依照法律规定在一定的规划区域内,根据国民经济和第一章导论9',
-    '划定城市增长边界。明确生态环境、土地、水'
-  ];
-  goSourceLocation(data[0]);
-};
-//ai 问答
-const goSourceLocation = (content) => {
-  //获取页面
-  removeSourceHightLight();
-  var list = [];
-  var pageNumber = 0;
-  if (content.indexOf('-') > -1 && content.indexOf('-') < 3) {
-    content = content.substring(content.indexOf('-') + 1);
-  }
-  if (content.startsWith(' ')) {
-    content = content.substring(1);
-  }
-  //   if (content.endsWith('\n\n') && content.replaceAll('\n\n', '').lastIndexOf('\n') != -1) {
-  //     content = content
-  //       .replaceAll('\n\n', '')
-  //       .substring(0, content.replaceAll('\n\n', '').lastIndexOf('\n'));
-  //   }
-  var text = content;
-
-  var ptText = text.replaceAll('\n', '');
-  ptText = ptText.replaceAll(' ', '');
-  console.log(ptText);
-  for (var i = 0; i < pageText.value.length; i++) {
-    var item = pageText.value[i];
-    item.txt = item.txt.replaceAll('\n', '');
-    item.txt = item.txt.replaceAll(' ', '');
-    console.log('==页=' + item.txt);
-    console.log('==t=' + ptText);
-    if (ptText.length > 30) {
-      if (item.txt.indexOf(ptText.substring(30, 48)) > -1) {
-        pageNumber = item.page;
-        break;
-      }
-    } else {
-      if (item.txt.indexOf(ptText.substring(0, 18)) > -1) {
-        pageNumber = item.page;
-        break;
-      }
-    }
-  }
-  text = text.replaceAll('\n', '');
-  text = text.replaceAll(' ', '');
-  if (text.endsWith('。') || text.endsWith(',') || text.endsWith('、')) {
-    text = text.substring(0, text.length - 1);
-  }
-  //'left: 133.17px; top: 152.408px; font-size: 31.3597px; font-family: sans-serif; transform: scaleX(1.01878);'
-  var arr = document.getElementsByClassName('docx')[pageNumber - 1].getElementsByTagName('span');
-  if (arr) {
-    var hightList = [];
-    var startIndex = 0;
-    var endIndex = 0;
-    var thirdIndex = 0;
-    startIndex = getStartIndex(arr, text, text.length);
-    endIndex = getEndIndex(arr, text, text.length, startIndex) + 1;
-    if (endIndex + '' == 'NaN') {
-      endIndex = undefined;
-    }
-    if (startIndex && endIndex && endIndex < startIndex) {
-      endIndex = startIndex + text.length;
-    }
-    var currentPageIndex = 0;
-    var nextArr = [];
-    var thirdArr = [];
-    if (endIndex == undefined) {
-      currentPageIndex = arr.length;
-      if (document.getElementsByClassName('docx')[pageNumber]) {
-        nextArr = document.getElementsByClassName('docx')[pageNumber].getElementsByTagName('span');
-        endIndex = getEndIndex(nextArr, text, text.length, startIndex);
-        if (endIndex == undefined && document.getElementsByClassName('docx')[pageNumber + 1]) {
-          thirdArr = document
-            .getElementsByClassName('docx')
-            [pageNumber + 1].getElementsByTagName('span');
-          thirdIndex = getEndIndex(thirdArr, text, text.length, 0);
-        }
-      } else {
-        endIndex = undefined;
-      }
-    } else {
-      currentPageIndex = endIndex;
-      if (endIndex && startIndex && endIndex > startIndex + content.length) {
-        currentPageIndex = startIndex + content.length;
-      }
-    }
-    if (!startIndex) {
-      startIndex = 0;
-    }
-    for (var i = startIndex; i < currentPageIndex + 1; i++) {
-      var element = arr[i];
-      if (!element) {
-        break;
-      }
-      var hItem = {};
-      var cssText = element.style.cssText;
-
-      var spanText = element.innerText;
-      if (!spanText) {
-        continue;
-      }
-      var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;
-      var s = spanText.replaceAll(' ', '');
-      console.log(spanText);
-      if (
-        text.includes(spanText) ||
-        (s && text.includes(s)) ||
-        (d && text.includes(d)) ||
-        spanText.includes(text) ||
-        (spanText.substring(2) && text.includes(spanText.substring(2)))
-      ) {
-        element.classList.add('searchWord');
-        list.push(spanText);
-        if (list.length == 1) {
-          element.scrollIntoView({ behavior: 'smooth', block: 'center' });
-        }
-      }
-    }
-    // if (type == 2) {
-    var nextHightList = [];
-    //跨页 目前只考虑跨1页
-    if (endIndex != undefined) {
-      for (var i = 0; i < nextArr.length; i++) {
-        var element = nextArr[i];
-        var hItem = {};
-        var cssText = element.style.cssText;
-        var spanText = element.innerText;
-        console.log(spanText);
-        var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;
-        var s = spanText.replaceAll(' ', '');
-        console.log(spanText);
-        if (
-          text.includes(spanText) ||
-          (s && text.includes(s)) ||
-          (d && text.includes(d)) ||
-          spanText.includes(text) ||
-          (spanText.substring(2) && text.includes(spanText.substring(2)))
-        ) {
-          list.push(spanText);
-        }
-        if (text.endsWith(spanText)) {
-          break;
-        }
-      }
-    } else {
-      //跨页 目前只考虑跨2页
-      for (var i = 0; i < nextArr.length; i++) {
-        var element = nextArr[i];
-        var hItem = {};
-        var cssText = element.style.cssText;
-        var spanText = element.innerText;
-        console.log(spanText);
-
-        list.push(spanText);
-      }
-      var thirdHightList = [];
-      if (thirdIndex != 0 && thirdIndex != undefined) {
-        for (var z = 0; z < thirdIndex + 1; z++) {
-          var element = thirdArr[z];
-          var hItem = {};
-          var cssText = element.style.cssText;
-          var spanText = element.innerText;
-          console.log(spanText);
-          var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;
-          var s = spanText.replaceAll(' ', '');
-          console.log(spanText);
-          if (
-            text.includes(spanText) ||
-            (s && text.includes(s)) ||
-            (d && text.includes(d)) ||
-            spanText.includes(text) ||
-            (spanText.substring(2) && text.includes(spanText.substring(2)))
-          ) {
-            list.push(spanText);
-          }
-          if (text.endsWith(spanText)) {
-            break;
-          }
-        }
-      }
-    }
-    // list.forEach((item) => {
-    //   handleSearch(item);
-    // });
-  }
-};
-const getStartIndex = (arr, text, total) => {
-  var indexs = [];
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    console.log('===' + spanText);
-    if (
-      (spanText && text.startsWith(spanText)) ||
-      (spanText && spanText.substring(2) && spanText && text.startsWith(spanText.substring(2))) ||
-      (spanText.indexOf('。') > -1 &&
-        spanText.split('。')[1] &&
-        text.startsWith(spanText.split('。')[1]))
-    ) {
-      indexs.push(i);
-      //   return i;
-    }
-  }
-  if (indexs.length == 0) {
-    return 0;
-  } else if (indexs.length == 2) {
-    console.log(JSON.stringify(indexs));
-    return indexs[0] == 0 ? indexs[1] : indexs[0];
-  } else {
-    return indexs[0];
-  }
-  //todo 有问题
-  // if (count == arr.length) {
-  //   start.value = start.value + 1;
-  //   text = text.substring(start.value, total);
-  //   getStartIndex(arr, text, total);
-  // }
-};
-const getEndIndex = (arr, text, total, startIndex) => {
-  for (var i = 0; i < arr.length; i++) {
-    var element = arr[i];
-    var spanText = element.innerText;
-    if(spanText.includes('的名著《政治经济学与赋税原理》中指出:地租仅只是为了使用土地而付给地主的金额') ){
-      debugger;
-    }
-    var e='';
-    if (spanText.endsWith('。')) {
-      spanText = spanText.substring(0, spanText.lastIndexOf('。'));
-    }
-     if (spanText.indexOf('。')>-1) {
-      e = spanText.substring(0, spanText.lastIndexOf('。'));
-    }
-    console.log('===' + spanText);
-    if (
-      (spanText && text.endsWith(spanText) && spanText.length > 0) ||
-      (spanText&&spanText.indexOf(text) > -1)||(e && text.endsWith(e))
-    ) {
-      return i;
-    }
-  }
-};
-const removeSourceHightLight = () => {
-  //获取页面 ai定位移除
-
-  const arr = document.getElementsByClassName('searchWord');
-  const l = arr.length;
-  for (let i = l - 1; i >= 0; i--) {
-    if (arr[i] != null) {
-      arr[i].classList.remove('searchWord');
-    }
-  }
-};
-// 高亮方法,可以使用vue所有页面
-const handleSearch = (e: any) => {
-  searchNum.value = 0; //本页有多少个关键词
-  indexNum.value = 0; //当前关键词序号
-  let searchVal = e;
-  //words是内容区域的类名,我这个是word文档的类名
-  let main = <any>document.querySelector('.words');
-  let innerHTML = main.innerHTML;
-
-  // 每次搜索之前都需要将em替换回来,不然就会出现em里面套em的情况而导致em数量一直叠加,
-  //多个关键词这点可以去掉,不然只显示最后一个关键词高亮
-  //   let emReg1 = new RegExp('<em class="searchWord">', 'g');
-  //   innerHTML = innerHTML.replace(emReg1, '');
-  //   let emReg2 = new RegExp('</em>', 'g');
-  //   innerHTML = innerHTML.replace(emReg2, '');
-  //
-  //删除当前关键词的背景色
-  //多个关键词这点可以去掉,不然只显示最后一个关键词高亮
-  //   let emReg3 = new RegExp('<em class="currentSearchWord">', 'g');
-  //   innerHTML = innerHTML.replace(emReg3, '');
-  //   let emReg4 = new RegExp('</em>', 'g');
-  //   innerHTML = innerHTML.replace(emReg4, '');
-  try {
-    if (searchVal) {
-      // 设置本次搜索背景色
-      let reg = new RegExp(searchVal, 'i');
-      innerHTML = innerHTML.replace(reg, '<em class="searchWord">' + searchVal + '</em>');
-    }
-    main.innerHTML = innerHTML;
-  } catch (e) {
-    console.log(e);
-  }
-};
-const searchGaoLian = (e: any) => {
-  let searchVal = e;
-  searchNum.value = document.getElementsByTagName('em').length;
-  if (searchNum.value != 0) {
-    // 使用.style.background会出现em删不掉会一直叠加的情况 因此只能替换innerHTML
-    document.getElementsByTagName('em')[0].innerHTML =
-      '<em class="currentSearchWord">' + searchVal + '</em>';
-    // 滚动到第一个关键字位置
-    document.getElementsByTagName('em')[0].scrollIntoView({
-      block: 'start',
-      behavior: 'smooth'
-    });
-  }
-};
-
-const fullScreen = () => {
-  const pdfSrc = props.src.replace(window.AppGlobalConfig.knowledgeDocUrlProxy, window.AppGlobalConfig.knowledgeDocUrlProxy2)
-  window.open(`/aisearch/#/viewer/word?file=${encodeURIComponent(pdfSrc)}`, '_blank')
-}
-//生命周期显示word
-onMounted(() => {
-  inti();
-});
-</script>
-<style lang="scss" scoped>
-.word-container {
-  width: 100%;
-  height: 100%;
-
-  //position: relative;
-
-  .spin {
-    width: 100%;
-    display: flex;
-    margin-top: 200px;
-    justify-content: center;
-    align-items: center;
-  }
-  .header {
-    height: 40px;
-    position: absolute;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    border-bottom: 1px solid #eee;
-    top:0;
-    z-index: 10001;
-    background: #fff;
-    width: 100%;
-
-    .title {
-      font-size: 18px;
-      font-weight: bolder;
-    }
-    .close-icon {
-      position: absolute;
-      top: 10px;
-      right: 21px;
-      cursor: pointer;
-    }
-    .full-screen {
-      position: absolute;
-      top: 10px;
-      right: 51px;
-      cursor: pointer;
-      color: #0C6FF7;
-    }
-  }
-  .words {
-    overflow: auto;
-    margin-top: 40px;
-    max-height: 1200px;
-  }
-}
-</style>
-<style s>
-.searchWord {
-  background-color: #0076fa;
-  line-height: 40px;
-  opacity: 0.8;
-  color: white !important;
-}
-.docx-wrapper {
-  background: white !important;
-}
-.docx-wrapper .docx {
-  width: 100% !important;
-
-  padding: 50px !important;
-}
-.docx-wrapper .docx span {
-  font-size: 20px !important;
-}
-.docx-wrapper > section.docx {
-  box-shadow: unset !important;
-}
-</style>