mg-ocr-invoice 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.es.js +5685 -5598
- package/dist/index.umd.js +35 -35
- package/dist/style.css +1 -1
- package/dist/types/components/InvoiceList/index.vue.d.ts +5 -1
- package/package.json +1 -1
- package/src/components/Invoice/index.vue +11 -2
- package/src/components/InvoiceList/const.ts +2 -2
- package/src/components/InvoiceList/index.vue +141 -24
- package/src/components/OCRInvoice/index.vue +28 -36
|
@@ -4,6 +4,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
4
4
|
listId: {
|
|
5
5
|
required: true;
|
|
6
6
|
type: StringConstructor;
|
|
7
|
+
default: string;
|
|
7
8
|
};
|
|
8
9
|
multiple: {
|
|
9
10
|
required: true;
|
|
@@ -13,6 +14,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
13
14
|
listId: {
|
|
14
15
|
required: true;
|
|
15
16
|
type: StringConstructor;
|
|
17
|
+
default: string;
|
|
16
18
|
};
|
|
17
19
|
multiple: {
|
|
18
20
|
required: true;
|
|
@@ -21,5 +23,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
21
23
|
}>> & {
|
|
22
24
|
onOk?: ((...args: any[]) => any) | undefined;
|
|
23
25
|
onEdit?: ((...args: any[]) => any) | undefined;
|
|
24
|
-
}, {
|
|
26
|
+
}, {
|
|
27
|
+
listId: string;
|
|
28
|
+
}, {}>;
|
|
25
29
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="Invoice">
|
|
3
|
-
<div class="top">
|
|
3
|
+
<div class="top" @click="openPreViewImg">
|
|
4
4
|
<img :src="invoiceData.attachmentLink" alt="" />
|
|
5
5
|
</div>
|
|
6
6
|
<div class="company">
|
|
@@ -114,7 +114,13 @@
|
|
|
114
114
|
import { ref } from 'vue'
|
|
115
115
|
import '@/utils/disableZoom'
|
|
116
116
|
import { __updateInvoice } from '@/api/invoice'
|
|
117
|
-
import {
|
|
117
|
+
import {
|
|
118
|
+
showToast,
|
|
119
|
+
Overlay,
|
|
120
|
+
Loading,
|
|
121
|
+
showFailToast,
|
|
122
|
+
showImagePreview,
|
|
123
|
+
} from 'vant'
|
|
118
124
|
import { ElInputNumber } from 'element-plus'
|
|
119
125
|
const { ids, invoiceData } = defineProps({
|
|
120
126
|
ids: {
|
|
@@ -134,6 +140,9 @@ const showLoading = ref(false)
|
|
|
134
140
|
const close = () => {
|
|
135
141
|
emit('saveSuccess')
|
|
136
142
|
}
|
|
143
|
+
const openPreViewImg = () => {
|
|
144
|
+
showImagePreview([invoiceData.attachmentLink])
|
|
145
|
+
}
|
|
137
146
|
const editFlag = ref(false)
|
|
138
147
|
const submit = async () => {
|
|
139
148
|
if (!editFlag.value) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const const_invoiceStatus: any = {
|
|
2
|
-
invalid: '
|
|
2
|
+
invalid: '异常发票',
|
|
3
3
|
unused: '未使用',
|
|
4
4
|
using: '使用中',
|
|
5
5
|
used: '已使用',
|
|
@@ -8,7 +8,7 @@ export const const_realStatus: any = {
|
|
|
8
8
|
noNeed: '无需验真',
|
|
9
9
|
notCheck: '未验真',
|
|
10
10
|
checked: '已验真',
|
|
11
|
-
checkFail: '
|
|
11
|
+
checkFail: '验真异常',
|
|
12
12
|
}
|
|
13
13
|
export const const_taskStatus: any = {
|
|
14
14
|
init: '初始状态',
|
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="InvoiceList">
|
|
3
|
+
<div class="selectAll">
|
|
4
|
+
<div class="left">已选 {{ selectedLength }}/{{ selectedLengthCount }}</div>
|
|
5
|
+
<div class="right">
|
|
6
|
+
<span>全选</span>
|
|
7
|
+
<input
|
|
8
|
+
type="checkbox"
|
|
9
|
+
@change.self="changeSelectAll"
|
|
10
|
+
v-model="selectedAll"
|
|
11
|
+
@click.stop
|
|
12
|
+
class="checkbox" />
|
|
13
|
+
<!-- <Checkbox
|
|
14
|
+
@change.self="changeSelectAll"
|
|
15
|
+
v-model="selectedAll"
|
|
16
|
+
@click.stop
|
|
17
|
+
icon-size="22px"></Checkbox> -->
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
3
21
|
<div class="card">
|
|
4
22
|
<ul>
|
|
5
23
|
<li
|
|
6
24
|
v-for="(item, index) in list"
|
|
7
25
|
:key="index"
|
|
8
|
-
@click="
|
|
26
|
+
@click="clickItem(item)">
|
|
9
27
|
<div class="li">
|
|
10
28
|
<div
|
|
11
29
|
class="item-card"
|
|
12
30
|
v-if="
|
|
13
31
|
item.taskStatus === 'finish' || item.taskStatus === 'repeat'
|
|
14
32
|
">
|
|
33
|
+
<div class="details-btn" @click.stop="openDetails(item)">
|
|
34
|
+
详情
|
|
35
|
+
</div>
|
|
15
36
|
<div
|
|
16
37
|
class="title"
|
|
17
38
|
:class="{ person: item.invoiceCompanyType === '公司' }">
|
|
@@ -21,7 +42,7 @@
|
|
|
21
42
|
<div class="name">
|
|
22
43
|
<div class="left">{{ item.sellerName }}</div>
|
|
23
44
|
<div class="right" v-if="item.taskStatus === 'repeat'">
|
|
24
|
-
|
|
45
|
+
已收录
|
|
25
46
|
</div>
|
|
26
47
|
</div>
|
|
27
48
|
<div class="tags">
|
|
@@ -59,10 +80,13 @@
|
|
|
59
80
|
</div>
|
|
60
81
|
</div>
|
|
61
82
|
<div class="rightCheckbox">
|
|
62
|
-
<
|
|
83
|
+
<input
|
|
63
84
|
@click.stop
|
|
85
|
+
type="checkbox"
|
|
86
|
+
class="checkbox"
|
|
87
|
+
@change="changeItemCheckbox"
|
|
64
88
|
v-model="item.selected"
|
|
65
|
-
icon-size="22px"
|
|
89
|
+
icon-size="22px" />
|
|
66
90
|
</div>
|
|
67
91
|
</div>
|
|
68
92
|
</div>
|
|
@@ -83,7 +107,7 @@
|
|
|
83
107
|
<Skeleton :loading="true" title :row="6"></Skeleton>
|
|
84
108
|
</div>
|
|
85
109
|
<div class="err-card" v-else>
|
|
86
|
-
<div class="left-img">
|
|
110
|
+
<div class="left-img" @click="openErrImg(item.fileUrlKey)">
|
|
87
111
|
<img :src="item.fileUrlKey" alt="" />
|
|
88
112
|
</div>
|
|
89
113
|
<div class="right-errText">
|
|
@@ -94,10 +118,11 @@
|
|
|
94
118
|
<p>可以重新拍照识别,或手动添加信息导入</p>
|
|
95
119
|
</div>
|
|
96
120
|
<div>
|
|
97
|
-
<
|
|
121
|
+
<input
|
|
122
|
+
type="checkbox"
|
|
123
|
+
class="checkbox"
|
|
98
124
|
@click.stop
|
|
99
|
-
v-model="item.selected"
|
|
100
|
-
icon-size="22px"></Checkbox>
|
|
125
|
+
v-model="item.selected" />
|
|
101
126
|
</div>
|
|
102
127
|
</div>
|
|
103
128
|
</div>
|
|
@@ -135,13 +160,12 @@
|
|
|
135
160
|
<Loading class="loading" color="#0094ff">上传中...</Loading>
|
|
136
161
|
</Overlay>
|
|
137
162
|
</template>
|
|
138
|
-
<!--
|
|
163
|
+
<!-- 异常发票, 已使用的, 使用中的, 识别失败 禁止提交 -->
|
|
139
164
|
<script setup lang="ts">
|
|
140
165
|
import 'vant/lib/index.css'
|
|
141
166
|
import { ref, onMounted, computed } from 'vue'
|
|
142
167
|
import {
|
|
143
168
|
Popup,
|
|
144
|
-
Checkbox,
|
|
145
169
|
Skeleton,
|
|
146
170
|
Loading,
|
|
147
171
|
showToast,
|
|
@@ -161,14 +185,14 @@ import {
|
|
|
161
185
|
const_taskStatus,
|
|
162
186
|
setClass,
|
|
163
187
|
} from './const'
|
|
164
|
-
|
|
188
|
+
import { showImagePreview } from 'vant'
|
|
165
189
|
// console.log(addNumber('495.28', '29.72'))
|
|
166
190
|
const emit = defineEmits(['edit', 'ok'])
|
|
167
191
|
const { listId, multiple } = defineProps({
|
|
168
192
|
listId: {
|
|
169
193
|
required: true,
|
|
170
194
|
type: String,
|
|
171
|
-
|
|
195
|
+
default: '1690918419274137620',
|
|
172
196
|
},
|
|
173
197
|
multiple: {
|
|
174
198
|
required: true,
|
|
@@ -186,7 +210,8 @@ const selectId = computed(() => {
|
|
|
186
210
|
const getList = async () => {
|
|
187
211
|
return new Promise(async (resolve, reject) => {
|
|
188
212
|
const data: any = {}
|
|
189
|
-
data.batchId = listId
|
|
213
|
+
data.batchId = listId || '1691015132836003840'
|
|
214
|
+
if (!data.batchId) return
|
|
190
215
|
try {
|
|
191
216
|
const res: any = await __getUploadInvoiceList(data, token.value)
|
|
192
217
|
if (res.code === 200) {
|
|
@@ -205,7 +230,9 @@ const getList = async () => {
|
|
|
205
230
|
}
|
|
206
231
|
})
|
|
207
232
|
}
|
|
208
|
-
|
|
233
|
+
const clickItem = (row: any) => {
|
|
234
|
+
row.selected = !row.selected
|
|
235
|
+
}
|
|
209
236
|
const openDetails = (row: any) => {
|
|
210
237
|
if (row.taskStatus !== 'finish' && row.taskStatus !== 'repeat') {
|
|
211
238
|
return
|
|
@@ -219,6 +246,33 @@ const openDetails = (row: any) => {
|
|
|
219
246
|
row
|
|
220
247
|
)
|
|
221
248
|
}
|
|
249
|
+
const everyStatus = (item: any) => {
|
|
250
|
+
return (
|
|
251
|
+
item.invoiceStatus === 'unused' &&
|
|
252
|
+
(item.taskStatus === 'ocr_success' ||
|
|
253
|
+
item.taskStatus === 'repeat' ||
|
|
254
|
+
item.taskStatus === 'finish' ||
|
|
255
|
+
item.invoiceStatus === 'invalid' ||
|
|
256
|
+
item.invoiceStatus === 'invalid' ||
|
|
257
|
+
item.invoiceStatus === 'used' ||
|
|
258
|
+
item.realStatus === 'noNeed' ||
|
|
259
|
+
item.realStatus === 'notCheck' ||
|
|
260
|
+
item.realStatus === 'checked' ||
|
|
261
|
+
item.realStatus === 'checkFail')
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
const selectedAll: any = ref(false)
|
|
265
|
+
const changeSelectAll = (v: any) => {
|
|
266
|
+
list.value.forEach((item) => {
|
|
267
|
+
item.selected = everyStatus(item) && selectedAll.value
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
const changeItemCheckbox = () => {
|
|
271
|
+
const status = list.value
|
|
272
|
+
.filter((item) => everyStatus(item))
|
|
273
|
+
.every((item) => item.selected)
|
|
274
|
+
selectedAll.value = status
|
|
275
|
+
}
|
|
222
276
|
const deleteSelectItem = () => {
|
|
223
277
|
if (selectId.value.length <= 0) {
|
|
224
278
|
showToast({ type: 'text', message: '请先选择发票' })
|
|
@@ -276,23 +330,37 @@ const submitBtn = computed(() => {
|
|
|
276
330
|
const flag = list.value
|
|
277
331
|
.filter((item) => item.selected)
|
|
278
332
|
.every((item) => {
|
|
279
|
-
return (
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
333
|
+
return everyStatus(item)
|
|
334
|
+
// item.invoiceStatus === 'unused' &&
|
|
335
|
+
// (item.taskStatus === 'ocr_success' ||
|
|
336
|
+
// item.taskStatus === 'repeat' ||
|
|
337
|
+
// item.taskStatus === 'finish' ||
|
|
338
|
+
// item.invoiceStatus === 'invalid' ||
|
|
339
|
+
// item.invoiceStatus === 'invalid' ||
|
|
340
|
+
// item.invoiceStatus === 'used' ||
|
|
341
|
+
// item.realStatus === 'noNeed' ||
|
|
342
|
+
// item.realStatus === 'notCheck' ||
|
|
343
|
+
// item.realStatus === 'checked' ||
|
|
344
|
+
// item.realStatus === 'checkFail')
|
|
285
345
|
})
|
|
286
346
|
return flag && list.value.filter((item) => item.selected).length > 0
|
|
287
347
|
})
|
|
288
|
-
|
|
348
|
+
const selectedLength = computed(() => {
|
|
349
|
+
return list.value.filter((item) => item.selected && everyStatus(item)).length
|
|
350
|
+
})
|
|
351
|
+
const selectedLengthCount = computed(() => {
|
|
352
|
+
return list.value.filter((item) => everyStatus(item)).length
|
|
353
|
+
})
|
|
354
|
+
const openErrImg = (url: any) => {
|
|
355
|
+
showImagePreview([url])
|
|
356
|
+
}
|
|
289
357
|
const ok = () => {
|
|
290
358
|
if (selectId.value.length <= 0) {
|
|
291
359
|
showToast({ type: 'text', message: '请先选择发票' })
|
|
292
360
|
return
|
|
293
361
|
}
|
|
294
362
|
if (!submitBtn.value) {
|
|
295
|
-
showToast({ type: 'text', message: '
|
|
363
|
+
showToast({ type: 'text', message: '存在异常发票,无法提交' })
|
|
296
364
|
return
|
|
297
365
|
}
|
|
298
366
|
// showDeleteBtn.value = false
|
|
@@ -329,12 +397,25 @@ onMounted(() => {
|
|
|
329
397
|
padding-bottom: 100px;
|
|
330
398
|
position: relative;
|
|
331
399
|
width: 100%;
|
|
332
|
-
min-height:
|
|
400
|
+
min-height: 100vh;
|
|
333
401
|
background-color: #f3f4f6;
|
|
402
|
+
.selectAll {
|
|
403
|
+
background-color: #f3f4f6;
|
|
404
|
+
position: sticky;
|
|
405
|
+
top: 0;
|
|
406
|
+
z-index: 999;
|
|
407
|
+
padding: 12px;
|
|
408
|
+
display: flex;
|
|
409
|
+
justify-content: space-between;
|
|
410
|
+
.right {
|
|
411
|
+
display: flex;
|
|
412
|
+
gap: 5px;
|
|
413
|
+
padding-right: 12px;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
334
416
|
.card {
|
|
335
417
|
width: 100%;
|
|
336
418
|
ul {
|
|
337
|
-
padding-top: 12px;
|
|
338
419
|
display: flex;
|
|
339
420
|
flex-direction: column;
|
|
340
421
|
gap: 12px;
|
|
@@ -346,11 +427,24 @@ onMounted(() => {
|
|
|
346
427
|
align-items: center;
|
|
347
428
|
gap: 12px;
|
|
348
429
|
overflow: hidden;
|
|
430
|
+
|
|
349
431
|
.item-card {
|
|
350
432
|
flex: 1;
|
|
433
|
+
position: relative;
|
|
434
|
+
|
|
351
435
|
background-color: #fff;
|
|
352
436
|
padding-bottom: 20px;
|
|
353
437
|
min-width: 100%;
|
|
438
|
+
.details-btn {
|
|
439
|
+
position: absolute;
|
|
440
|
+
bottom: 12px;
|
|
441
|
+
right: 9px;
|
|
442
|
+
border: 1px solid #dcdee0;
|
|
443
|
+
padding: 4px 16px;
|
|
444
|
+
font-size: 14px;
|
|
445
|
+
color: #333;
|
|
446
|
+
border-radius: 2px;
|
|
447
|
+
}
|
|
354
448
|
div.person {
|
|
355
449
|
background-color: #ff8b26;
|
|
356
450
|
}
|
|
@@ -590,4 +684,27 @@ onMounted(() => {
|
|
|
590
684
|
}
|
|
591
685
|
}
|
|
592
686
|
}
|
|
687
|
+
|
|
688
|
+
/* 重置复选框的默认样式 */
|
|
689
|
+
.checkbox {
|
|
690
|
+
appearance: none; /* 去除默认外观 */
|
|
691
|
+
-webkit-appearance: none;
|
|
692
|
+
-moz-appearance: none;
|
|
693
|
+
display: inline-block;
|
|
694
|
+
width: 22px;
|
|
695
|
+
height: 22px;
|
|
696
|
+
border: 1px solid #c9cacd; /* 边框宽度和颜色 */
|
|
697
|
+
border-radius: 50%; /* 使复选框成为圆形 */
|
|
698
|
+
outline: none; /* 去除点击时的边框 */
|
|
699
|
+
cursor: pointer;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/* 根据复选框的选中状态设置颜色 */
|
|
703
|
+
.checkbox:checked {
|
|
704
|
+
width: 22px;
|
|
705
|
+
height: 22px;
|
|
706
|
+
background: url('@/assets/xuanzhong@2x.png') no-repeat center;
|
|
707
|
+
background-size: 110%;
|
|
708
|
+
border: none;
|
|
709
|
+
}
|
|
593
710
|
</style>
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="OCRInvoice">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
<div v-if="activePage === 1" class="box">
|
|
4
|
+
<PaymentMode
|
|
5
|
+
:batchId="batchId"
|
|
6
|
+
:multiple="multiple"
|
|
7
|
+
@uploadSuccess="uploadSuccess"></PaymentMode>
|
|
8
|
+
</div>
|
|
9
|
+
<div v-if="activePage === 2" class="box">
|
|
10
|
+
<InvoiceList
|
|
11
|
+
:multiple="multiple"
|
|
12
|
+
:listId="listId"
|
|
13
|
+
@ok="submit"
|
|
14
|
+
@edit="edit">
|
|
15
|
+
</InvoiceList>
|
|
16
|
+
</div>
|
|
17
|
+
<div v-if="activePage === 3" class="box">
|
|
18
|
+
<Invoice
|
|
19
|
+
@saveSuccess="saveSuccess"
|
|
20
|
+
:ids="ids"
|
|
21
|
+
:invoiceData="invoiceData"></Invoice>
|
|
22
|
+
</div>
|
|
20
23
|
</div>
|
|
21
24
|
</template>
|
|
22
25
|
<script lang="ts" setup>
|
|
@@ -54,28 +57,13 @@ const { token, multiple, Base_URL, OCR_AuthDomain, batchId } = defineProps({
|
|
|
54
57
|
required: false,
|
|
55
58
|
},
|
|
56
59
|
})
|
|
57
|
-
|
|
58
|
-
'z7v5gIDRD-sMhb9lRaspBmrWU8y--e5YK2xqWxMCIMTqBReMcoHNTJQ3XyNBdHmLVHiwommCp-HtP4wWSiK9oZDwTWvCW9CZswjLNNL4nGM'
|
|
60
|
+
|
|
59
61
|
const initToken = () => {
|
|
60
|
-
activePage.value =
|
|
62
|
+
activePage.value = 2
|
|
61
63
|
const params = getUrlParams(window.location.href)
|
|
62
64
|
const linkToken = params.token
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// type: 'fail',
|
|
66
|
-
// message: '请在URL拼接token或者组件传递token',
|
|
67
|
-
// duration: 0,
|
|
68
|
-
// })
|
|
69
|
-
sessionStorage.setItem('token', tempToken)
|
|
70
|
-
} else {
|
|
71
|
-
sessionStorage.setItem(
|
|
72
|
-
'token',
|
|
73
|
-
linkToken ||
|
|
74
|
-
token ||
|
|
75
|
-
'z7v5gIDRD-tZIqYE1f7is2aWk6u0y6RCK2xqWxMCIMTqBReMcoHNTJQ3XyNBdHmLVHiwommCp-HtP4wWSiK9oZDwTWvCW9CZswjLNNL4nGM'
|
|
76
|
-
)
|
|
77
|
-
activePage.value = 1
|
|
78
|
-
}
|
|
65
|
+
Cookies.set('token', linkToken || token)
|
|
66
|
+
;('1690993442433269760')
|
|
79
67
|
}
|
|
80
68
|
const init_Base_URL = () => {
|
|
81
69
|
const params = getUrlParams(window.location.href)
|
|
@@ -113,5 +101,9 @@ onMounted(() => {
|
|
|
113
101
|
.OCRInvoice {
|
|
114
102
|
width: 100%;
|
|
115
103
|
height: 100%;
|
|
104
|
+
.box {
|
|
105
|
+
width: 100%;
|
|
106
|
+
min-height: 100%;
|
|
107
|
+
}
|
|
116
108
|
}
|
|
117
109
|
</style>
|