Bläddra i källkod

新增上传功能

yuanmingze 3 månader sedan
förälder
incheckning
743f105f4b

+ 9 - 0
src/services/modules/common/index.ts

@@ -0,0 +1,9 @@
+import http from '../../index'
+import type { UploadRequest } from './type.d'
+
+export const sysFileUploadApi = (data: UploadRequest) => {
+  return http.post({
+    url: '/admin/sys-file/upload',
+    data,
+  })
+}

+ 1 - 0
src/services/modules/common/type.d.ts

@@ -0,0 +1 @@
+export type UploadRequest = FormData | { file: File | string }

+ 80 - 18
src/views/identity-upload/index.vue

@@ -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>