add id card ocr api
This commit is contained in:
parent
167916057e
commit
faba34294a
|
|
@ -93,26 +93,26 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="formData.qrCode">
|
<div v-if="formData.qrCode">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-base text-gray-800 mb-1 font-bold">您已成功领取喜礼</h3>
|
<h3 class="text-base text-gray-800 mb-1 font-bold">您已成功领取喜礼</h3>
|
||||||
<span class="text-sm text-gray-600">下面是您的专属核销二维码,请在领取站点出示给工作人员扫码核销。</span>
|
<span class="text-sm text-gray-600">下面是您的专属核销二维码,请在领取站点出示给工作人员扫码核销。</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex flex-col items-center">
|
<div class="mt-4 flex flex-col items-center">
|
||||||
<div class="flex justify-center items-center relative h-[210px] w-[210px]" ref="qrCodeWrapper">
|
<div class="flex justify-center items-center relative h-[210px] w-[210px]" ref="qrCodeWrapper">
|
||||||
<div v-if="formData.status == 1"
|
<div v-if="formData.status == 1"
|
||||||
class="h-[210px] w-[210px] bg-white/90 rounded-md flex justify-center items-center absolute z-10">
|
class="h-[210px] w-[210px] bg-white/90 rounded-md flex justify-center items-center absolute z-10">
|
||||||
<span class="text-[#E8424D] text-lg font-bold">二维码已核销</span>
|
<span class="text-[#E8424D] text-lg font-bold">二维码已核销</span>
|
||||||
</div>
|
</div>
|
||||||
<qrcode-vue class="absolute opacity-0 pointer-events-none" :value="formData.qrCode" :size="200"
|
<qrcode-vue class="absolute opacity-0 pointer-events-none" :value="formData.qrCode" :size="200"
|
||||||
level="H" render-as="canvas" />
|
level="H" render-as="canvas" />
|
||||||
<img v-if="qrImageSrc" :src="qrImageSrc" alt="核销二维码"
|
<img v-if="qrImageSrc" :src="qrImageSrc" alt="核销二维码"
|
||||||
class="h-[210px] w-[210px] rounded-md shadow-[0_10px_24px_rgba(232,66,77,0.18)] bg-white object-contain" />
|
class="h-[210px] w-[210px] rounded-md shadow-[0_10px_24px_rgba(232,66,77,0.18)] bg-white object-contain" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-xs text-gray-500">长按二维码保存至相册</div>
|
<div class="mt-3 text-xs text-gray-500">长按二维码保存至相册</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="activityInfo.status === 2">
|
<div v-if="activityInfo.status === 2">
|
||||||
<!-- 活动结束状态 -->
|
<!-- 活动结束状态 -->
|
||||||
|
|
@ -204,32 +204,32 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import apiService from '../../services/apiService'
|
import apiService from '../../services/apiService'
|
||||||
import { ref, onMounted, nextTick } from 'vue'
|
import { ref, onMounted, nextTick } from 'vue'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import { showLoading, hideLoading } from '../../components/loading'
|
import { showLoading, hideLoading } from '../../components/loading'
|
||||||
import { showDialog } from 'vant';
|
import { showDialog } from 'vant';
|
||||||
import 'vant/es/dialog/style';
|
import 'vant/es/dialog/style';
|
||||||
|
|
||||||
const ocrUploadId = ref<HTMLInputElement>();
|
const ocrUploadId = ref<HTMLInputElement>();
|
||||||
const qrCodeWrapper = ref<HTMLDivElement | null>(null);
|
const qrCodeWrapper = ref<HTMLDivElement | null>(null);
|
||||||
const qrImageSrc = ref('');
|
const qrImageSrc = ref('');
|
||||||
|
|
||||||
const syncQrImage = () => {
|
const syncQrImage = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const canvas = qrCodeWrapper.value?.querySelector('canvas') as HTMLCanvasElement | null;
|
const canvas = qrCodeWrapper.value?.querySelector('canvas') as HTMLCanvasElement | null;
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
qrImageSrc.value = '';
|
qrImageSrc.value = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
qrImageSrc.value = canvas.toDataURL('image/png');
|
qrImageSrc.value = canvas.toDataURL('image/png');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('生成二维码图片失败:', error);
|
console.error('生成二维码图片失败:', error);
|
||||||
qrImageSrc.value = '';
|
qrImageSrc.value = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
|
|
@ -296,15 +296,15 @@ const clearPhone = () => {
|
||||||
formData.value.marriageNo = '';
|
formData.value.marriageNo = '';
|
||||||
formData.value.husbandName = '';
|
formData.value.husbandName = '';
|
||||||
formData.value.wifeName = '';
|
formData.value.wifeName = '';
|
||||||
formData.value.registerDate = '';
|
formData.value.registerDate = '';
|
||||||
formData.value.qrCode = '';
|
formData.value.qrCode = '';
|
||||||
formData.value.status = 0;
|
formData.value.status = 0;
|
||||||
qrImageSrc.value = '';
|
qrImageSrc.value = '';
|
||||||
countdown.value = 0;
|
countdown.value = 0;
|
||||||
if (countdownTimer) {
|
if (countdownTimer) {
|
||||||
clearInterval(countdownTimer);
|
clearInterval(countdownTimer);
|
||||||
countdownTimer = null;
|
countdownTimer = null;
|
||||||
}
|
}
|
||||||
localStorage.removeItem('userAs');
|
localStorage.removeItem('userAs');
|
||||||
if (ocrUploadId.value) ocrUploadId.value.value = '';
|
if (ocrUploadId.value) ocrUploadId.value.value = '';
|
||||||
}
|
}
|
||||||
|
|
@ -373,34 +373,34 @@ const verifyCode = (flag: any) => {
|
||||||
mobile: formData.value.phone,
|
mobile: formData.value.phone,
|
||||||
smsCode: smsCode,
|
smsCode: smsCode,
|
||||||
type: 3,
|
type: 3,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
localStorage.setItem('userAs', JSON.stringify({
|
localStorage.setItem('userAs', JSON.stringify({
|
||||||
phone: formData.value.phone,
|
phone: formData.value.phone,
|
||||||
smsCode: formData.value.smsCode,
|
smsCode: formData.value.smsCode,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
formData.value.verifyCode = true;
|
formData.value.verifyCode = true;
|
||||||
|
|
||||||
// 验证成功后重置倒计时
|
// 验证成功后重置倒计时
|
||||||
countdown.value = 0;
|
countdown.value = 0;
|
||||||
|
|
||||||
// 验证成功如果有二维码,保存到表单
|
// 验证成功如果有二维码,保存到表单
|
||||||
if (res?.data?.code) {
|
if (res?.data?.code) {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
...formData.value,
|
...formData.value,
|
||||||
qrCode: res.data.code,
|
qrCode: res.data.code,
|
||||||
status: res.data.status,
|
status: res.data.status,
|
||||||
}
|
}
|
||||||
syncQrImage();
|
syncQrImage();
|
||||||
} else {
|
} else {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
...formData.value,
|
...formData.value,
|
||||||
marriageNo: "",
|
marriageNo: "",
|
||||||
husbandName: "",
|
husbandName: "",
|
||||||
wifeName: "",
|
wifeName: "",
|
||||||
registerDate: "",
|
registerDate: "",
|
||||||
qrCode: ""
|
qrCode: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
localStorage.removeItem('userAs');
|
localStorage.removeItem('userAs');
|
||||||
|
|
@ -408,21 +408,21 @@ const verifyCode = (flag: any) => {
|
||||||
flag && showDialog({
|
flag && showDialog({
|
||||||
message: error.msg || '验证码验证失败,请重试',
|
message: error.msg || '验证码验证失败,请重试',
|
||||||
});
|
});
|
||||||
formData.value = {
|
formData.value = {
|
||||||
...formData.value,
|
...formData.value,
|
||||||
smsCode: "",
|
smsCode: "",
|
||||||
marriageNo: "",
|
marriageNo: "",
|
||||||
husbandName: "",
|
husbandName: "",
|
||||||
wifeName: "",
|
wifeName: "",
|
||||||
registerDate: "",
|
registerDate: "",
|
||||||
qrCode: ""
|
qrCode: ""
|
||||||
}
|
}
|
||||||
qrImageSrc.value = '';
|
qrImageSrc.value = '';
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 重置结婚证信息
|
// 重置结婚证信息
|
||||||
function resetMarriageInfo() {
|
function resetMarriageInfo() {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
...formData.value,
|
...formData.value,
|
||||||
|
|
@ -456,7 +456,7 @@ const handleImageChange = () => {
|
||||||
|
|
||||||
showLoading();
|
showLoading();
|
||||||
apiService.uploadOcrImage(formFormData).then((response: any) => {
|
apiService.uploadOcrImage(formFormData).then((response: any) => {
|
||||||
apiService.parseOcrInfo({
|
apiService.marriageParseOcrInfo({
|
||||||
mobile: formData.value.phone,
|
mobile: formData.value.phone,
|
||||||
smsCode: formData.value.smsCode,
|
smsCode: formData.value.smsCode,
|
||||||
uploadId: response.data.uploadId,
|
uploadId: response.data.uploadId,
|
||||||
|
|
@ -492,11 +492,11 @@ const handleImageChange = () => {
|
||||||
|
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
if (!formData.value.phone || !formData.value.smsCode) {
|
if (!formData.value.phone || !formData.value.smsCode) {
|
||||||
showDialog({
|
showDialog({
|
||||||
message: '请完善所有信息',
|
message: '请完善所有信息',
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,22 +506,22 @@ const submitForm = () => {
|
||||||
receiveName: formData.value.husbandName,
|
receiveName: formData.value.husbandName,
|
||||||
receiveMobile: formData.value.phone,
|
receiveMobile: formData.value.phone,
|
||||||
smsCode: formData.value.smsCode,
|
smsCode: formData.value.smsCode,
|
||||||
}).then((res: any) => {
|
}).then((res: any) => {
|
||||||
formData.value.qrCode = res.data.code;
|
formData.value.qrCode = res.data.code;
|
||||||
syncQrImage();
|
syncQrImage();
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
showDialog({
|
showDialog({
|
||||||
message: error?.msg || '提交失败,请稍后重试',
|
message: error?.msg || '提交失败,请稍后重试',
|
||||||
});
|
});
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件卸载时清理定时器
|
// 组件卸载时清理定时器
|
||||||
import { onUnmounted } from 'vue'
|
import { onUnmounted } from 'vue'
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (countdownTimer) {
|
if (countdownTimer) {
|
||||||
clearInterval(countdownTimer)
|
clearInterval(countdownTimer)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,53 @@ export interface OcrUploadResponse {
|
||||||
uploadId: string
|
uploadId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OcrParseResponse {
|
export interface IdCardOcrParseResponse {
|
||||||
raw: string
|
raw: string
|
||||||
words: string[]
|
words: string[]
|
||||||
parsed: {
|
parsed: {
|
||||||
marriageNo: string
|
birthday?: string
|
||||||
husbandName: string
|
id_number: string
|
||||||
wifeName: string
|
address: string
|
||||||
registerDate: string
|
image_status:
|
||||||
|
| 'normal'
|
||||||
|
| 'reversed_side'
|
||||||
|
| 'non_idcard'
|
||||||
|
| 'blurred'
|
||||||
|
| 'other_type_card'
|
||||||
|
| 'over_exposure'
|
||||||
|
| 'over_dark'
|
||||||
|
| 'unknown'
|
||||||
|
risk_type:
|
||||||
|
| 'normal'
|
||||||
|
| 'copy'
|
||||||
|
| 'scan'
|
||||||
|
| 'temporary'
|
||||||
|
| 'screen'
|
||||||
|
| 'screenshot'
|
||||||
|
| 'unknown'
|
||||||
|
gender: '男' | '女' | '未知' | null | undefined
|
||||||
|
name?: string
|
||||||
|
nationality?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarriageOcrParseResponse {
|
||||||
|
raw: string
|
||||||
|
words: string[]
|
||||||
|
parsed: {
|
||||||
|
marriageNo?: string
|
||||||
|
registerDate?: string
|
||||||
|
certificateHolder?: string
|
||||||
|
wifeId?: string
|
||||||
|
wifeName?: string
|
||||||
|
wifeBirthDate?: string
|
||||||
|
wifeNationality?: string
|
||||||
|
wifeGender?: '男' | '女' | '未知' | null | undefined
|
||||||
|
husbandId?: string
|
||||||
|
husbandName?: string
|
||||||
|
husbandGender?: '男' | '女' | '未知' | null | undefined
|
||||||
|
husbandBirthDate?: string
|
||||||
|
husbandNationality?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,12 +125,21 @@ export const apiService = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// OCR识别并返回证件信息
|
// OCR识别并返回证件信息
|
||||||
parseOcrInfo(data: {
|
marriageParseOcrInfo(data: {
|
||||||
mobile: string
|
mobile: string
|
||||||
smsCode: string
|
smsCode: string
|
||||||
uploadId: string
|
uploadId: string
|
||||||
}) {
|
}) {
|
||||||
return request.post<OcrParseResponse>('/marriage/ocr/parse', data)
|
return request.post<MarriageOcrParseResponse>('/marriage/ocr/parse', data)
|
||||||
|
},
|
||||||
|
|
||||||
|
// OCR 识别身份证
|
||||||
|
idCardParseOcrInfo(data: {
|
||||||
|
mobile: string
|
||||||
|
smsCode: string
|
||||||
|
uploadId: string
|
||||||
|
}) {
|
||||||
|
return request.post<IdCardOcrParseResponse>('/marriage/ocr/parseIdCard', data)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 领取流程相关接口
|
// 领取流程相关接口
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export interface OcrUploadResponse {
|
||||||
uploadId: string
|
uploadId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OcrParseResponse {
|
export interface MarriageOcrParseResponse {
|
||||||
raw: string
|
raw: string
|
||||||
words: string[]
|
words: string[]
|
||||||
parsed: {
|
parsed: {
|
||||||
|
|
@ -70,7 +70,7 @@ export interface ApiService {
|
||||||
sendSms(data: CommSmsDTO): Promise<any>
|
sendSms(data: CommSmsDTO): Promise<any>
|
||||||
|
|
||||||
// OCR识别并返回证件信息
|
// OCR识别并返回证件信息
|
||||||
parseOcrInfo(data: {
|
marriageParseOcrInfo(data: {
|
||||||
mobile: string
|
mobile: string
|
||||||
smsCode: string
|
smsCode: string
|
||||||
uploadId: string
|
uploadId: string
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue