Ver Fonte

[web_demo] 新增uie页面,所有模块都有样例图片可供选择,新增文件上传与展示合一组件

yanxin há 1 ano atrás
pai
commit
be30f99072
61 ficheiros alterados com 633 adições e 113 exclusões
  1. 3 2
      src/MenuView.vue
  2. 10 0
      src/api/api.ts
  3. BIN
      src/assets/dewarp(1).jpg
  4. BIN
      src/assets/dewarp(2).jpg
  5. BIN
      src/assets/layout_analysis(1).png
  6. BIN
      src/assets/layout_analysis(2).png
  7. BIN
      src/assets/layout_analysis(3).png
  8. BIN
      src/assets/magic_color(1).jpg
  9. BIN
      src/assets/magic_color(2).jpg
  10. BIN
      src/assets/magic_color(3).jpg
  11. BIN
      src/assets/magic_color(4).jpg
  12. BIN
      src/assets/magic_color(5).jpg
  13. BIN
      src/assets/ocr(1).jpg
  14. BIN
      src/assets/ocr(2).jpg
  15. BIN
      src/assets/ocr(3).jpg
  16. BIN
      src/assets/stamp(1).jpg
  17. BIN
      src/assets/stamp(2).jpg
  18. BIN
      src/assets/stamp(3).jpg
  19. BIN
      src/assets/table_rec(1).png
  20. BIN
      src/assets/table_rec(2).png
  21. BIN
      src/assets/table_rec(3).png
  22. BIN
      src/assets/table_rec(4).png
  23. BIN
      src/assets/table_rec(5).png
  24. BIN
      src/assets/uie(1).jpg
  25. BIN
      src/assets/uie(2).jpg
  26. 155 0
      src/components/ImageList.vue
  27. 176 0
      src/components/ImageWithUpload.vue
  28. BIN
      src/dist/assets/dewarp(1)-d610e810.jpg
  29. BIN
      src/dist/assets/dewarp(2)-bbfd45cd.jpg
  30. 95 95
      src/dist/assets/index-d9a132a3.js
  31. 1 1
      src/dist/assets/index-2a05abf2.css
  32. BIN
      src/dist/assets/layout_analysis(1)-5d1e538c.png
  33. BIN
      src/dist/assets/layout_analysis(3)-e92197e8.png
  34. BIN
      src/dist/assets/magic_color(1)-98638402.jpg
  35. BIN
      src/dist/assets/magic_color(2)-a2fd0add.jpg
  36. BIN
      src/dist/assets/magic_color(3)-fe33af0e.jpg
  37. BIN
      src/dist/assets/magic_color(4)-6eb6e914.jpg
  38. BIN
      src/dist/assets/magic_color(5)-0fb72a48.jpg
  39. BIN
      src/dist/assets/ocr(1)-2bb78629.jpg
  40. BIN
      src/dist/assets/ocr(2)-b544c22e.jpg
  41. BIN
      src/dist/assets/ocr(3)-eb547f1a.jpg
  42. BIN
      src/dist/assets/stamp(1)-0368e961.jpg
  43. BIN
      src/dist/assets/stamp(2)-dc818ba4.jpg
  44. BIN
      src/dist/assets/stamp(3)-51cc00e5.jpg
  45. BIN
      src/dist/assets/table_rec(1)-d43e33d1.png
  46. BIN
      src/dist/assets/table_rec(2)-e2b8892f.png
  47. BIN
      src/dist/assets/table_rec(3)-cf07e3aa.png
  48. BIN
      src/dist/assets/table_rec(4)-cdc99530.png
  49. BIN
      src/dist/assets/table_rec(5)-15921616.png
  50. BIN
      src/dist/assets/uie(1)-581c7f37.jpg
  51. BIN
      src/dist/assets/uie(2)-bac80682.jpg
  52. 2 2
      src/dist/index.html
  53. 6 2
      src/pages/main/views/Detection/LayoutAnalysis.vue
  54. 5 1
      src/pages/main/views/Detection/StampDetection.vue
  55. 5 1
      src/pages/main/views/ImageProcess/dewarp.vue
  56. 5 1
      src/pages/main/views/ImageProcess/magicColor.vue
  57. 156 5
      src/pages/main/views/NLP/UIEX.vue
  58. 5 1
      src/pages/main/views/Recognize/ocr.vue
  59. 5 1
      src/pages/main/views/Recognize/tableRec.vue
  60. 2 0
      src/store/CanvasImg.ts
  61. 2 1
      src/store/Server.ts

