Ver código fonte

[web_demo] 新增版面分析web demo,其余页面部分优化

yanxin 2 anos atrás
pai
commit
7d8779d13e

+ 10 - 1
src/api/api.ts

@@ -19,6 +19,12 @@ interface MagciColorRes {
   cost: number;
 }
 
+interface DetectionRes {
+  code: number;
+  response_id: string;
+  data: any;
+}
+
 interface OcrRecRes {
   code: number;
   response_id: string;
@@ -36,10 +42,13 @@ export const IMMagicColor = (
 ): Promise<PredictRes<MagciColorRes>> =>
   server.post("/v1/image_process/magic_color", data);
 
+export const Detection = (data: FormData): Promise<DetectionRes> =>
+  server.post("/v1/detection", data);
+
 export const OcrRec = (data: FormData): Promise<OcrRecRes> =>
   server.post("/v1/ocr", data);
 
-export const TableRec = (data: FormData): Promise<TableRecRes> => 
+export const TableRec = (data: FormData): Promise<TableRecRes> =>
   server.post("/v1/table_rec", data);
 
 export const SubmitBug = (data: any): Promise<OcrRecRes> =>

+ 1 - 1
src/api/index.ts

@@ -1,7 +1,7 @@
 import axios from "axios";
 
 const server = axios.create({
-  baseURL: "http://192.168.10.33:80",
+  baseURL: "http://localhost:7896",
 });
 
 server.interceptors.request.use(

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
src/dist/assets/index-23a74d14.css


Diferenças do arquivo suprimidas por serem muito extensas
+ 140 - 135
src/dist/assets/index-6825386e.js


+ 2 - 2
src/dist/index.html

@@ -4,8 +4,8 @@
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>DocumentAI Web Demo</title>
-    <script type="module" crossorigin src="./assets/index-6825386e.js"></script>
-    <link rel="stylesheet" href="./assets/index-23a74d14.css">
+    <script type="module" crossorigin src="./assets/index-d678fce6.js"></script>
+    <link rel="stylesheet" href="./assets/index-9e3c8667.css">
   </head>
   <body>
     <div id="app"></div>

+ 225 - 56
src/pages/main/views/Detection/LayoutAnalysis.vue

@@ -2,39 +2,97 @@
   <el-row :gutter="20">
     <el-col :span="12" class="place">
       <el-row class="small-title">
-        <h2>版面分析(暂未实现)</h2>
+        <h2>版面分析</h2>
       </el-row>
+      <el-row style="color: gray; font-size: small;">
+        <p>目前支持检测图片与表格</p>
+      </el-row>
+      <el-row style="color: gray; font-size: small;">
+        <h4>支持jpg, png, bmp, pdf格式</h4>
+      </el-row>
+      <div class="common-layout">
+        <el-container>
+          <el-input type="file" v-model="fileName" @change="uploadImg"></el-input>
+          <el-button type="primary" @click="predict">Predict</el-button>
+        </el-container>
+      </div>
+      <div v-show="is_pdf">
+        <el-row>
+          <el-button-group>
+            <el-button type="primary" :icon="ArrowLeft" @click="prePage">上一页</el-button>
+            <el-button type="primary" @click="nextPage">
+              下一页<el-icon class="el-icon--right">
+                <ArrowRight />
+              </el-icon>
+            </el-button>
+          </el-button-group>
+          <!-- <div class="page-tool-item" @click="prePage">上一页</div>
+          <div class="page-tool-item" @click="nextPage">下一页</div> -->
+          <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
+          <el-container>
+            <el-input type="number" v-model="pdf_page"></el-input>
+            <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
+          </el-container>
+        </el-row>
+      </div>
+      <el-row>
+        <!-- 用于展示图片 -->
+        <img id="show-img" class="show-area" />
+      </el-row>
+      <div class="pdf-preview" v-show="false">
+        <div class="pdf-wrap">
+          <vue-pdf-embed :source="state.source" :scale="3.0" class="vue-pdf-embed" :page="state.pageNum" />
+        </div>
+      </div>
+      <canvas id="canvas"></canvas>
     </el-col>
     <el-col :span="12" class="place">
+      <el-row class="small-title">
+        <h2 style="margin-right: 0;">识别结果展示</h2>
+        <el-button type="danger" @click="submitBug" disabled>提交bug</el-button>
+      </el-row>
+      <div>
+        <el-scrollbar height="600px">
+          <ul>
+            <li v-for="(item, index) in recArr" :key="index" @click="handleClick(index, item)"
+              :style="index == selectedItem ? 'color: blue' : ''">
+              {{ item }}
+            </li>
+          </ul>
+        </el-scrollbar>
+      </div>
+      <el-row>
+        <section> 耗时:{{ predictTime }} ms.</section>
+      </el-row>
     </el-col>
   </el-row>
 </template>
 
 <script lang="ts" setup>
-import { IMMagicColor, SubmitBug } from '../../../../api/api'
-import { useServerIpStore } from '../../../../store/ServerIp';
-import { storeToRefs } from 'pinia'
-
+import { Detection, SubmitBug } from '../../../../api/api'
+import { fabric } from 'fabric';
 import { reactive, ref, toRefs, computed } from 'vue'
 import { onMounted } from "vue";
 import VuePdfEmbed from "vue-pdf-embed";
 import { createLoadingTask } from "vue3-pdfjs/esm"; // 获得总页数
+import {
+  ArrowLeft,
+  ArrowRight,
+} from '@element-plus/icons-vue'
 
 let loadingTask: any;
 
+const is_pdf = ref(false);
 const pdf_page = ref(1);
-
 const pdf_img: any = ref("")
 
 const state = reactive({
   source: "", //预览pdf文件地址
   pageNum: 1, //当前页面
-  scale: 1, // 缩放比例
+  // scale: 4, // 缩放比例
   numPages: 0, // 总页数
 });
 
-const scale = computed(() => `transform:scale(${state.scale})`)
-
 function dataURLtoBlob(dataURL: any) {
   var arr = dataURL.split(','),
     mime = arr[0].match(/:(.*?);/)[1],
@@ -52,7 +110,7 @@ function getPdfImage(index: number) {
   loadingTask.promise.then((pdf: any) => {
     state.numPages = pdf.numPages;
     pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 10.0 })
+      const viewport = page.getViewport({ scale: 4.0 })
       canvas.value.height = viewport.height;
       canvas.value.width = viewport.width;
       // 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
@@ -68,8 +126,10 @@ function getPdfImage(index: number) {
       });
       canvas.value.toBlob(function (blob) {
         pdf_img.value = dataURLtoBlob(canvas.value.toDataURL('images/png', 1.0))
-        // console.log(pdf_img.value);
-        // console.log(canvas.value.toDataURL(), state.pageNum)
+        const showImg = document.getElementById("show-img") as HTMLImageElement;
+        showImg.src = canvas.value.toDataURL('images/png', 1.0);
+        fa_canvas = new fabric.Canvas(canvas.value);
+        rects.splice(0)
       });
     })
   });
