- 이미지를 백엔드(/account/ocr/receipt)로 업로드 → Vision 텍스트 → 금액·날짜·상호 파싱 - 업로드 전 이미지 축소(최대 1600px JPEG), Tesseract.js 의존성 제거 - 진행률 표시 제거(인식 중…), 정확도·속도 대폭 개선 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { accountApi } from '@/api/accountApi'
|
||||
import IconBtn from '@/components/ui/IconBtn.vue'
|
||||
import { scanReceipt } from '@/utils/receiptOcr'
|
||||
import { imageToBlob, parseReceiptText } from '@/utils/receiptOcr'
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'
|
||||
|
||||
@@ -59,7 +59,6 @@ const formError = ref(null)
|
||||
// 영수증 OCR (온디바이스)
|
||||
const receiptInput = ref(null)
|
||||
const ocrRunning = ref(false)
|
||||
const ocrProgress = ref(0)
|
||||
const ocrResult = ref(null) // { amount, date, store }
|
||||
async function pickReceipt() {
|
||||
ocrResult.value = null
|
||||
@@ -91,11 +90,12 @@ async function onReceiptFile(e) {
|
||||
}
|
||||
async function runOcr(image) {
|
||||
ocrRunning.value = true
|
||||
ocrProgress.value = 0
|
||||
ocrResult.value = null
|
||||
formError.value = null
|
||||
try {
|
||||
const r = await scanReceipt(image, (p) => (ocrProgress.value = p))
|
||||
const blob = await imageToBlob(image)
|
||||
const { text } = await accountApi.ocrReceipt(blob)
|
||||
const r = parseReceiptText(text)
|
||||
// 추출값이 있을 때만 폼에 채움 (메모는 비어있을 때만)
|
||||
if (r.amount) form.amount = r.amount
|
||||
if (r.date) form.entryDate = r.date
|
||||
@@ -104,8 +104,8 @@ async function runOcr(image) {
|
||||
if (!r.amount && !r.date) {
|
||||
formError.value = '영수증에서 정보를 충분히 인식하지 못했습니다. 직접 입력하거나 더 선명한 사진으로 다시 시도하세요.'
|
||||
}
|
||||
} catch {
|
||||
formError.value = '영수증 인식에 실패했습니다. 다시 시도해 주세요.'
|
||||
} catch (e) {
|
||||
formError.value = e.response?.data?.message || '영수증 인식에 실패했습니다. 다시 시도해 주세요.'
|
||||
} finally {
|
||||
ocrRunning.value = false
|
||||
}
|
||||
@@ -541,7 +541,7 @@ onMounted(async () => {
|
||||
type="button" class="receipt-btn"
|
||||
:disabled="submitting || ocrRunning" @click="pickReceipt"
|
||||
>📷 영수증 스캔</button>
|
||||
<span v-if="ocrRunning" class="receipt-status">인식 중… {{ ocrProgress }}%</span>
|
||||
<span v-if="ocrRunning" class="receipt-status">인식 중…</span>
|
||||
<span v-else-if="ocrResult" class="receipt-status ok">
|
||||
<template v-if="ocrResult.amount">{{ won(ocrResult.amount) }}원</template>
|
||||
<template v-if="ocrResult.date"> · {{ ocrResult.date }}</template>
|
||||
|
||||
Reference in New Issue
Block a user