+ 3 - 2
src/MenuView.vue

@@ -42,8 +42,9 @@
           <el-col :span="3">🔥</el-col>
           <span>PDF转Word</span>
         </el-menu-item>
-        <el-menu-item index="9">
-          <span></span>
+        <el-menu-item index="9" @click="routerJump('/UIEX')">
+          <el-col :span="3">🔥</el-col>
+          <span>通用型文档信息抽取</span>
         </el-menu-item>
       </el-menu>
     </el-col>

+ 10 - 0
src/api/api.ts

@@ -49,6 +49,11 @@ interface TableRecRes {
   data: any;
 }
 
+interface UIEXRes {
+  code: number;
+  result: string;
+}
+
 export const GetVersion = (api: string): Promise<string> => server.get(api);
 
 export const GetBuildTag = (api: string): Promise<string> => server.get(api);
@@ -93,4 +98,9 @@ export const PDFToWord = (
   data: FormData
 ): Promise<PredictRes<ConvertRes>> => server.post(api, data);
 
+export const UIEX = (
+  api: string,
+  data: FormData
+): Promise<PredictRes<UIEXRes>> => server.post(api, data);
+
 export {};

BIN
src/assets/dewarp(1).jpg


BIN
src/assets/dewarp(2).jpg


BIN
src/assets/layout_analysis(1).png


BIN
src/assets/layout_analysis(2).png


BIN
src/assets/layout_analysis(3).png


BIN
src/assets/magic_color(1).jpg


BIN
src/assets/magic_color(2).jpg


BIN
src/assets/magic_color(3).jpg


BIN
src/assets/magic_color(4).jpg


BIN
src/assets/magic_color(5).jpg


BIN
src/assets/ocr(1).jpg


BIN
src/assets/ocr(2).jpg


BIN
src/assets/ocr(3).jpg


BIN
src/assets/stamp(1).jpg


BIN
src/assets/stamp(2).jpg


BIN
src/assets/stamp(3).jpg


BIN
src/assets/table_rec(1).png


BIN
src/assets/table_rec(2).png


BIN
src/assets/table_rec(3).png


BIN
src/assets/table_rec(4).png


BIN
src/assets/table_rec(5).png


BIN
src/assets/uie(1).jpg


BIN
src/assets/uie(2).jpg


+ 155 - 0
src/components/ImageList.vue

