|
|
@@ -4,11 +4,11 @@
|
|
|
|
|
|
<!-- 上传区域 -->
|
|
|
<div class="upload-section">
|
|
|
- <div class="upload-item" v-for="(item, index) in uploadList" :key="index">
|
|
|
+ <div class="upload-item" v-for="(item, index) in uploadList" :key="item.field">
|
|
|
<van-uploader
|
|
|
v-model="item.fileList"
|
|
|
:max-count="1"
|
|
|
- :after-read="(file) => handleAfterRead(file, index)"
|
|
|
+ :after-read="(file) => handleAfterRead(file, item, index)"
|
|
|
:deletable="true"
|
|
|
accept="image/*"
|
|
|
:multiple="false"
|
|
|
@@ -53,17 +53,26 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, computed } from 'vue'
|
|
|
-import { showToast } from 'vant'
|
|
|
+import { showToast, showFailToast } from 'vant'
|
|
|
+import { sysFileUploadApi } from '@/services/modules/common'
|
|
|
|
|
|
/** 上传项类型 */
|
|
|
+interface UploadFileItem {
|
|
|
+ url?: string
|
|
|
+ file?: File
|
|
|
+ fileId?: string
|
|
|
+ status?: 'uploading' | 'done' | 'failed'
|
|
|
+ message?: string
|
|
|
+}
|
|
|
+
|
|
|
interface UploadItem {
|
|
|
label: string
|
|
|
- field: string
|
|
|
- fileList: { url: string; file?: File }[]
|
|
|
+ field: 'front' | 'back'
|
|
|
+ fileList: UploadFileItem[]
|
|
|
bg: string
|
|
|
}
|
|
|
|
|
|
-/** 背景图(本地 assets 图片) */
|
|
|
+/** 背景图 */
|
|
|
import frontBg from '@/assets/images/id-front-bg.png'
|
|
|
import backBg from '@/assets/images/id-back-bg.png'
|
|
|
|
|
|
@@ -73,20 +82,64 @@ const uploadList = ref<UploadItem[]>([
|
|
|
{ label: '请上传身份证国徽面', field: 'back', fileList: [], bg: backBg },
|
|
|
])
|
|
|
|
|
|
-/** 图片选择后处理 */
|
|
|
-const handleAfterRead = (file: any, index: number) => {
|
|
|
+/** 上传+OCR识别逻辑 */
|
|
|
+const handleAfterRead = async (file: any, item: UploadItem, index: number) => {
|
|
|
const target = uploadList.value[index]
|
|
|
if (!target) return
|
|
|
- showToast('上传中...')
|
|
|
- setTimeout(() => {
|
|
|
- target.fileList = [
|
|
|
- {
|
|
|
- url: URL.createObjectURL(file.file),
|
|
|
- file: file.file,
|
|
|
- },
|
|
|
- ]
|
|
|
- showToast('上传成功')
|
|
|
- }, 800)
|
|
|
+
|
|
|
+ try {
|
|
|
+ target.fileList = [{ status: 'uploading', message: '上传中...' }]
|
|
|
+ const formData = new FormData()
|
|
|
+ formData.append('file', file.file)
|
|
|
+
|
|
|
+ // 调用上传接口
|
|
|
+ const res = await sysFileUploadApi(formData)
|
|
|
+
|
|
|
+ if (res.code === 0 && res.data?.url) {
|
|
|
+ const baseUrl = import.meta.env.VITE_APP_URL
|
|
|
+ const fullUrl = res.data.url.startsWith('http') ? res.data.url : `${baseUrl}${res.data.url}`
|
|
|
+
|
|
|
+ target.fileList = [{ url: fullUrl, status: 'done', fileId: res.data.fileId }]
|
|
|
+ showToast(`${item.label} 上传成功`)
|
|
|
+
|
|
|
+ // 调用OCR识别
|
|
|
+ const ocrRes = await handleOcrCheck(item.field, res.data.fileId, fullUrl)
|
|
|
+ if (!ocrRes.success) {
|
|
|
+ // OCR 识别失败:清除该图片并提示
|
|
|
+ target.fileList = []
|
|
|
+ showFailToast(`识别${item.label}失败,请重新上传`)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ target.fileList = [{ status: 'failed', message: '上传失败' }]
|
|
|
+ showFailToast(res.msg || '上传失败')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('upload error:', error)
|
|
|
+ target.fileList = [{ status: 'failed', message: '上传异常' }]
|
|
|
+ showFailToast('上传异常,请重试')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 模拟OCR识别接口逻辑(你可以替换成实际API) */
|
|
|
+const handleOcrCheck = async (
|
|
|
+ side: 'front' | 'back',
|
|
|
+ fileId: string,
|
|
|
+ url: string,
|
|
|
+): Promise<{ success: boolean }> => {
|
|
|
+ // 示例:这里可以根据 side 调用不同的 OCR 接口
|
|
|
+ // 例如 front 调用 /ocr/idcard/front back 调用 /ocr/idcard/back
|
|
|
+ try {
|
|
|
+ console.log('识别请求 =>', { side, fileId, url })
|
|
|
+ // 模拟延时识别
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 800))
|
|
|
+
|
|
|
+ // ✅ 模拟成功 / ❌ 模拟失败
|
|
|
+ const success = Math.random() > 0.2 // 80% 成功率示例
|
|
|
+ return { success }
|
|
|
+ } catch (err) {
|
|
|
+ console.error('OCR error', err)
|
|
|
+ return { success: false }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/** 是否完成上传 */
|
|
|
@@ -95,6 +148,15 @@ const isReady = computed(() => uploadList.value.every((item) => item.fileList.le
|
|
|
/** 下一步按钮点击 */
|
|
|
const onNext = () => {
|
|
|
if (!isReady.value) return showToast('请先上传身份证正反面')
|
|
|
+
|
|
|
+ // 拼装最终提交数据
|
|
|
+ const result = uploadList.value.map((item) => ({
|
|
|
+ field: item.field,
|
|
|
+ fileId: item.fileList[0]?.fileId,
|
|
|
+ url: item.fileList[0]?.url,
|
|
|
+ }))
|
|
|
+
|
|
|
+ console.log('提交数据:', result)
|
|
|
showToast('上传完成,进入下一步')
|
|
|
}
|
|
|
</script>
|