index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. <template>
  2. <div v-if="!show">
  3. <div class="upload">
  4. <Icon type="md-reverse-camera" />
  5. <form id="psd">
  6. <input type="file" accept="image/*" @change="selectImg($event)" />
  7. </form>
  8. </div>
  9. <div class="content">
  10. <div class="list">
  11. <img
  12. v-for="(item, id) in newImg"
  13. :key="id + '6s'"
  14. :src="item.url"
  15. alt=""
  16. />
  17. <p v-for="(item, id) in table" :key="id">
  18. {{ item.name }}:{{ item.num }}
  19. </p>
  20. </div>
  21. <div class="btn">
  22. <Button type="primary" @click="save" size="large">开始</Button>
  23. </div>
  24. </div>
  25. </div>
  26. <div class="loading" v-else>
  27. <div class="spinner"></div>
  28. </div>
  29. </template>
  30. <script>
  31. import { Icon, Button, Notice, Message } from "view-design";
  32. import "view-design/dist/styles/iview.css";
  33. import axios from "@/utils/axios";
  34. import ImageCompressor from "js-image-compressor";
  35. export default {
  36. components: {
  37. Icon,
  38. Button,
  39. },
  40. data() {
  41. return {
  42. show: false,
  43. newImg: [],
  44. table: [],
  45. };
  46. },
  47. methods: {
  48. // 选择多张图片
  49. selectImg(event) {
  50. const file = event.target.files;
  51. const size = 2097152; //2M
  52. const newArr = [];
  53. if (file.length > 1) {
  54. Notice.warning({
  55. desc: "不能超过1张",
  56. });
  57. return;
  58. }
  59. for (let j = 0; j < file.length; j++) {
  60. const el = file[j];
  61. if (el.size >= size) {
  62. Notice.warning({
  63. desc: el.name + "大小超过2M限制请重新上传",
  64. });
  65. break;
  66. } else if (el.size >= size * 0.5) {
  67. Notice.warning({
  68. desc: el.name + "大小超过限制将被压缩",
  69. });
  70. // 压缩
  71. new ImageCompressor({
  72. file: el,
  73. quality: 0.3,
  74. mimeType: "image/jpeg",
  75. success: (result) => {
  76. newArr.push({
  77. url: this.getObjectURL(result),
  78. data: result,
  79. });
  80. },
  81. error: function (msg) {
  82. Notice.warning({
  83. desc: "请重新上传",
  84. });
  85. },
  86. });
  87. continue;
  88. } else {
  89. newArr.push({
  90. url: this.getObjectURL(el),
  91. data: el,
  92. });
  93. }
  94. }
  95. this.newImg = newArr;
  96. document.getElementById("psd").reset();
  97. this.table = [];
  98. },
  99. // 图片临时路径
  100. getObjectURL(file) {
  101. var url = null;
  102. if (window.createObjcectURL != undefined) {
  103. url = window.createOjcectURL(file);
  104. } else if (window.URL != undefined) {
  105. url = window.URL.createObjectURL(file);
  106. } else if (window.webkitURL != undefined) {
  107. url = window.webkitURL.createObjectURL(file);
  108. }
  109. return url;
  110. },
  111. // 识别
  112. async save() {
  113. if (!this.newImg.length) return;
  114. const start = Date.now();
  115. try {
  116. this.show = true;
  117. const formData = new FormData();
  118. formData.append("pic", this.newImg[0].data);
  119. const res = await axios.post("/uploadOneInvoicePic", formData);
  120. this.table = this.setData(res.data.invoice_data.words_result[0].result);
  121. } catch (error) {
  122. Notice.warning({
  123. desc: error,
  124. });
  125. }
  126. this.show = false;
  127. const end = Date.now();
  128. Message.info({
  129. content: "识别总用时:" + (start - end) / 1000 + "s",
  130. duration: 5,
  131. });
  132. },
  133. // 处理数据
  134. setData(data) {
  135. if (!data && !data.length) return [];
  136. let content = [];
  137. for (const key in data) {
  138. content.push({
  139. name: this.names(key) || "无",
  140. num: data[key].length ? data[key][0].word : "",
  141. });
  142. }
  143. return content;
  144. },
  145. // 名词
  146. names(key) {
  147. let name = "";
  148. switch (key) {
  149. case "AmountInFiguers":
  150. name = "合计";
  151. break;
  152. case "AmountInWords":
  153. name = "合计大写";
  154. break;
  155. case "CheckCode":
  156. name = "校验码";
  157. break;
  158. case "Checker":
  159. name = "复核";
  160. break;
  161. case "InvoiceCode":
  162. name = "发票代码";
  163. break;
  164. case "InvoiceCodeConfirm":
  165. name = "发票代码确认";
  166. break;
  167. case "InvoiceDate":
  168. name = "发票日期";
  169. break;
  170. case "InvoiceNum":
  171. name = "发票编号";
  172. break;
  173. case "InvoiceNumConfirm":
  174. name = "发票编号确认";
  175. break;
  176. case "NoteDrawer":
  177. name = "开票人";
  178. break;
  179. case "Payee":
  180. name = "收款人";
  181. break;
  182. case "PurchaserAddress":
  183. name = "买方地址";
  184. break;
  185. case "PurchaserBank":
  186. name = "买方银行信息";
  187. break;
  188. case "PurchaserName":
  189. name = "买方名称";
  190. break;
  191. case "PurchaserRegisterNum":
  192. name = "买方识别号";
  193. break;
  194. case "SellerAddress":
  195. name = "卖方地址";
  196. break;
  197. case "SellerBank":
  198. name = "卖方银行信息";
  199. break;
  200. case "SellerName":
  201. name = "卖方名称";
  202. break;
  203. case "SellerRegisterNum":
  204. name = "卖方识别号";
  205. break;
  206. default:
  207. break;
  208. }
  209. return name;
  210. },
  211. },
  212. };
  213. </script>
  214. <style lang="less" scoped>
  215. .upload {
  216. width: 0.4rem;
  217. height: 0.4rem;
  218. overflow: hidden;
  219. border: dashed 1px #dcdee2;
  220. color: #dcdee2;
  221. position: relative;
  222. margin: 0 auto;
  223. margin-top: 0.1rem;
  224. font-size: 0.2rem;
  225. text-align: center;
  226. line-height: 0.35rem;
  227. input {
  228. width: 0.4rem;
  229. height: 0.4rem;
  230. position: absolute;
  231. left: 0;
  232. top: 0;
  233. opacity: 0;
  234. }
  235. }
  236. .content {
  237. .list {
  238. padding: 0.1rem 0;
  239. max-height: 6rem;
  240. color: #dcdee2;
  241. text-align: center;
  242. font-size: 0.16rem;
  243. overflow-x: hidden;
  244. overflow-y: auto;
  245. img {
  246. max-width: 100%;
  247. max-height: 3rem;
  248. font-size: 0;
  249. }
  250. p {
  251. text-align: left;
  252. max-width: 4rem;
  253. margin: 0 auto;
  254. }
  255. }
  256. .btn {
  257. text-align: center;
  258. padding-top: 0.1rem;
  259. }
  260. }
  261. .loading {
  262. position: fixed;
  263. width: 100vw;
  264. height: 100vh;
  265. z-index: 96;
  266. left: 0;
  267. top: 0;
  268. background: rgba(0, 0, 0, 0.5);
  269. display: flex;
  270. justify-content: center;
  271. align-items: center;
  272. .spinner {
  273. width: 0.4rem;
  274. height: 0.4rem;
  275. background-color: #dcdee2;
  276. margin: 0 auto;
  277. -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
  278. animation: sk-rotateplane 1.2s infinite ease-in-out;
  279. }
  280. @-webkit-keyframes sk-rotateplane {
  281. 0% {
  282. -webkit-transform: perspective(1.2rem);
  283. }
  284. 50% {
  285. -webkit-transform: perspective(1.2rem) rotateY(180deg);
  286. }
  287. 100% {
  288. -webkit-transform: perspective(1.2rem) rotateY(180deg) rotateX(180deg);
  289. }
  290. }
  291. @keyframes sk-rotateplane {
  292. 0% {
  293. transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
  294. -webkit-transform: perspective(1.2rem) rotateX(0deg) rotateY(0deg);
  295. }
  296. 50% {
  297. transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
  298. -webkit-transform: perspective(1.2rem) rotateX(-180.1deg) rotateY(0deg);
  299. }
  300. 100% {
  301. transform: perspective(1.2rem) rotateX(-180deg) rotateY(-179.9deg);
  302. -webkit-transform: perspective(1.2rem) rotateX(-180deg) rotateY(-179.9deg);
  303. }
  304. }
  305. }
  306. </style>