<template>
|
<div class="authentication">
|
<fx-header :back="false" @back="loginOut">
|
<template #title>
|
<span>{{ $t('Primary') }}</span>
|
</template>
|
</fx-header>
|
|
<div class="auth-body">
|
<!-- nationality -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('nationality') }}</label>
|
<div class="auth-input auth-input--select" @click="openNationality">
|
<span class="auth-placeholder" :class="{ 'auth-placeholder--filled': countryName && countryName !== $t('selectNation') }">{{ countryName }}</span>
|
<van-icon name="arrow" class="auth-chevron" />
|
</div>
|
</div>
|
|
<!-- document type -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('documentType') }}</label>
|
<div class="auth-input auth-input--select" @click="showDocType = true">
|
<span class="auth-placeholder" :class="{ 'auth-placeholder--filled': idname }">{{ idname || $t('pleaseSelectDocumentType') }}</span>
|
<van-icon name="arrow" class="auth-chevron" />
|
</div>
|
</div>
|
|
<!-- last name -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('lastName') }}</label>
|
<input v-model="name" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterLastName')" />
|
</div>
|
|
<!-- first name -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('firstName') }}</label>
|
<input v-model="firstName" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterFirstName')" />
|
</div>
|
|
<!-- ID number -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('idNumber') }}</label>
|
<input v-model="idnumber" type="text" class="auth-input auth-input--text" :placeholder="$t('pleaseEnterIdNumber')" />
|
</div>
|
|
<!-- birth -->
|
<div class="auth-field">
|
<label class="auth-label">{{ $t('birth') }}</label>
|
<input v-model="birth" type="date" class="auth-input auth-input--text auth-input--date" :placeholder="$t('pleaseSelectBirth')" />
|
</div>
|
|
<!-- 证件上传(保留接口) -->
|
<div class="auth-upload-section" v-if="!disabled()">
|
<div class="auth-label">{{ $t('uploadCredentPassport') }}</div>
|
<div class="auth-upload-row">
|
<div class="auth-upload-item">
|
<van-uploader v-model="frontFile" :max-count="1" :deletable="!disabled()" :after-read="afterRead" />
|
<div class="auth-upload-tip">{{ $t('credentFront') }}</div>
|
</div>
|
<div class="auth-upload-item">
|
<van-uploader v-model="reverseFile" :max-count="1" :deletable="!disabled()" :after-read="afterRead" />
|
<div class="auth-upload-tip">{{ $t('credentObverse') }}</div>
|
</div>
|
</div>
|
</div>
|
|
<button type="button" class="auth-submit" @click="onSubmit">{{ $t('Submit') }}</button>
|
</div>
|
|
<nationality-list ref="controlChild" :title="$t('selectNation')" @getName="getName" />
|
<van-action-sheet v-model:show="showDocType" :actions="docTypeActions" @select="onSelectDocType" />
|
</div>
|
</template>
|
|
<script setup>
|
import { _getIdentify, _applyIdentify } from "@/service/user.api.js";
|
import { _uploadImage } from "@/service/upload.api.js";
|
import { onMounted, ref } from 'vue';
|
import nationalityList from './components/nationalityList.vue';
|
import { useRouter } from "vue-router";
|
import { showToast } from "vant";
|
import countries from "./components/countryList";
|
import { useI18n } from "vue-i18n";
|
|
const { t } = useI18n();
|
const router = useRouter();
|
|
const countryName = ref(t('selectNation'));
|
const countryCode = ref('af');
|
const idname = ref('');
|
const idnumber = ref('');
|
const name = ref('');
|
const firstName = ref('');
|
const birth = ref('');
|
const frontFile = ref([]);
|
const reverseFile = ref([]);
|
const status = ref('');
|
const show = ref(false);
|
const showDocType = ref(false);
|
const controlChild = ref(null);
|
|
const docTypeActions = [
|
{ name: 'ID Card', value: 'id/passport' },
|
{ name: 'Passport', value: 'passport' }
|
];
|
|
const disabled = () => ![0, 3, ''].includes(status.value);
|
|
onMounted(() => {
|
fetchInfo();
|
});
|
|
const loginOut = () => {
|
router.push('/certificationCenter');
|
};
|
|
const fetchInfo = () => {
|
_getIdentify().then(data => {
|
show.value = true;
|
status.value = data.status ?? '';
|
if (data.id != null || data.nationality) {
|
const code = (data.nationality || 'af').toLowerCase();
|
countryName.value = countries[code] ? countries[code].name : t('selectNation');
|
countryCode.value = code;
|
idnumber.value = data.idnumber || data.idNumber || '';
|
name.value = data.name || '';
|
firstName.value = data.firstName || data.firstname || '';
|
birth.value = data.birth || '';
|
frontFile.value = data.idimg_1 || data.idFrontImg ? [{ url: data.idimg_1_path || data.idFrontImg, resURL: data.idimg_1 || data.idFrontImg }] : [];
|
reverseFile.value = data.idimg_2 || data.idBackImg ? [{ url: data.idimg_2_path || data.idBackImg, resURL: data.idimg_2 || data.idBackImg }] : [];
|
}
|
}).catch(() => {});
|
};
|
|
const openNationality = () => {
|
if (!disabled() && controlChild.value) controlChild.value.open();
|
};
|
|
const getName = (params) => {
|
countryName.value = params.name;
|
countryCode.value = params.code;
|
};
|
|
const onSelectDocType = (item) => {
|
idname.value = item.value || item.name;
|
showDocType.value = false;
|
};
|
|
const afterRead = (file) => {
|
file.status = 'uploading';
|
file.message = t('uploading');
|
_uploadImage(file).then(data => {
|
file.status = 'success';
|
file.message = t('uploadSuccess');
|
file.resURL = data;
|
}).catch(() => {
|
file.status = 'failed';
|
file.message = t('uploadFailed');
|
});
|
};
|
|
const onSubmit = () => {
|
if (!countryName.value || countryName.value === t('selectNation')) {
|
showToast(t('selectNation'));
|
return;
|
}
|
if (!name.value) {
|
showToast(t('pleaseEnterLastName'));
|
return;
|
}
|
if (!firstName.value) {
|
showToast(t('pleaseEnterFirstName'));
|
return;
|
}
|
if (!idnumber.value) {
|
showToast(t('pleaseEnterIdNumber'));
|
return;
|
}
|
if (!birth.value) {
|
showToast(t('pleaseSelectBirth'));
|
return;
|
}
|
if (!frontFile.value.length || !frontFile.value[0]?.resURL) {
|
showToast(frontFile.value[0]?.status === 'uploading' ? t('uploading') : t('uploadComplete'));
|
return;
|
}
|
if (!reverseFile.value.length || !reverseFile.value[0]?.resURL) {
|
showToast(reverseFile.value[0]?.status === 'uploading' ? t('uploading') : t('uploadComplete'));
|
return;
|
}
|
|
_applyIdentify({
|
countryName: countryCode.value,
|
idname: idname.value || 'id/passport',
|
name: name.value,
|
firstName: firstName.value,
|
idnumber: idnumber.value,
|
birth: birth.value,
|
frontFile: frontFile.value,
|
reverseFile: reverseFile.value,
|
}).then(() => {
|
showToast(t('submitSuccess'));
|
router.push('/certificationCenter');
|
}).catch(err => {
|
if (err.code === 'ECONNABORTED') showToast(t('networkTimeout'));
|
else if (err.msg) showToast(err.msg);
|
});
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.authentication {
|
min-height: 100vh;
|
background: #fff;
|
padding-bottom: 2rem;
|
font-size: 14px;
|
}
|
|
:deep(.van-nav-bar) {
|
background: #fff !important;
|
}
|
:deep(.van-nav-bar__title) {
|
color: #333;
|
font-weight: 700;
|
font-size: 16px;
|
}
|
:deep(.van-icon) {
|
color: #333;
|
}
|
|
.auth-body {
|
padding: 0 1.25rem;
|
}
|
|
.auth-field {
|
margin-bottom: 1.25rem;
|
}
|
|
.auth-label {
|
display: block;
|
font-size: 14px;
|
color: #333;
|
margin-bottom: 0.5rem;
|
font-weight: 500;
|
}
|
|
.auth-input {
|
width: 100%;
|
box-sizing: border-box;
|
height: 48px;
|
line-height: 48px;
|
padding: 0 1rem;
|
background: #f8f8f8;
|
border-radius: 8px;
|
border: none;
|
font-size: 14px;
|
color: #333;
|
}
|
|
.auth-input--text {
|
display: block;
|
}
|
.auth-input--text::placeholder {
|
color: #999;
|
}
|
|
.auth-input--date {
|
color-scheme: light;
|
}
|
.auth-input--date::-webkit-calendar-picker-indicator {
|
opacity: 0.6;
|
cursor: pointer;
|
}
|
|
.auth-input--select {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
cursor: pointer;
|
}
|
|
.auth-placeholder {
|
color: #999;
|
font-size: 14px;
|
}
|
.auth-placeholder--filled {
|
color: #333;
|
}
|
|
.auth-chevron {
|
font-size: 14px;
|
color: #999;
|
flex-shrink: 0;
|
margin-left: 8px;
|
}
|
|
.auth-upload-section {
|
margin-top: 1.5rem;
|
margin-bottom: 1.5rem;
|
}
|
|
.auth-upload-row {
|
display: flex;
|
gap: 1rem;
|
margin-top: 0.5rem;
|
}
|
|
.auth-upload-item {
|
flex: 1;
|
text-align: center;
|
background-color: #F7F8FA;
|
}
|
.auth-upload-item :deep(.van-uploader__upload),
|
.auth-upload-item :deep(.van-uploader__preview) {
|
width: 100%;
|
height: 100px;
|
margin: 0;
|
}
|
.auth-upload-item :deep(.van-uploader__upload-icon) {
|
font-size: 24px;
|
}
|
.auth-upload-tip {
|
font-size: 12px;
|
color: #999;
|
margin-top: 6px;
|
}
|
|
.auth-submit {
|
width: 100%;
|
height: 50px;
|
line-height: 50px;
|
font-size: 14px;
|
font-weight: 700;
|
color: #fff;
|
background: linear-gradient(90deg, #7c3aed, #5b21b6);
|
border: none;
|
border-radius: 12px;
|
margin-top: 1rem;
|
cursor: pointer;
|
}
|
</style>
|