@@ -0,0 +1,155 @@
+<template>
+    <div class="demo-image">
+        <div v-for="(image, index) in images" :key="image" class="block">
+            <span class="demonstration"> 样例{{ index + 1 }} </span>
+            <el-image style="width: 100px; height: 100px" :src="image" :fit="'contain'" @click="imageClick(index)" />
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from 'vue'
+import { useCanvasImgStore } from '../store/CanvasImg';
+import { usePdfProperty } from '../store/PdfProperty';
+import { storeToRefs } from 'pinia'
+import { fabric } from 'fabric';
+
+import MagicColor1 from '@/assets/magic_color(1).jpg'
+import MagicColor2 from '@/assets/magic_color(2).jpg'
+import MagicColor3 from '@/assets/magic_color(3).jpg'
+import MagicColor4 from '@/assets/magic_color(4).jpg'
+import MagicColor5 from '@/assets/magic_color(5).jpg'
+
+import OCR1 from '@/assets/ocr(1).jpg'
+import OCR2 from '@/assets/ocr(2).jpg'
+import OCR3 from '@/assets/ocr(3).jpg'
+
+import Dewarp1 from '@/assets/dewarp(1).jpg'
+import Dewarp2 from '@/assets/dewarp(2).jpg'
+
+import LA1 from '@/assets/layout_analysis(1).png'
+import LA2 from '@/assets/layout_analysis(2).png'
+import LA3 from '@/assets/layout_analysis(3).png'
+
+import TableRec1 from '@/assets/table_rec(1).png'
+import TableRec2 from '@/assets/table_rec(2).png'
+import TableRec3 from '@/assets/table_rec(3).png'
+import TableRec4 from '@/assets/table_rec(4).png'
+import TableRec5 from '@/assets/table_rec(5).png'
+
+import Stamp1 from '@/assets/stamp(1).jpg'
+import Stamp2 from '@/assets/stamp(2).jpg'
+import Stamp3 from '@/assets/stamp(3).jpg'
+
+import UIE1 from '@/assets/uie(1).jpg'
+import UIE2 from '@/assets/uie(2).jpg'
+import UIE3 from '@/assets/uie(3).jpg'
+import UIE4 from '@/assets/uie(4).jpg'
+
+const props = defineProps({
+    module: String,
+});
+
+const c_img = useCanvasImgStore();
+const { show_image, show_canvas, fabric_canvas, image_item_index, input_file } = storeToRefs(c_img);
+const pdf = usePdfProperty();
+const { is_pdf } = storeToRefs(pdf);
+
+const fits = ['fill', 'contain', 'cover', 'none', 'scale-down']
+const images: any = ref([])
+onMounted(async () => {
+    if (props.module == 'magic_color') {
+        images.value.push(MagicColor1)
+        images.value.push(MagicColor2)
+        images.value.push(MagicColor3)
+        images.value.push(MagicColor4)
+        images.value.push(MagicColor5)
+    } else if (props.module == 'ocr') {
+        images.value.push(OCR1)
+        images.value.push(OCR2)
+        images.value.push(OCR3)
+    } else if (props.module == 'table_rec') {
+        images.value.push(TableRec1)
+        images.value.push(TableRec2)
+        images.value.push(TableRec3)
+        images.value.push(TableRec4)
+        images.value.push(TableRec5)
+    } else if (props.module == 'layout_analysis') {
+        images.value.push(LA1)
+        images.value.push(LA2)
+        images.value.push(LA3)
+    } else if (props.module == 'dewarp') {
+        images.value.push(Dewarp1)
+        images.value.push(Dewarp2)
+    } else if (props.module == 'stamp') {
+        images.value.push(Stamp1)
+        images.value.push(Stamp2)
+        images.value.push(Stamp3)
+    } else if (props.module == 'uie') {
+        images.value.push(UIE1)
+        images.value.push(UIE2)
+        // images.value.push(UIE3)
+        // images.value.push(UIE4)
+    }
+    imageClick(0)
+    image_item_index.value = 0
+});
+
+async function imageClick(index: number) {
+    if (fabric_canvas.value != null) {
+        fabric_canvas.value.dispose();
+        fabric_canvas.value = null;
+    }
+    image_item_index.value = index
+
+    show_image.value.src = images.value[index]
+    show_image.value.onload = () => {
+        show_canvas.value.width = show_image.value.width;
+        show_canvas.value.height = show_image.value.height;
+        fabric_canvas.value = new fabric.Canvas(show_canvas.value);
+        fabric_canvas.value.clear()
+    }
+    Image2File(images.value[index])
+    is_pdf.value = false
+}
+
+function Image2File(image: any) {
+    fetch(image)
+        .then(res => res.blob())
+        .then(blob => {
+            // 创建File对象
+            input_file.value = new File([blob], 'image.png', { type: 'image/png' })
+        })
+        .catch(err => console.error(err))
+}
+</script>
+
+
+
+<style scoped>
+.demo-image {
+    width: 100%;
+    height: auto;
+}
+
+.block {
+    padding: 30px 0;
+    text-align: center;
+    border-right: solid 1px var(--el-border-color);
+    display: inline-block;
+    width: 20%;
+    box-sizing: border-box;
+    vertical-align: top;
+}
+
+.demo-image .block:last-child {
+    border-right: none;
+}
+
+.demo-image .demonstration {
+    display: block;
+    color: var(--el-text-color-secondary);
+    font-size: 14px;
+    margin-bottom: 20px;
+}
+</style>

+ 176 - 0
src/components/ImageWithUpload.vue

