|
|
@@ -0,0 +1,190 @@
|
|
|
+<template>
|
|
|
+ <app-view class="g-form account-certification">
|
|
|
+ <template #header>
|
|
|
+ <app-navbar title="实名认证" />
|
|
|
+ </template>
|
|
|
+ <Form ref="formRef" class="g-form__container" @submit="onCheckCardNum" :loading="loading">
|
|
|
+ <CellGroup inset>
|
|
|
+ <Field v-model="formData.username" name="username" label="姓名" placeholder="请输入用户姓名" :rules="formRules.username"
|
|
|
+ :readonly="isReadonly" />
|
|
|
+ <!-- <Field v-model="formData.mobile" name="mobile" readonly label="手机号码" /> -->
|
|
|
+ <Field name="idCardType" label="证件类型" :rules="formRules.cardtype" is-link>
|
|
|
+ <template #input>
|
|
|
+ <app-select v-model="formData.cardtype" placeholder="请选择证件类型"
|
|
|
+ :options="getAQCertificateTypeList()" :readonly="isReadonly" />
|
|
|
+ </template>
|
|
|
+ </Field>
|
|
|
+ <Field v-model="formData.cardnum" name="cardnum" label="证件号码" placeholder="请输入证件号码" :rules="formRules.cardnum"
|
|
|
+ :readonly="isReadonly" />
|
|
|
+ <Field name="cardfrontphotourl" label="证件正面照片" :rules="formRules.cardfrontphotourl">
|
|
|
+ <template #input>
|
|
|
+ <Image fit="contain" :src="getFileUrl(formData.cardfrontphotourl)" width="100" height="100"
|
|
|
+ v-if="isReadonly" />
|
|
|
+ <app-uploader @success="f_afterRead" v-else />
|
|
|
+ </template>
|
|
|
+ </Field>
|
|
|
+ <Field name="cardbackphotourl" label="证件反面照片" :rules="formRules.cardbackphotourl">
|
|
|
+ <template #input>
|
|
|
+ <Image fit="contain" :src="getFileUrl(formData.cardbackphotourl)" width="100" height="100"
|
|
|
+ v-if="isReadonly" />
|
|
|
+ <app-uploader @success="b_afterRead" v-else />
|
|
|
+ </template>
|
|
|
+ </Field>
|
|
|
+ </CellGroup>
|
|
|
+ </Form>
|
|
|
+ <img src="../../../assets/images/certification.png" />
|
|
|
+ <template #footer>
|
|
|
+ <div class="g-form__footer inset">
|
|
|
+ <Button type="danger" :loading="buttonLoading" @click="onSubmit" round block>提交实名认证</Button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <component ref="componentRef" v-bind="{ formData }" :is="componentMap.get(componentId)" @closed="closeComponent"
|
|
|
+ v-if="componentId" />
|
|
|
+ </app-view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { shallowRef, defineAsyncComponent, onMounted, computed } from 'vue'
|
|
|
+import { CellGroup, Button, Field, Form, FormInstance, showFailToast, FieldRule, Image } from 'vant'
|
|
|
+import { fullloading, dialog } from '@/utils/vant';
|
|
|
+import { getFileUrl } from '@/filters';
|
|
|
+import { getAQCertificateTypeList } from "@/constants/account";
|
|
|
+import { useRequest } from '@/hooks/request'
|
|
|
+import { queryUserESignRecord, requestCheckCardNum } from '@/services/api/account';
|
|
|
+import { addAuthReq } from '@/business/user/account';
|
|
|
+import { validateRules } from '@/constants/regex';
|
|
|
+import { useComponent } from '@/hooks/component'
|
|
|
+import { useUserStore } from '@/stores'
|
|
|
+import AppSelect from '@mobile/components/base/select/index.vue'
|
|
|
+import AppUploader from '@mobile/components/base/uploader/index.vue'
|
|
|
+import { useNavigation } from '@mobile/router/navigation'
|
|
|
+
|
|
|
+const componentMap = new Map<string, unknown>([
|
|
|
+ ['certification-next', defineAsyncComponent(() => import('./components/certification-next/Index.vue'))], // 爱签-实名认证第二步
|
|
|
+])
|
|
|
+
|
|
|
+const { router } = useNavigation()
|
|
|
+const userStore = useUserStore()
|
|
|
+const formRef = shallowRef<FormInstance>()
|
|
|
+const { formData, formSubmit, loading } = addAuthReq()
|
|
|
+
|
|
|
+const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
|
|
|
+ router.back()
|
|
|
+})
|
|
|
+
|
|
|
+const isReadonly = computed(() => userESignRecords.value.some((e) => e.templatetype === 1 && e.recordstatus === 3))
|
|
|
+
|
|
|
+/// 查询记录
|
|
|
+const { loading: buttonLoading, dataList: userESignRecords, run: getUserESignRecord } = useRequest(queryUserESignRecord, {
|
|
|
+ onSuccess: (res) => {
|
|
|
+ const record = res.data.find((e) => e.templatetype === 1 && e.recordstatus === 3)
|
|
|
+ if (record) {
|
|
|
+ const { name, idCard, idCardPhoto, idCardPhotoBackURL, mobile, idCardType } = JSON.parse(record.authinfo || '{}')
|
|
|
+ formData.username = name
|
|
|
+ formData.cardnum = idCard
|
|
|
+ formData.cardbackphotourl = idCardPhoto
|
|
|
+ formData.cardbackphotourl = idCardPhotoBackURL
|
|
|
+ formData.cardtype = idCardType
|
|
|
+ // formData.mobile = mobile
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onError: (err) => {
|
|
|
+ showFailToast(err)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const b_afterRead = (filePath: string) => {
|
|
|
+ formData.cardbackphotourl = filePath
|
|
|
+}
|
|
|
+
|
|
|
+const f_afterRead = (filePath: string) => {
|
|
|
+ formData.cardfrontphotourl = filePath
|
|
|
+}
|
|
|
+
|
|
|
+// 表单验证规则
|
|
|
+const formRules: { [key in keyof Model.AddAuthReq]?: FieldRule[] } = {
|
|
|
+ username: [{
|
|
|
+ required: true,
|
|
|
+ message: '请输入用户姓名',
|
|
|
+ }],
|
|
|
+ mobile: [{
|
|
|
+ required: true,
|
|
|
+ message: '请输入手机号码',
|
|
|
+ validator: (val) => {
|
|
|
+ if (validateRules.phone.validate(val)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return validateRules.phone.message
|
|
|
+ }
|
|
|
+ }],
|
|
|
+ cardnum: [{
|
|
|
+ required: true,
|
|
|
+ message: '请输入证件号码',
|
|
|
+ validator: (val) => {
|
|
|
+ if (validateRules.cardno.validate(val)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return validateRules.cardno.message
|
|
|
+ }
|
|
|
+ }],
|
|
|
+ cardbackphotourl: [{
|
|
|
+ required: true,
|
|
|
+ message: '请上传证件背面照片',
|
|
|
+ }],
|
|
|
+ cardfrontphotourl: [{
|
|
|
+ required: true,
|
|
|
+ message: '请上传证件正面照片',
|
|
|
+ }],
|
|
|
+}
|
|
|
+
|
|
|
+const onCheckCardNum = () => {
|
|
|
+ fullloading((hideLoading) => {
|
|
|
+ requestCheckCardNum({
|
|
|
+ data: {
|
|
|
+ cardnum: formData.idCard
|
|
|
+ }
|
|
|
+ }).then(() => {
|
|
|
+ formSubmit().then(() => {
|
|
|
+ hideLoading()
|
|
|
+ getUserESignRecord()
|
|
|
+ dialog('提交请求成功').then(() => {
|
|
|
+ /// 进行下一步
|
|
|
+ openComponent('certification-next')
|
|
|
+ })
|
|
|
+ }).catch((err) => {
|
|
|
+ switch (err) {
|
|
|
+ case '100020':
|
|
|
+ hideLoading('个人三要素信息验证失败', 'fail')
|
|
|
+ break
|
|
|
+ case '100021':
|
|
|
+ hideLoading('用户已存在', 'fail')
|
|
|
+ break
|
|
|
+ case '100726':
|
|
|
+ hideLoading('该条实名记录为核验记录,无法用于添加用户', 'fail')
|
|
|
+ break
|
|
|
+ case '100727':
|
|
|
+ hideLoading('实名认证类型和添加用户类型不匹配', 'fail')
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ hideLoading(err, 'fail')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }).catch((err) => {
|
|
|
+ hideLoading(err, 'fail')
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const onSubmit = () => {
|
|
|
+ const isInclude = userESignRecords.value.some((e) => e.templatetype === 1 && e.recordstatus === 1)
|
|
|
+ if (!userESignRecords.value.length || isInclude) {
|
|
|
+ formRef.value?.submit()
|
|
|
+ } else {
|
|
|
+ openComponent('certification-next')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ formData.mobile = userStore.userInfo?.mobile2 ?? ''
|
|
|
+})
|
|
|
+</script>
|