Browse Source

更新上传
Signed-off-by: Caner <5658514@qq.com>

Caner 4 years ago
parent
commit
82180bf0c3
7 changed files with 220 additions and 304 deletions
  1. 1 0
      .gitignore
  2. 1 1
      web/index.html
  3. 1 0
      web/package.json
  4. 0 91
      web/src/components/HelloWorld.vue
  5. 205 206
      web/src/pages/index/views/index.vue
  6. 7 6
      web/vite.config.js
  7. 5 0
      web/yarn.lock

+ 1 - 0
.gitignore

@@ -61,3 +61,4 @@ fonts
 jTessBoxEditorFX
 invoice
 20220411_one_line_data_date
+imgs_out_json(1)

+ 1 - 1
web/index.html

@@ -5,7 +5,7 @@
   <meta charset="UTF-8" />
   <link rel="icon" href="/favicon.ico" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  <title>发票识别</title>
+  <title>ImageRecognition</title>
 </head>
 
 <body>

+ 1 - 0
web/package.json

@@ -8,6 +8,7 @@
   },
   "dependencies": {
     "axios": "^0.24.0",
+    "js-image-compressor": "^2.0.0",
     "js-md5": "^0.7.3",
     "view-design": "^4.7.0",
     "vue": "^2.6.14",

+ 0 - 91
web/src/components/HelloWorld.vue

@@ -1,91 +0,0 @@
-<template>
-  <h1>{{ msg }}</h1>
-
-  <p>
-    Recommended IDE setup:
-    <a
-      href="https://code.visualstudio.com/"
-      target="_blank"
-    >VSCode</a>
-    +
-    <a
-      href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
-      target="_blank"
-    >
-      Vetur
-    </a>
-    or
-    <a
-      href="https://github.com/johnsoncodehk/volar"
-      target="_blank"
-    >Volar</a>
-    (if using
-    <code>&lt;script setup&gt;</code>)
-  </p>
-
-  <p>See <code>README.md</code> for more information.</p>
-
-  <p>
-    <a
-      href="https://vitejs.dev/guide/features.html"
-      target="_blank"
-    >
-      Vite Docs
-    </a>
-    |
-    <a
-      href="https://v3.vuejs.org/"
-      target="_blank"
-    >Vue 3 Docs</a>
-  </p>
-
-  <button
-    type="button"
-    @click="count++"
-  >
-    count is: {{ count }}
-  </button>
-  <p>
-    Edit
-    <code>components/HelloWorld.vue</code> to test hot module replacement.
-  </p>
-</template>
-
-<script lang="ts">
-import { ref, defineComponent } from 'vue'
-
-export default defineComponent({
-  name: 'HelloWorld',
-  props: {
-    msg: {
-      type: String,
-      required: true
-    }
-  },
-  setup: () => {
-    const count = ref(0)
-    return { count }
-  },
-  created() {
-    console.log(import.meta.env)
-  }
-})
-</script>
-
-<style scoped>
-a {
-  color: #42b983;
-}
-
-label {
-  margin: 0 0.5em;
-  font-weight: bold;
-}
-
-code {
-  background-color: #eee;
-  padding: 2px 4px;
-  border-radius: 4px;
-  color: #304455;
-}
-</style>

+ 205 - 206
web/src/pages/index/views/index.vue

@@ -1,40 +1,37 @@
 <template>
-  <div class="upload">
-    <div class="bottom">
-      <img
-        v-for="(item, index) in newImg"
-        :key="index"
-        :src="item.url"
-        alt=""
-      />
-      <div class="upinput" v-if="!show">
-        <Icon type="md-reverse-camera" />
-        <input
-          type="file"
-          accept="image/*"
-          multiple
-          @change="selectImg($event)"
-        />
-      </div>
+  <div v-if="!show">
+    <div class="upload">
+      <Icon type="md-reverse-camera" />
+      <form id="psd">
+        <input type="file" accept="image/*" @change="selectImg($event)" />
+      </form>
     </div>
     <div class="content">
-      <span v-if="!table.length">{{ err }}</span>
-      <p v-else  v-for="(item,id) in table" :key="id">{{item.name}}:{{item.num}}</p>
-    </div>
-    <div class="top">
-      <Button type="primary" size="large" @click="save" v-if="!show"
-        >识别</Button
-      >
-    </div>
-    <div class="loading" v-if="show">
-      <div class="spinner"></div>
+      <div class="list">
+        <img
+          v-for="(item, id) in newImg"
+          :key="id + '6s'"
+          :src="item.url"
+          alt=""
+        />
+        <p v-for="(item, id) in table" :key="id">
+          {{ item.name }}:{{ item.num }}
+        </p>
+      </div>
+      <div class="btn">
+        <Button type="primary" @click="save" size="large">开始</Button>
+      </div>
     </div>
   </div>
+  <div class="loading" v-else>
+    <div class="spinner"></div>
+  </div>
 </template>
 <script>
-import { Icon, Button } from "view-design";
+import { Icon, Button, Notice } from "view-design";
 import "view-design/dist/styles/iview.css";
 import axios from "@/utils/axios";
+import ImageCompressor from "js-image-compressor";
 export default {
   components: {
     Icon,
@@ -42,26 +39,46 @@ export default {
   },
   data() {
     return {
-      newImg: [],
       show: false,
-      err: "",
-      table:[]
+      newImg: [],
+      table: [],
     };
   },
   methods: {
-    // 选择图片
+    // 选择多张图片
     selectImg(event) {
       const file = event.target.files;
-      const size = 10485760; //10M
+      const size = 2097152; //2M
       const newArr = [];
       if (file.length > 1) {
-        this.err = "不能超过1张";
+        Notice.warning({
+          desc: "不能超过1张",
+        });
         return;
       }
       for (let j = 0; j < file.length; j++) {
         const el = file[j];
         if (el.size > size) {
-          this.err = el.name + "大小超过限制";
+          Notice.warning({
+            desc: el.name + "大小超过限制将被压缩",
+          });
+          // 压缩
+          new ImageCompressor({
+            file: el,
+            quality: 0.3,
+            mimeType: "image/jpeg",
+            success: (result) => {
+              newArr.push({
+                url: this.getObjectURL(result),
+                data: result,
+              });
+            },
+            error: function (msg) {
+              Notice.warning({
+                desc: "请重新上传",
+              });
+            },
+          });
           continue;
         } else {
           newArr.push({
@@ -71,7 +88,6 @@ export default {
         }
       }
       this.newImg = newArr;
-      this.err = "";
     },
     // 图片临时路径
     getObjectURL(file) {
@@ -88,204 +104,187 @@ export default {
     // 识别
     async save() {
       if (!this.newImg.length) return;
-      this.show = true;
-      const formData = new FormData();
-      formData.append("pic", this.newImg[0].data);
-      const res = await axios.post("/uploadOneInvoicePic", formData);
-      if (res.success) {
-        const newArr = this.setData(res.data.invoice_data.words_result[0].result)
-        this.table = newArr
-      } else {
-        this.err = "识别错误";
-        this.table = []
+      try {
+        this.show = true;
+        const formData = new FormData();
+        formData.append("pic", this.newImg[0].data);
+        const res = await axios.post("/uploadOneInvoicePic", formData);
+        this.table = this.setData(res.data.invoice_data.words_result[0].result);
+        document.getElementById("psd").reset();
+      } catch (error) {
+        Notice.warning({
+          desc: error,
+        });
       }
       this.show = false;
     },
     // 处理数据
     setData(data) {
+      if (!data && !data.length) return [];
       let content = [];
       for (const key in data) {
         content.push({
-          name: this.names(key) || '无',
-          num: data[key].length ? data[key][0].word : ''
-        })
+          name: this.names(key) || "无",
+          num: data[key].length ? data[key][0].word : "",
+        });
       }
-      return content
+      return content;
     },
     // 名词
-    names(key){
-      let name = ''
-        switch (key) {
-          case "AmountInFiguers":
-            name = "合计"
-            break;
-          case "AmountInWords":
-            name = '合计大写'
-            break;
-          case "CheckCode":
-            name = '校验码'
-            break;  
-          case "Checker":
-            name = '复核'
-            break;
-          case "InvoiceCode":
-            name = '发票代码'
-            break;
-          case "InvoiceCodeConfirm":
-            name = '发票代码确认'
-            break;
-          case "InvoiceDate":
-            name = '发票日期'
-            break;
-          case "InvoiceNum":
-            name = '发票编号'
-            break;
-          case "InvoiceNumConfirm":
-            name = '发票编号确认'
-            break;
-          case "NoteDrawer":
-            name = '开票人'
-            break;   
-          case "Payee":
-            name = '收款人'
-            break; 
-          case "PurchaserAddress":
-            name = '买方地址'
-            break; 
-          case "PurchaserBank":
-            name = '买方银行信息'
-            break; 
-          case "PurchaserName":
-            name = '买方名称'
-            break; 
-          case "PurchaserRegisterNum":
-            name = '买方识别号'
-            break; 
-          case "SellerAddress":
-            name = '卖方地址'
-            break; 
-          case "SellerBank":
-            name = '卖方银行信息'
-            break; 
-          case "SellerName":
-            name = '卖方名称'
-            break;   
-          case "SellerRegisterNum":
-            name = '卖方识别号'
-            break;                                                                                                                                                                                                     
-          default:
-            break;
-        }
-      return name
-    }
+    names(key) {
+      let name = "";
+      switch (key) {
+        case "AmountInFiguers":
+          name = "合计";
+          break;
+        case "AmountInWords":
+          name = "合计大写";
+          break;
+        case "CheckCode":
+          name = "校验码";
+          break;
+        case "Checker":
+          name = "复核";
+          break;
+        case "InvoiceCode":
+          name = "发票代码";
+          break;
+        case "InvoiceCodeConfirm":
+          name = "发票代码确认";
+          break;
+        case "InvoiceDate":
+          name = "发票日期";
+          break;
+        case "InvoiceNum":
+          name = "发票编号";
+          break;
+        case "InvoiceNumConfirm":
+          name = "发票编号确认";
+          break;
+        case "NoteDrawer":
+          name = "开票人";
+          break;
+        case "Payee":
+          name = "收款人";
+          break;
+        case "PurchaserAddress":
+          name = "买方地址";
+          break;
+        case "PurchaserBank":
+          name = "买方银行信息";
+          break;
+        case "PurchaserName":
+          name = "买方名称";
+          break;
+        case "PurchaserRegisterNum":
+          name = "买方识别号";
+          break;
+        case "SellerAddress":
+          name = "卖方地址";
+          break;
+        case "SellerBank":
+          name = "卖方银行信息";
+          break;
+        case "SellerName":
+          name = "卖方名称";
+          break;
+        case "SellerRegisterNum":
+          name = "卖方识别号";
+          break;
+        default:
+          break;
+      }
+      return name;
+    },
   },
 };
 </script>
 <style lang="less" scoped>
 .upload {
-  width: 3.5rem;
-  background: rgb(37, 45, 60);
+  width: 0.4rem;
+  height: 0.4rem;
+  overflow: hidden;
+  border: dashed 1px #dcdee2;
+  color: #dcdee2;
+  position: relative;
   margin: 0 auto;
   margin-top: 0.1rem;
-  padding: 0.1rem;
-  overflow-x: hidden;
-  color: #dcdee2;
-  font-size: 0.16rem;
-  .top {
-    text-align: center;
-    padding: 0.2rem 0 0.1rem 0;
+  font-size: 0.2rem;
+  text-align: center;
+  line-height: 0.35rem;
+  input {
+    width: 0.4rem;
+    height: 0.4rem;
+    position: absolute;
+    left: 0;
+    top: 0;
+    opacity: 0;
   }
-  .bottom {
-    display: flex;
-    flex-flow: wrap;
-    max-height: 3rem;
-    overflow-y: auto;
+}
+.content {
+  .list {
+    padding: 0.1rem 0;
+    max-height: 6rem;
+    color: #dcdee2;
+    text-align: center;
+    font-size: 0.16rem;
     overflow-x: hidden;
-    .upinput {
-      border: 1px dashed #dcdee2;
-      overflow: hidden;
-      margin: 0;
-      width: 0.8rem;
-      height: 0.8rem;
-      border-radius: 4px;
-      text-align: center;
-      font-size: 0.3rem;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      position: relative;
-      margin-left: 0.03rem;
-      input {
-        position: absolute;
-        width: 0.8rem;
-        height: 0.8rem;
-        top: 0;
-        left: 0;
-        opacity: 0;
-      }
-    }
+    overflow-y: auto;
     img {
-      width: 0.8rem;
-      height: 0.8rem;
+      max-width: 100%;
+      max-height: 3rem;
       font-size: 0;
-      margin-bottom: 0.03rem;
-      &:not(:nth-child(5n + 1)) {
-        margin-left: 0.03rem;
-      }
     }
   }
-  .content {
-    padding: 0.1rem 0;
-    max-height: 6rem;
-    overflow-y: auto;
-    overflow-x: hidden;
+  .btn {
+    text-align: center;
+    padding-top: 0.1rem;
+  }
+}
+.loading {
+  position: fixed;
+  width: 100vw;
+  height: 100vh;
+  z-index: 96;
+  left: 0;
+  top: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  .spinner {
+    width: 0.4rem;
+    height: 0.4rem;
+    background-color: #dcdee2;
+    margin: 0 auto;
+    -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
+    animation: sk-rotateplane 1.2s infinite ease-in-out;
   }
-  .loading {
-    position: fixed;
-    width: 100vw;
-    height: 100vh;
-    z-index: 96;
-    left: 0;
-    top: 0;
-    background: rgba(0, 0, 0, 0.5);
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    .spinner {
-      width: 0.4rem;
-      height: 0.4rem;
-      background-color: #dcdee2;
-      margin: 0 auto;
-      -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
-      animation: sk-rotateplane 1.2s infinite ease-in-out;
-    }
 
-    @-webkit-keyframes sk-rotateplane {
-      0% {
-        -webkit-transform: perspective(1.2rem);
-      }
-      50% {
-        -webkit-transform: perspective(1.2rem) rotateY(180deg);
-      }
-      100% {
-        -webkit-transform: perspective(1.2rem) rotateY(180deg) rotateX(180deg);
-      }
+  @-webkit-keyframes sk-rotateplane {
+    0% {
+      -webkit-transform: perspective(1.2rem);
+    }
+    50% {
+      -webkit-transform: perspective(1.2rem) rotateY(180deg);
+    }
+    100% {
+      -webkit-transform: perspective(1.2rem) rotateY(180deg) rotateX(180deg);
     }
+  }
 
-    @keyframes sk-rotateplane {
-      0% {
-        transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
-        -webkit-transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
-      }
-      50% {
-        transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
-        -webkit-transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
-      }
-      100% {
-        transform: perspective(1.2rem) rotateX(-180deg) rotateY(-179.9deg);
-        -webkit-transform: perspective(1.2rem) rotateX(-180deg)
-          rotateY(-179.9deg);
-      }
+  @keyframes sk-rotateplane {
+    0% {
+      transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
+      -webkit-transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
+    }
+    50% {
+      transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
+      -webkit-transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
+    }
+    100% {
+      transform: perspective(1.2rem) rotateX(-180deg) rotateY(-179.9deg);
+      -webkit-transform: perspective(1.2rem) rotateX(-180deg) rotateY(-179.9deg);
     }
   }
 }

+ 7 - 6
web/vite.config.js

@@ -58,11 +58,11 @@ export default ({ mode }) => defineConfig({
   build: {
     rollupOptions: {
       input: entryConfig(),
-      output: { //静态资源分类打包
-        chunkFileNames: 'js/[name]-[hash].js',
-        entryFileNames: 'js/[name]-[hash].js',
-        assetFileNames: 'assets/[name]-[hash].[ext]'
-      }
+      // output: { //静态资源分类打包
+      //   chunkFileNames: 'js/[name]-[hash].js',
+      //   entryFileNames: 'js/[name]-[hash].js',
+      //   assetFileNames: 'assets/[name]-[hash].[ext]'
+      // }
     },
     terserOptions: { //去掉打印
       compress: {
@@ -70,10 +70,11 @@ export default ({ mode }) => defineConfig({
         drop_debugger: true,
       },
     },
+    assetsDir:'static'
   },
   define: { //环境变量配置
     'process.env': {
-      'SERVERURL': mode === 'development' ? 'https://ocrserver.caner.top':'https://ocrserver.caner.top'
+      'SERVERURL': mode === 'development' ? 'http://192.168.1.100:5000':''
     }
   }
 })

+ 5 - 0
web/yarn.lock

@@ -1617,6 +1617,11 @@ js-calendar@^1.2.3:
   resolved "https://registry.npmmirror.com/js-calendar/-/js-calendar-1.2.3.tgz#a583b0644b4e695ba394f344d103dbcc7a7a7d3e"
   integrity sha512-dAA1/Zbp4+c5E+ARCVTIuKepXsNLzSYfzvOimiYD4S5eeP9QuplSHLcdhfqFSwyM1o1u6ku6RRRCyaZ0YAjiBw==
 
+js-image-compressor@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/js-image-compressor/-/js-image-compressor-2.0.0.tgz#93ba3f35710189bd5d1fe3e50825117065f0c6f8"
+  integrity sha512-HUhGwVxwLsxXjP7ztQ1CF2iE6X1YRW1lcalJZYfNymPvuO4kK1bbLVeumVDZs6OPDUK1c0BPwhVH/SsRso8Jbw==
+
 js-md5@^0.7.3:
   version "0.7.3"
   resolved "https://registry.npmmirror.com/js-md5/-/js-md5-0.7.3.tgz#b4f2fbb0b327455f598d6727e38ec272cd09c3f2"