@@ -0,0 +1,176 @@
+<template>
+    <div style="position:relative;width: 100%; height: 100%;">
+        <div style="opacity: 0; position:absolute;top:0;left:0;width: 100%; height: 100%; z-index:1;">
+            <div class="upload-container">
+                <div class="mask" @dragover.prevent @drop="handleDrop">
+                    <el-upload class="upload" drag :before-upload="BeforeUpload" :file-list="[]" action=""
+                        accept=".jpg,.jpeg,.png,.bmp,.pdf">
+                        <i class="el-icon-upload"></i>
+                        <div class="file-name" v-if="fileName">{{ fileName }}</div>
+                        <div class="upload-text">点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                            点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件点击或拖拽上传文件
+                        </div>
+                    </el-upload>
+                </div>
+            </div>
+        </div>
+        <div style="position:flex;z-index:0; width: 100%; height: 100%;">
+            <div class="image-container">
+                <img id="show_img">
+                <canvas id="show_canvas"></canvas>
+                <canvas id="hide_canvas" style="display: none;"></canvas>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+
+import { ref, onMounted } from 'vue'
+import { useCanvasImgStore } from '../store/CanvasImg';
+import { storeToRefs } from 'pinia'
+import { usePdfProperty } from '../store/PdfProperty';
+
+const fileName = ref("")
+const c_img = useCanvasImgStore();
+const { show_image, show_canvas, hide_canvas, input_file } = storeToRefs(c_img);
+
+onMounted(async () => {
+    show_image.value = document.getElementById("show_img") as HTMLImageElement;
+    show_canvas.value = document.getElementById("show_canvas") as HTMLCanvasElement;
+    hide_canvas.value = document.getElementById("hide_canvas") as HTMLCanvasElement;
+});
+
+const pdf_property = usePdfProperty();
+const { is_pdf, pdf_source } = storeToRefs(pdf_property);
+
+function handleDrop(e: any) {
+    e.preventDefault()
+    console.log('handleDrop')
+    const files = e.dataTransfer.files
+    if (files.length > 0) {
+        const file = files[0]
+        UpdateFile(file)
+    }
+}
+
+const BeforeUpload = (file: File): boolean | Promise<boolean> => {
+    console.log('BeforeUpload')
+    return UpdateFile(file);
+}
+
+function UpdateFile(file: File) {
+    const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
+
+    fileName.value = file.name;
+    if (post_ == ".pdf") {
+        is_pdf.value = true;
+            pdf_source.value = URL.createObjectURL(file);
+    } else if (post_ == ".jpg" || post_ == ".png" || post_ == ".bmp" || post_ == ".jpeg") {
+        is_pdf.value = false
+        if (show_image.value != null && show_canvas.value != null) {
+            show_image.value.src = URL.createObjectURL(file);
+            show_image.value.onload = () => {
+                show_canvas.value.width = show_image.value.width;
+                show_canvas.value.height = show_image.value.height;
+            }
+        }
+        input_file.value = file;
+    }
+    return true;
+}
+</script>
+
+<style scoped lang="less">
+.image-container {
+    position: relative;
+    width: 100%;
+    height: 600px;
+    background-color: gainsboro;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+}
+
+#show_canvas {
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 0;
+    background-color: transparent;
+}
+
+#show_img,
+#res_img {
+    z-index: 0;
+    max-width: 100%;
+    max-height: 100%;
+    display: block;
+    margin: auto;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+.upload-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: #f5f7fa;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.mask {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    border: 2px dashed rgba(0, 0, 0, 0.3);
+}
+
+.upload {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+    background-color: #fff;
+    border-radius: 8px;
+    color: #c0c4cc;
+    font-size: 24px;
+    text-align: center;
+    overflow: hidden;
+    cursor: pointer;
+}
+
+.upload-text {
+    margin-top: 10px;
+}
+
+.file-name {
+    margin-top: 10px;
+    font-size: 16px;
+    text-align: center;
+}
+</style>

BIN
src/dist/assets/dewarp(1)-d610e810.jpg


BIN
src/dist/assets/dewarp(2)-bbfd45cd.jpg


Diff do ficheiro suprimidas por serem muito extensas
+ 95 - 95
src/dist/assets/index-d9a132a3.js


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
src/dist/assets/index-2a05abf2.css


BIN
src/dist/assets/layout_analysis(1)-5d1e538c.png


BIN
src/dist/assets/layout_analysis(3)-e92197e8.png


BIN
src/dist/assets/magic_color(1)-98638402.jpg


BIN
src/dist/assets/magic_color(2)-a2fd0add.jpg


BIN
src/dist/assets/magic_color(3)-fe33af0e.jpg


BIN
src/dist/assets/magic_color(4)-6eb6e914.jpg


BIN
src/dist/assets/magic_color(5)-0fb72a48.jpg


BIN
src/dist/assets/ocr(1)-2bb78629.jpg


BIN
src/dist/assets/ocr(2)-b544c22e.jpg


BIN
src/dist/assets/ocr(3)-eb547f1a.jpg