@@ -99,16 +159,6 @@ function nextPage() {
     getPdfImage(state.pageNum);
   }
 }
-function pageZoomOut() {
-  if (state.scale < 2) {
-    state.scale += 0.1;
-  }
-}
-function pageZoomIn() {
-  if (state.scale > 1) {
-    state.scale -= 0.1;
-  }
-}
 
 // 构建 File 对象
 function blobToFile(blob: any, fileName: any) {
@@ -134,29 +184,43 @@ async function convertCanvasToFile(canvas: HTMLCanvasElement, fileName: any) {
   return file;
 }
 
-const si = useServerIpStore()
-const { server_ip } = storeToRefs(si);
-
 let loading = ref(false)
+let show_predict = ref(false)
+let predictTime = ref(0)
 const fileName = ref(null);
+const canvas = ref(null as unknown as HTMLCanvasElement);
+
+let selectedItem = ref(-1)
 
+let recArr: any = ref([])
+
+let fa_canvas: any = null;
+const rec_result = ref("");
 let bugId = ref("");
 
-let predictTime = ref(0)
+const activeName = ref('2')
+const json_result = ref("");
 
-const is_pdf = ref(false);
+interface iRect {
+  left: number,
+  top: number,
+  width: number,
+  height: number
+}
 
-const canvas = ref(null as unknown as HTMLCanvasElement);
+let rects: any = []
 
 onMounted(async () => {
   canvas.value = document.getElementById("canvas") as HTMLCanvasElement;
 });
 
 const uploadImg = () => {
+  /**
+   * 这里由于操作是绑定在 el-input 上;因此需要在内部重新获取 input 再拿到 file
+   */
   const reader = new FileReader();
+  // 用于展示
   const showImg = document.getElementById("show-img") as HTMLImageElement;
-  const rawImg = document.getElementById("raw-img") as HTMLImageElement;
-  const predictImg = document.getElementById("predict-img") as HTMLImageElement;
   const inputElement = document
     .getElementsByClassName("el-input")[0]
     .getElementsByTagName("input")[0];
@@ -165,81 +229,157 @@ const uploadImg = () => {
     const file = inputElement.files![0];
     reader.onload = () => {
       const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
+      fa_canvas ? fa_canvas.clear() : 0;
       if (post_ == ".pdf") {
         state.pageNum = 1;
-        state.scale = 1;
+        // state.scale = 4;
         state.source = URL.createObjectURL(file);
         is_pdf.value = true
         loadingTask = createLoadingTask(state.source);
         getPdfImage(state.pageNum);
       } else if (post_ == ".jpg" || post_ == ".png" || post_ == ".bmp") {
         showImg.src = URL.createObjectURL(file);
-        rawImg.src = URL.createObjectURL(file);
+        showImg.onload = () => {
+          canvas.value.width = showImg.width;
+          canvas.value.height = showImg.height;
+          fa_canvas = new fabric.Canvas(canvas.value);
+          rects.splice(0)
+          selectedItem.value = -1;
+        }
         is_pdf.value = false
       } else {
         alert('不支持的文件格式!')
-        fileName.value = null
+        // fileName.value = null
       }
     };
     reader.readAsDataURL(file);
   } catch (err) {
     console.error(err);
   }
+  if (show_predict.value === true)
+    show_predict.value = !show_predict.value;
 };
 
-const predict = () => {
+type RectWithId = fabric.Rect & { id: number };
+
+function CreateRect(canvas: any, i: number, left: number, top: number, width: number, height: number, highlight: boolean) {
+  var rect = new fabric.Rect({
+    left: left,
+    top: top,
+    width: width,
+    height: height,
+    fill: 'transparent',
+    stroke: highlight ? 'blue' : 'green',
+    strokeWidth: 2,
+    opacity: 1.0,
+    selectable: false,
+    name: highlight ? 'high' : 'normal',
+  }) as RectWithId;
+  rect.set('id', i);
+  canvas.add(rect);
+  // canvas.renderAll();
+}
+
+const predict = async () => {
   if (fileName.value == undefined) {
     alert('请上传图片!')
     return;
   }
-  const showImg = document.getElementById("show-img") as HTMLImageElement;
-  const predictImg = document.getElementById("predict-img") as HTMLImageElement;
+
+  fa_canvas.clear()
+  rects.splice(0)
+
+  const img = document.getElementById("show-img") as HTMLImageElement;
   const inputElement = document
     .getElementsByClassName("el-input")[0]
     .getElementsByTagName("input")[0];
   const file = inputElement.files![0];
-  // console.log(file)
 
   loading.value = !loading.value
   var data = new FormData();
 
   if (is_pdf.value) {
     const file: any = convertCanvasToFile(canvas.value, "pdf.png").then(result => {
-      console.log(result)
       data.append('images', result);
-      IMMagicColor(data).then(res => {
+      Detection(data).then(res => {
         console.log(res.code)
-        // bug_id.value = res.response_id;
-        predictImg.src = server_ip.value + res.data.out_image
-        predictTime.value = res.data.cost
+        json_result.value = JSON.stringify(res.data, null, 4);
+        console.log(res.data);
+        recArr.value.splice(0);
+        let tmp_text = res.data.labels;
+        if (tmp_text.length == 0) {
+          recArr.value.push("no result!");
+        } else {
+          for (let i = 0; i < tmp_text.length; i++) {
+            recArr.value.push(tmp_text[i]);
+          }
+        }
+        let tmp_boxes = res.data.boxes;
+        // fa_canvas = new fabric.Canvas(canvas.value);
+        const h_radio = img.height / img.naturalHeight;
+        const w_radio = img.width / img.naturalWidth;
+        for (let i = 0; i < tmp_boxes.length; i++) {
+          let left = w_radio * tmp_boxes[i][0];
+          let top = h_radio * tmp_boxes[i][1];
+          let width = w_radio * (tmp_boxes[i][2] - tmp_boxes[i][0]);
+          let height = h_radio * (tmp_boxes[i][3] - tmp_boxes[i][1]);
+          const rect: iRect = { left, top, width, height };
+          rects.push(rect);
+          CreateRect(fa_canvas, i, left, top, width, height, false);
+        }
+        predictTime.value = res.data.cost;
+        loading.value = !loading.value;
         bugId.value = res.response_id;
-
-
-        loading.value = false
+        if (show_predict.value === false)
+          show_predict.value = !show_predict.value;
       }).catch(function (err) {
-        loading.value = false
-        // bug_id.value = ""
+        loading.value = !loading.value;
+        bugId.value = ""
         predictTime.value = 0
       });
     })
-    // console.log(file)
-    // data.append('images', file.File);
   } else {
     data.append('images', file);
 
-    IMMagicColor(data).then(res => {
-      predictImg.src = server_ip.value + res.data.out_image
-      predictTime.value = res.data.cost
+    Detection(data).then(res => {
+      console.log(res.code)
+      json_result.value = JSON.stringify(res.data, null, 4);
+      console.log(res.data);
+      // rec_result.value = res.data.text.reduce((total: any, cur: any) => total + `<p>${cur}</p>`);
+      recArr.value.splice(0);
+      let tmp_text = res.data.labels;
+      if (tmp_text.length == 0) {
+        alert('未检测到结果!');
+      } else {
+        for (let i = 0; i < tmp_text.length; i++) {
+          recArr.value.push(tmp_text[i]);
+        }
+      }
+      let tmp_boxes = res.data.boxes;
+      // fa_canvas = new fabric.Canvas(canvas.value);
+      const h_radio = img.height / img.naturalHeight;
+      const w_radio = img.width / img.naturalWidth;
+      for (let i = 0; i < tmp_boxes.length; i++) {
+        let left = w_radio * tmp_boxes[i][0];
+        let top = h_radio * tmp_boxes[i][1];
+        let width = w_radio * (tmp_boxes[i][2] - tmp_boxes[i][0]);
+        let height = h_radio * (tmp_boxes[i][3] - tmp_boxes[i][1]);
+        const rect: iRect = { left, top, width, height };
+        rects.push(rect);
+        CreateRect(fa_canvas, i, left, top, width, height, false);
+      }
+      predictTime.value = res.data.cost;
+      loading.value = !loading.value;
       bugId.value = res.response_id;
-
-      loading.value = !loading.value
+      if (show_predict.value === false)
+        show_predict.value = !show_predict.value;
     }).catch(function (err) {
       loading.value = !loading.value;
       bugId.value = ""
       predictTime.value = 0
     });
   }
-}
+};
 
 const submitBug = async () => {
   if (bugId.value == undefined || bugId.value == "") {
@@ -247,6 +387,7 @@ const submitBug = async () => {
     return;
   }
 
+
   SubmitBug(bugId.value).then(res => {
     console.log(res.code, res.data)
   }).catch(function (err) {
@@ -255,10 +396,37 @@ const submitBug = async () => {
   });
 };
 
-let src = ''
+async function handleClick(index: any, item: any) {
+  selectedItem.value = index;
+  let objects = fa_canvas.getObjects();
+  for (let i = 0; i < objects.length; i++) {
+    if (objects[i].name === 'high') {
+      // 找到名为 rectName 的矩形元素,执行删除操作等
+      fa_canvas.remove(objects[i]);
+      break;
+    }
+  }
+  CreateRect(fa_canvas, index, rects[index].left, rects[index].top, rects[index].width, rects[index].height, true);
+}
 </script>
 
 <style scoped>
+#canvas {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 0;
+  /* 设置Canvas的层级,使其显示在图像之上 */
+  background-color: transparent;
+}
+
+#show-img {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 0;
+}
+
 .demo-image__placeholder .block {
   padding: 30px 0;
   text-align: center;
@@ -362,6 +530,7 @@ let src = ''
   z-index: 100;
   cursor: pointer;
   margin-left: 50%;
+  top: 100%;
   transform: translateX(-50%);
 }
 

+ 4 - 16
src/pages/main/views/ImageProcess/magicColor.vue

@@ -24,7 +24,7 @@
         </el-row>
         <div class="pdf-preview" v-show="is_pdf">
           <div class="pdf-wrap">
-            <vue-pdf-embed :source="state.source" :scale="10.0" class="vue-pdf-embed" :page="state.pageNum" />
+            <vue-pdf-embed :source="state.source" :scale="3.0" class="vue-pdf-embed" :page="state.pageNum" />
           </div>
           <div class="page-tool">
             <div class="page-tool-item" @click="prePage">上一页</div>
@@ -85,12 +85,10 @@ const pdf_img: any = ref("")
 const state = reactive({
   source: "", //预览pdf文件地址
   pageNum: 1, //当前页面
-  scale: 1, // 缩放比例
+  // scale: 4, // 缩放比例
   numPages: 0, // 总页数
 });
 
-const scale = computed(() => `transform:scale(${state.scale})`)
-
 function dataURLtoBlob(dataURL: any) {
   var arr = dataURL.split(','),
     mime = arr[0].match(/:(.*?);/)[1],
@@ -108,7 +106,7 @@ function getPdfImage(index: number) {
   loadingTask.promise.then((pdf: any) => {
     state.numPages = pdf.numPages;
     pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 10.0 })
+      const viewport = page.getViewport({ scale: 4.0 })
       canvas.value.height = viewport.height;
       canvas.value.width = viewport.width;
       // 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
@@ -155,16 +153,6 @@ function nextPage() {
     getPdfImage(state.pageNum);
   }
 }
-function pageZoomOut() {
-  if (state.scale < 2) {
-    state.scale += 0.1;
-  }
-}
-function pageZoomIn() {
-  if (state.scale > 1) {
-    state.scale -= 0.1;
-  }
-}
 
 // 构建 File 对象
 function blobToFile(blob: any, fileName: any) {
@@ -223,7 +211,7 @@ const uploadImg = () => {
       const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
       if (post_ == ".pdf") {
         state.pageNum = 1;
-        state.scale = 1;
+        // state.scale = 4;
         state.source = URL.createObjectURL(file);
         is_pdf.value = true
         loadingTask = createLoadingTask(state.source);

+ 16 - 20
src/pages/main/views/Recognize/ocr.vue

@@ -22,7 +22,7 @@
       </el-row>
       <div class="pdf-preview" v-show="is_pdf">
         <div class="pdf-wrap">
-          <vue-pdf-embed :source="state.source" :scale="10.0" class="vue-pdf-embed" :page="state.pageNum" />
+          <vue-pdf-embed :source="state.source" :scale="3.0" class="vue-pdf-embed" :page="state.pageNum" />
         </div>
         <div class="page-tool">
           <div class="page-tool-item" @click="prePage">上一页</div>
@@ -112,12 +112,10 @@ const pdf_img: any = ref("")
 const state = reactive({
   source: "", //预览pdf文件地址
   pageNum: 1, //当前页面
-  scale: 1, // 缩放比例
+  // scale: 4, // 缩放比例
   numPages: 0, // 总页数
 });
 
-const scale = computed(() => `transform:scale(${state.scale})`)
-
 function dataURLtoBlob(dataURL: any) {
   var arr = dataURL.split(','),
     mime = arr[0].match(/:(.*?);/)[1],
@@ -135,7 +133,7 @@ function getPdfImage(index: number) {
   loadingTask.promise.then((pdf: any) => {
     state.numPages = pdf.numPages;
     pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 10.0 })
+      const viewport = page.getViewport({ scale: 4.0 })
       canvas.value.height = viewport.height;
       canvas.value.width = viewport.width;
       // 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
@@ -184,16 +182,6 @@ function nextPage() {
     getPdfImage(state.pageNum);
   }
 }
-function pageZoomOut() {
-  if (state.scale < 2) {
-    state.scale += 0.1;
-  }
-}
-function pageZoomIn() {
-  if (state.scale > 1) {
-    state.scale -= 0.1;
-  }
-}
 
 // 构建 File 对象
 function blobToFile(blob: any, fileName: any) {
@@ -272,7 +260,7 @@ const uploadImg = () => {
       fa_canvas ? fa_canvas.clear() : 0;
       if (post_ == ".pdf") {
         state.pageNum = 1;
-        state.scale = 1;
+        // state.scale = 4;
         state.source = URL.createObjectURL(file);
         is_pdf.value = true
         loadingTask = createLoadingTask(state.source);
@@ -351,8 +339,12 @@ const predict = async () => {
         rec_result.value = res.data.text.reduce((total: any, cur: any) => total + `<p>${cur}</p>`);
         recArr.value.splice(0);
         let tmp_text = res.data.text;
-        for (let i = 0; i < tmp_text.length; i++) {
-          recArr.value.push(tmp_text[i]);
+        if (tmp_text.length == 0) {
+          alert('未检测到结果!');
+        } else {
+          for (let i = 0; i < tmp_text.length; i++) {
+            recArr.value.push(tmp_text[i]);
+          }
         }
         let tmp_boxes = res.data.boxes;
         // fa_canvas = new fabric.Canvas(canvas.value);
@@ -387,8 +379,12 @@ const predict = async () => {
       rec_result.value = res.data.text.reduce((total: any, cur: any) => total + `<p>${cur}</p>`);
       recArr.value.splice(0);
       let tmp_text = res.data.text;
-      for (let i = 0; i < tmp_text.length; i++) {
-        recArr.value.push(tmp_text[i]);
+      if (tmp_text.length == 0) {
+        alert('未检测到结果!');
+      } else {
+        for (let i = 0; i < tmp_text.length; i++) {
+          recArr.value.push(tmp_text[i]);
+        }
       }
       let tmp_boxes = res.data.boxes;
       // fa_canvas = new fabric.Canvas(canvas.value);

+ 29 - 15
src/pages/main/views/Recognize/tableRec.vue

@@ -33,7 +33,7 @@
           <div class="page-tool-item" @click="nextPage">下一页</div>
           <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
         <!-- <div class="page-tool-item" @click="pageZoomOut">放大</div>
-              <div class="page-tool-item" @click="pageZoomIn">缩小</div> -->
+                  <div class="page-tool-item" @click="pageZoomIn">缩小</div> -->
           <el-input type="number" v-model="pdf_page"></el-input>
           <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
         </div>
@@ -64,7 +64,9 @@
                   <span v-html="item"></span>
                 </div>
               </el-scrollbar>
-              <el-button type="info" :icon="DocumentCopy" @click="copy(index)" plain />
+            <!-- <div>
+                <el-button type="info" :icon="DocumentCopy" @click="copy(index)" v-on:mouseover="showText()" v-on:mouseout="hideText()" plain />
+                  </div> -->
             </li>
           </el-collapse-item>
         </el-collapse>
@@ -104,7 +106,7 @@ const { bug_id } = storeToRefs(bi);
 const state = reactive({
   source: "", //预览pdf文件地址
   pageNum: 1, //当前页面
-  scale: 3, // 缩放比例
+  // scale: 4, // 缩放比例
   numPages: 0, // 总页数
 });
 
@@ -150,7 +152,7 @@ const uploadImg = () => {
       const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
       if (post_ == ".pdf") {
         state.pageNum = 1;
-        state.scale = 3;
+        // state.scale = 4;
         state.source = URL.createObjectURL(file);
         is_pdf.value = true
         loadingTask = createLoadingTask(state.source);
@@ -202,14 +204,17 @@ const predict = async () => {
         predictTime.value = res.data.cost;
         jsonArr.value.splice(0);
         let tmp_json = res.data.json_items;
-        for (let i = 0; i < tmp_json.length; i++) {
-          jsonArr.value.push(JSON.stringify(tmp_json[i], null, 4));
-        }
-
-        htmlArr.value.splice(0);
-        let tmp_html = res.data.html_items;
-        for (let i = 0; i < tmp_html.length; i++) {
-          htmlArr.value.push(tmp_html[i]);
+        if (tmp_json.length == 0) {
+          alert('未检测到结果!');
+        } else {
+          for (let i = 0; i < tmp_json.length; i++) {
+            jsonArr.value.push(JSON.stringify(tmp_json[i], null, 4));
+          }
+          htmlArr.value.splice(0);
+          let tmp_html = res.data.html_items;
+          for (let i = 0; i < tmp_html.length; i++) {
+            htmlArr.value.push(tmp_html[i]);
+          }
         }
         loading.value = false
       }).catch(function (err) {
@@ -247,8 +252,6 @@ const predict = async () => {
   }
 };
 
-const scale = computed(() => `transform:scale(${state.scale})`)
-
 function SetPdfPage() {
   if (pdf_page.value >= 1 && pdf_page.value <= state.numPages) {
     console.log(pdf_page.value)
@@ -260,6 +263,16 @@ function SetPdfPage() {
   }
 }
 
+let copy_text = ref("click this button to copy the html table");
+
+function showText() {
+  copy_text.value = "click it!";
+}
+
+function hideText() {
+  copy_text.value = "click this button to copy the html table";
+}
+
 const submitBug = async () => {
   if (bug_id.value == undefined || bug_id.value == "") {
     alert('请先预测结果!')
@@ -315,7 +328,7 @@ function getPdfImage(index: number) {
   loadingTask.promise.then((pdf: any) => {
     state.numPages = pdf.numPages;
     pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 3.0 })
+      const viewport = page.getViewport({ scale: 4.0 })
       canvas.value.height = viewport.height;
       canvas.value.width = viewport.width;
       // 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
@@ -357,6 +370,7 @@ const { toClipboard } = useClipboard()
 function copy(index: any) {
   try {
     toClipboard(htmlArr.value[index])
+    copy_text.value = "copied!";
     console.log('Copied to clipboard')
   } catch (e) {
     console.error(e)

+ 1 - 2
src/store/ServerIp.ts

@@ -2,8 +2,7 @@ import { defineStore } from 'pinia';
 import { ref } from 'vue'
 
 export const useServerIpStore = defineStore('server_ip', () => {
-  const server_ip = ref("http://192.168.10.33:80")
-  
+  const server_ip = ref("http://localhost:7896")
 
   return { server_ip }
 })