BIN
src/dist/assets/stamp(1)-0368e961.jpg


BIN
src/dist/assets/stamp(2)-dc818ba4.jpg


BIN
src/dist/assets/stamp(3)-51cc00e5.jpg


BIN
src/dist/assets/table_rec(1)-d43e33d1.png


BIN
src/dist/assets/table_rec(2)-e2b8892f.png


BIN
src/dist/assets/table_rec(3)-cf07e3aa.png


BIN
src/dist/assets/table_rec(4)-cdc99530.png


BIN
src/dist/assets/table_rec(5)-15921616.png


BIN
src/dist/assets/uie(1)-581c7f37.jpg


BIN
src/dist/assets/uie(2)-bac80682.jpg


+ 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-d9a132a3.js"></script>
-    <link rel="stylesheet" href="./assets/index-2a05abf2.css">
+    <script type="module" crossorigin src="./assets/index-937eedb5.js"></script>
+    <link rel="stylesheet" href="./assets/index-99f74905.css">
   </head>
   <body>
     <div id="app"></div>

+ 6 - 2
src/pages/main/views/Detection/LayoutAnalysis.vue

@@ -8,7 +8,7 @@
         <p>目前支持检测图片与表格</p>
       </el-row>
       <el-row>
-        <ShowImage :show-src-image=true   />
+        <ShowImage :show-src-image=true />
       </el-row>
       <el-row style="height: 200px; width: 100%; position: relative;">
         <FileUpload fileFormats="all" :isConvert=false />
@@ -16,10 +16,13 @@
       <el-row style="color: gray; font-size: small;">
         <h4>支持jpg, png, bmp, pdf等文件格式</h4>
       </el-row>
-      <el-row style="position: absolute;">
+      <el-row>
         <PdfPreview />
         <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
       </el-row>
+      <el-row>
+        <ImageList module="layout_analysis" />
+      </el-row>
     </el-col>
     <el-col :span="12" class="place">
       <el-row class="small-title">
@@ -66,6 +69,7 @@ import { usePdfProperty } from '../../../../store/PdfProperty';
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 const si = useServerStore();
 const { server_ip, server_port, api_layout_analysis } = storeToRefs(si);

+ 5 - 1
src/pages/main/views/Detection/StampDetection.vue

@@ -16,10 +16,13 @@
             <el-row style="color: gray; font-size: small;">
                 <h4>支持jpg, png, bmp, pdf等文件格式</h4>
             </el-row>
-            <el-row style="position: absolute;">
+            <el-row>
                 <PdfPreview />
                 <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
             </el-row>
+            <el-row>
+                <ImageList module="stamp" />
+            </el-row>
         </el-col>
         <el-col :span="12" class="place">
             <el-row class="small-title">
@@ -59,6 +62,7 @@ import { usePdfProperty } from '../../../../store/PdfProperty';
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 const si = useServerStore();
 const { server_ip, server_port, api_stamp_detection } = storeToRefs(si);

+ 5 - 1
src/pages/main/views/ImageProcess/dewarp.vue

@@ -16,10 +16,13 @@
             <el-row style="color: gray; font-size: small;">
                 <h4>支持jpg, png, bmp, pdf等文件格式</h4>
             </el-row>
-            <el-row style="position: absolute;">
+            <el-row>
                 <PdfPreview />
                 <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
             </el-row>
+            <el-row>
+                <ImageList module="dewarp" />
+            </el-row>
         </el-col>
         <el-col :span="12" class="place">
             <el-row class="small-title">
@@ -41,6 +44,7 @@ import { ref, onMounted } from 'vue'
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 import { storeToRefs } from 'pinia'
 import { useServerStore } from '../../../../store/Server';

+ 5 - 1
src/pages/main/views/ImageProcess/magicColor.vue

@@ -16,10 +16,13 @@
       <el-row style="color: gray; font-size: small;">
         <h4>支持jpg, png, bmp, pdf等文件格式</h4>
       </el-row>
-      <el-row style="position: absolute;">
+      <el-row>
         <PdfPreview />
         <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
       </el-row>
+      <el-row>
+        <ImageList module="magic_color" />
+      </el-row>
     </el-col>
     <el-col :span="12" class="place">
       <el-row class="small-title">
@@ -41,6 +44,7 @@ import { ref, onMounted } from 'vue'
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 import { storeToRefs } from 'pinia'
 import { useServerStore } from '../../../../store/Server';

+ 156 - 5
src/pages/main/views/NLP/UIEX.vue

@@ -9,23 +9,174 @@
                     后续可根据需求进行定制化训练N-Shot模型,满足0-Shot不能满足的需求。</p>
             </el-row>
             <el-row>
-                <ShowImage :show-src-image=true />
+                <ImageWithUpload />
             </el-row>
             <el-row style="color: gray; font-size: small;">
                 <h4>支持jpg, png, bmp, pdf等文件格式</h4>
             </el-row>
             <PdfPreview />
+            <el-row>
+                <ImageList module="uie" />
+            </el-row>
         </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> -->
+                <h2 style="margin-right: 0;">👉 设置schema</h2>
+            </el-row>
+            <el-row>
+                <p>实体抽取:实体类别之间以';'分割,例如 <strong>人物;组织机构</strong></p>
+            </el-row>
+            <el-row style="margin-bottom: 20px;">
+                关系抽取:需配置主体和关系类别,中间以'|'分割,例如 <strong>人物|出生时间;人物|邮箱</strong>
+            </el-row>
+            <el-row>
+                <div class="container">
+                    <div class="box">
+                        <div class="title">Schema</div>
+                        <div class="content">
+                            <el-input v-model="inputValue" placeholder="请输入文本"></el-input>
+                        </div>
+                        <div class="title">OCR语言</div>
+                        <div class="content">
+                            <el-radio-group v-model="ocrLanguage">
+                                <el-radio :label="1" border>ch</el-radio>
+                                <el-radio :label="2" border>en</el-radio>
+                            </el-radio-group>
+                        </div>
+                    </div>
+                </div>
+            </el-row>
+            <el-row class="twoButton">
+                <el-button type="primary" style="width: 45%;" :loading="loading" @click="ClearInput">Clear</el-button>
+                <el-button type="primary" style="width: 45%;" :loading="loading" @click="Predict">Predict</el-button>
+            </el-row>
+            <el-row v-show="outputValue">
+                <el-card style="width: 100%;">
+                    <el-scrollbar height="600px">
+                        <pre>{{ outputValue }}</pre>>
+                    </el-scrollbar>
+                </el-card>
             </el-row>
         </el-col>
     </el-row>
 </template>
 
 <script setup lang="ts">
-import ShowImage from '../../../../components/ShowImage.vue'
+import ImageWithUpload from '../../../../components/ImageWithUpload.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
-</script>
+import ImageList from '../../../../components/ImageList.vue'
+import { useCanvasImgStore } from '../../../../store/CanvasImg';
+import { useServerStore } from '../../../../store/Server';
+import { storeToRefs } from 'pinia'
+
+import { watchEffect } from 'vue'
+
+import { UIEX } from '../../../../api/api'
+
+
+import { ref } from 'vue'
+
+const uie_textes = ['销售方|名称;销售方|纳税人识别号;购买方|名称;购买方|纳税人识别号;金额;价税合计;开票日期;发票代码;发票号码', 
+                    '姓名;性别;出生地;民族;籍贯;出生日期;宗教信仰;公民身份证件编号;身高;血型;文化程度;婚姻状况;兵役状况;服务处所;职业', 
+                    '', 
+                    '',
+                    '']
+
+const si = useServerStore();
+const { api_uiex } = storeToRefs(si);
+const my_canvas = useCanvasImgStore();
+const { input_file, image_item_index } = storeToRefs(my_canvas);
+
+const inputValue = ref("");
+const outputValue = ref("");
+const ocrLanguage = ref(1);
+let loading = ref(false)
+
+function ClearInput() {
+    inputValue.value = ""
+}
+
+const Predict = async () => {
+    const fileName = input_file.value?.name
+    if (fileName == undefined || fileName == '') {
+        alert('请上传图片!')
+        return;
+    }
+    let ocr_lang: string = 'ch'
+    if (ocrLanguage.value == 2)
+        ocr_lang = 'en'
+
+    var data = new FormData();
+    data.append('image', input_file.value);
+    data.append('lang', ocr_lang);
+    data.append('schema', inputValue.value);
+
+    loading.value = !loading.value;
+    UIEX(api_uiex.value, data).then(res => {
+        loading.value = !loading.value;
+        try {
+            const obj = JSON.parse(res.data.result)
+            outputValue.value = JSON.stringify(obj, null, 2)
+        } catch (e) {
+            outputValue.value = res.data.result
+        }
+    }).catch(err => {
+        console.log(err)
+        loading.value = !loading.value;
+    })
+}
+
+watchEffect(() => {
+    image_item_index.value
+    inputValue.value = uie_textes[image_item_index.value]
+});
+</script>
+
+<style scoped lang="less">
+.small-title {
+    justify-content: space-between;
+    align-items: center;
+}
+
+.page {
+    height: 100%;
+    width: 100%;
+}
+
+.place {
+    margin-right: auto;
+    margin-left: auto;
+    border-right: solid 1px #ccc;
+}
+
+.container {
+    display: flex;
+    justify-content: center;
+    width: 100%;
+}
+
+.box {
+    width: 100%;
+    background-color: #fff;
+    border-radius: 10px;
+    box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.15);
+}
+
+.title {
+    font-size: 12px;
+    font-weight: bold;
+    color: #333;
+    padding: 10px;
+}
+
+.content {
+    padding: 10px;
+    border-bottom: 1px solid #eee;
+}
+
+.twoButton {
+    justify-content: center;
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+</style>

+ 5 - 1
src/pages/main/views/Recognize/ocr.vue

@@ -18,10 +18,13 @@
         <h4>支持jpg, png, bmp, pdf等文件格式</h4>
       </el-row>
       <PdfPreview />
-      <el-row style="position: absolute;">
+      <el-row>
         <OcrLangList />
         <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
       </el-row>
+      <el-row>
+        <ImageList module="ocr"/>
+      </el-row>
     </el-col>
     <el-col :span="12" class="place">
       <el-row class="small-title">
@@ -69,6 +72,7 @@ import OcrLangList from '../../../../components/OcrLangList.vue'
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 const si = useServerStore();
 const { server_ip, server_port, api_ocr } = storeToRefs(si);

+ 5 - 1
src/pages/main/views/Recognize/tableRec.vue

@@ -18,10 +18,13 @@
         <h4>支持jpg, png, bmp, pdf等文件格式</h4>
       </el-row>
       <PdfPreview />
-      <el-row style="position: absolute;">
+      <el-row>
         <OcrLangList />
         <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
       </el-row>
+      <el-row>
+        <ImageList module="table_rec"/>
+      </el-row>
     </el-col>
     <el-col :span="14" class="place">
       <el-row class="small-title">
@@ -71,6 +74,7 @@ import OcrLangList from '../../../../components/OcrLangList.vue'
 import FileUpload from '../../../../components/FileUpload.vue'
 import ShowImage from '../../../../components/ShowImage.vue'
 import PdfPreview from '../../../../components/PdfPreview.vue'
+import ImageList from '../../../../components/ImageList.vue'
 
 const si = useServerStore();
 const { server_ip, server_port, api_table_rec } = storeToRefs(si);

+ 2 - 0
src/store/CanvasImg.ts

@@ -8,6 +8,7 @@ export const useCanvasImgStore = defineStore("canvas_img", () => {
   const hide_canvas: any = ref(null as unknown as HTMLCanvasElement);
   const input_file: any = ref(null as unknown as File);
   const fabric_canvas: any = ref(null);
+  const image_item_index = ref(0)
 
   const reset_images =  () => {
     show_image.value = ''; // 清空 show_image 对象
@@ -25,6 +26,7 @@ export const useCanvasImgStore = defineStore("canvas_img", () => {
     hide_canvas,
     fabric_canvas,
     input_file,
+    image_item_index,
     reset_images
   };
 });

+ 2 - 1
src/store/Server.ts

@@ -16,8 +16,9 @@ export const useServerStore = defineStore('server', () => {
   const api_stamp_detection = ref(tmp_ip + "/v1/detection/detection_stamp")
   const api_pdf_to_word = ref(tmp_ip + "/v1/convert/pdf2word")
   const api_download = ref(tmp_ip + "/download")
+  const api_uiex = ref(tmp_ip + "/v1/nlp/information_extraction")
 
   return { server_ip, server_port, api_dewarp, api_layout_analysis, api_magic_color, api_pdf_to_word,
            api_ocr, api_stamp_detection, api_table_rec, api_build_tag, api_model_info, api_version,
-           api_download }
+           api_download, api_uiex }
 })