2026-03-25 14:38:42 +08:00

619 lines
24 KiB
Vue

<template>
<view class="container" :class="[`${themeInfo.theme}-theme`, `${themeInfo.language}`]">
<!-- <navBar /> -->
<view class="content">
<view class="formBox card">
<!-- <view class="fontb font36 mgb20" style="text-align: center;">
实名验证
</view> -->
<uv-form labelPosition="left" labelWidth="190rpx" :model="state" ref="form">
<!-- 用户姓名 -->
<uv-form-item label="用户姓名" prop="formData.name" borderBottom>
<uv-input placeholder="请填写" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.name" border="none"></uv-input>
</uv-form-item>
<!-- 证件类型 -->
<uv-form-item label="证件类型" prop="cardTypeText" borderBottom @click="openTypePicker">
<uv-input placeholder="请选择" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.cardTypeText" disabled disabledColor="#ffffff"
border="none"></uv-input>
<template #right>
<image src="/static/home/jiantou.svg" style="width: 44rpx;height: 24rpx;" class="icon"></image>
</template>
</uv-form-item>
<!-- 证件号码 -->
<uv-form-item label="证件号码" prop="formData.idCard" borderBottom>
<uv-input placeholder="请填写" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.idCard" border="none"></uv-input>
</uv-form-item>
<!-- 上传证件 -->
<uv-form-item label="证件正面照片" labelWidth="180rpx" labelPosition="top" borderBottom prop="formData.idFile1">
<view class="ImgUpload">
<my-upload v-model="state.formData.idFile1" :addWatermark="true" width="200rpx"
height="200rpx" :previewFullImage="false" uploadText=" ">
<!-- <image src="/static/personal/id02.png" mode="aspectFit"
style="width: 280rpx;height:200rpx;margin-bottom:20rpx"></image> -->
<!-- <view class="upLoadText">
{{ $t("common.IdCardFont") }}
</view> -->
</my-upload>
</view>
</uv-form-item>
<uv-form-item label="证件背面照片" prop="formData.idFile2" labelPosition="top" labelWidth="180rpx" borderBottom>
<view class="ImgUpload">
<my-upload v-model="state.formData.idFile2" :addWatermark="true" width="200rpx" height="200rpx"
:previewFullImage="false" uploadText=" ">
<!-- <image src="/static/personal/id01.png" mode="aspectFit"
style="width: 280rpx;height:200rpx;margin-bottom:20rpx"></image>
<view class="upLoadText">
{{ $t("common.IdCardBack") }}
</view> -->
</my-upload>
</view>
</uv-form-item>
<!-- 手机号码 -->
<uv-form-item label="手机号码" :class="{'phoneForm-item-disabled': !!storeState.userInfo.phone}" prop="formData.phone" borderBottom>
<view style="display:flex;align-items:center;width:100%">
<uv-input placeholder="请填写" :disabled="!!storeState.userInfo.phone" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.phone" border="none" style="flex:1"></uv-input>
</view>
</uv-form-item>
<!-- 境外号码 -->
<uv-form-item v-if="state.formData.type == 3 || state.formData.type == 4"
:label="isShichang ? '香港号码' : '境外号码'" borderBottom>
<view style="display:flex;align-items:center;width:100%">
<view @click="showAreaCodePicker"
style="display:flex;align-items:center;padding-right:16rpx">
<uv-input readonly v-model="state.formData.areaCode" border="none" style="width:120rpx"></uv-input>
<uv-icon name="play-right-fill" size="24rpx" style="transform: rotate(90deg)"></uv-icon>
</view>
<uv-input placeholder="请填写" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.abroadPhone" border="none" style="flex:1"></uv-input>
</view>
</uv-form-item>
<!-- 紧急联系人 -->
<uv-form-item label="紧急联系号码" prop="formData.emerPhone" borderBottom>
<uv-input placeholder="请填写" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.emerPhone" border="none"></uv-input>
</uv-form-item>
<!-- 邮箱 -->
<uv-form-item label="邮箱" prop="formData.email">
<uv-input placeholder="请填写" placeholderStyle="font-weight: 600;font-size: 28rpx;color:#A8AAAC;" v-model="state.formData.email" border="none"></uv-input>
</uv-form-item>
</uv-form>
</view>
<view class="info">
<view class="infobox">
<view class="personal" style="margin-top:20rpx;" v-show="state.vaildType == 1">
<view class="tips font28" v-if="state.formData.certificateStatus1 === 1"
style="text-align: left;color: red;margin: 20rpx 0;">
{{ $t("verification.vailFail") }}
</view>
<view class="tips font28" v-if="state.formData.certificateStatus1 === 0"
style="text-align: center; color: green;margin: 20rpx 0;">
{{ $t("verification.vailSuccess") }}
</view>
<view class="btn">
<!-- <AgreementCheck v-model="agree" /> -->
<uv-button :customStyle="{
height: '86rpx',
color: '#fff',
fontSize: '32rpx',
}" color="#FB322E" class="next-btn" shape="circle" :class="{ disabled: !agree }" @click="verifyPerson">
{{ state.formData.certificateStatus1 == 1 ? $t("common.verifyInfo") :
$t("common.saveInfo") }}
</uv-button>
</view>
</view>
</view>
</view>
</view>
<view class="footer">
<view @click="toHome">
返回主页
</view>
<view @click="goOrder">
返回订单
</view>
</view>
<!-- 选择证件类型 -->
<uvPickerSlef ref="typePickerRef" :confirmText="$t('common.confirm')"
:cancelText="$t('common.cancel')" confirmColor="#FB322E" round="24px" title="证件类型" :columns="state.cardType" keyName="label"
@confirm="confirmCardType"></uvPickerSlef>
<!-- 是否验证成功 -->
<myModal v-model="state.showAuthModal" :content="state.contentTips" :cancelShow="false"></myModal>
<uvPickerSlef ref="AreaCodePickerRef" title="区号" :columns="[areaCodeList]" keyName="label" round="24px" @confirm="onAreaCodeConfirm" />
</view>
</template>
<script setup>
import { ref, reactive, computed, watchEffect } from "vue";
import { onLoad, onShareAppMessage } from "@dcloudio/uni-app";
import { baseImageUrl, projectInfo, watermarkURL } from "@/config/index.js";
import { navigateBack } from '@/utils/common.js';
import navBar from "@/components/navBar.vue";
import { isShichang } from '@/config/index.js'
import myUpload from "@/components/myUpload.vue";
// import AgreementCheck from "@/components/agreementCheck.vue";
import uvPickerSlef from "@/components/uv-pickerself/components/uv-picker/uv-picker.vue";
// 主题色配置
import { useMainStore } from "@/store/index.js";
import myModal from "@/components/myModal.vue";
const { themeInfo, storeState,getUserInfo } = useMainStore();
import { useI18n } from 'vue-i18n';
import { useLoginApi } from "@/Apis/login.js";
import { authInfoApi } from "@/Apis/validInfo.js";
import { navigateTo } from '@/utils/navigateTo';
import dayjs from 'dayjs';
const { t } = useI18n();
const app = getApp();
const pages = getCurrentPages()
const getLoginApi = useLoginApi();
const getAuthApi = authInfoApi();
const agree = ref(true)
const goOrder = () => {
navigateTo('/pages/unlock/index');
}
const typePickerRef = ref();
const canGetCode = ref();
const state = reactive({
hasPhone: false,
tips: "获取验证码",
hasVeriPerson: false, // 是否验证过个人
hasVeriEnterprise: false, // 是否验证过企业
vaildType: 1, // 1 个人 2 企业
showAuthModal: false,
contentTips: '', // 验证成功提示
cardTypeText: '', // 证件类型
formData: {
name: '',
idCard: '',
areaCode: '+852',
phone: '',
email: '',
abroadPhone: '',
type: 0,
emerPhone: '',
idFile1: [],
idFile2: [],
enterpriseName: '',
license: '',
licenseFile: [],
certificateStatus1: '', // 个人认证 0 验证通过 1 失败
certificateStatus2: '', // 企业认证 0 验证通过 1 失败
},
cardType: [
[
{ id: 1, label: t('validation.identifyCard') },
{ id: 3, label: t('validation.passport') },
{ id: 4, label: t('validation.permit') },
]
]
});
const AreaCodePickerRef = ref();
const areaCodeList = ref([
{ label: '+86 (中国)', value: '+86' },
{ label: '+852 (中国香港)', value: '+852' },
{ label: '+853 (中国澳門)', value: '+853' },
{ label: '+886 (中国台灣)', value: '+886' },
{ label: '+81 (日本)', value: '+81' },
{ label: '+82 (대한민국)', value: '+82' },
{ label: '+65 (Singapura)', value: '+65' },
{ label: '+60 (Malaysia)', value: '+60' },
{ label: '+66 (ประเทศไทย)', value: '+66' },
{ label: '+84 (Việt Nam)', value: '+84' },
{ label: '+63 (Pilipinas)', value: '+63' },
{ label: '+62 (Indonesia)', value: '+62' },
{ label: '+1 (United States / Canada)', value: '+1' },
{ label: '+52 (México)', value: '+52' },
{ label: '+55 (Brasil)', value: '+55' },
{ label: '+54 (Argentina)', value: '+54' },
{ label: '+44 (United Kingdom)', value: '+44' },
{ label: '+33 (France)', value: '+33' },
{ label: '+49 (Deutschland)', value: '+49' },
{ label: '+39 (Italia)', value: '+39' },
{ label: '+34 (España)', value: '+34' },
{ label: '+7 (Россия)', value: '+7' },
{ label: '+61 (Australia)', value: '+61' },
{ label: '+64 (New Zealand)', value: '+64' },
{ label: '+91 (भारत)', value: '+91' },
{ label: '+966 (المملكة العربية السعودية)', value: '+966' },
{ label: '+971 (الإمارات العربية المتحدة)', value: '+971' },
{ label: '+90 (Türkiye)', value: '+90' },
{ label: '+27 (South Africa)', value: '+27' }
]);
const onAreaCodeConfirm = (e) => {
state.formData.areaCode = e.value[0].value;
closeAreaCodePicker();
};
const showAreaCodePicker = () => {
console.log(AreaCodePickerRef, "AreaCodePickerRef")
AreaCodePickerRef.value.open();
}
const closeAreaCodePicker = () => {
AreaCodePickerRef.value.close();
}
const codeChange = (text) => {
state.tips = text;
};
const getCode = () => {
if (canGetCode.value.canGetCode) {
// 模拟向后端请求验证码
uni.showLoading({
title: "正在获取验证码",
});
setTimeout(() => {
uni.hideLoading();
canGetCode.value.start();
}, 2000);
} else {
}
};
onShareAppMessage((res) => {
return {
title: `${projectInfo.miniName}`,
path: '/pagesb/validationInfo/index'
};
});
const getVerifyInfo = async () => {
await getUserInfo();
uni.showLoading();
getAuthApi.GetCertificationInfo().then(res => {
uni.hideLoading({
mark: true,
});
let { code, data } = res;
if (code == 200 && data && data.length) {
let personData = data.find(item => [1, 3, 4].includes(item.certificateType));
let enterpriseData = data.find(item => item.certificateType == 2);
if (personData && personData.id) {
agree.value = true;
state.hasVeriPerson = personData;
state.formData.name = personData.name;
state.formData.type = personData.certificateType;
state.formData.idCard = personData.certificateNumber;
state.formData.phone = personData.phone;
state.formData.email = personData.email;
state.formData.emerPhone = personData.emergencyPhone;
state.formData.areaCode = personData.areaCode || '';
state.formData.abroadPhone = personData.abroadPhone;
state.formData.certificateStatus1 = personData.certificateStatus;
state.formData.idFile1 = [{ status: 'success', url: baseImageUrl + personData.certificateImgHead + watermarkURL, fileUrl: personData.certificateImgHead + watermarkURL }];
state.formData.idFile2 = [{ status: 'success', url: baseImageUrl + personData.certificateImgTails + watermarkURL, fileUrl: personData.certificateImgTails + watermarkURL }];
let index = state.cardType[0].findIndex(item => item.id == personData.certificateType);
if (index > -1) typePickerRef.value.setIndexs([index]);
}
if (enterpriseData && enterpriseData.id) {
agree.value = true;
state.hasVeriEnterprise = enterpriseData;
state.formData.enterpriseName = enterpriseData.name;
state.formData.license = enterpriseData.certificateNumber;
state.formData.certificateStatus2 = enterpriseData.certificateStatus;
state.formData.licenseFile = [{ status: 'success', url: baseImageUrl + enterpriseData.certificateImgHead + watermarkURL, fileUrl: enterpriseData.certificateImgHead + watermarkURL }];
}
}
state.formData.phone = storeState.userInfo.phone;
});
}
onLoad(() => {
getVerifyInfo();
});
const toHome = (item) => {
uni.switchTab({
url: `/pages/index/index`,
});
}
const changeValidType = (val) => {
state.vaildType = val;
};
const getPhoneNumber = (e) => {
uni.showLoading();
if (e.code) {
getLoginApi.GetPhoneNumber({ code: e.code }).then((res) => {
if (res.code == 200) {
uni.hideLoading();
state.formData.phone = res.data;
}
});
} else {
uni.hideLoading();
uni.showToast({
title: t('validation.getPhoneFail'),
icon: "none",
duration: 2000,
});
}
}
// 选择证件类型
const openTypePicker = () => {
typePickerRef.value?.open();
}
watchEffect(() => {
state.cardTypeText = state.cardType[0].find(item => item.id == state.formData.type)?.label;
});
const confirmCardType = (e) => {
state.formData.type = e.value[0].id;
}
// 提交个人认证信息
const verifyPerson = () => {
// if (!agree.value) return uni.showToast({
// title: t('agreement.toast'),
// icon: 'none'
// });
if (!state.formData.name) return uni.showToast({
title: t('validation.inputName1'),
icon: 'none'
});
if (!state.formData.type) return uni.showToast({
title: t('validation.selectCardType'),
icon: 'none'
});
if (!state.formData.idCard) return uni.showToast({
title: t('validation.inputIdCard'),
icon: 'none'
});
if (!state.formData.idFile1.length || !state.formData.idFile2.length) return uni.showToast({
title: t('validation.uploadIdCard'),
icon: 'none'
});
if (!state.formData.phone) return uni.showToast({
title: t('validation.inputPhone'),
icon: 'none'
});
if ((state.formData.type == 3 || state.formData.type == 4) && !state.formData.abroadPhone) return uni.showToast({
title: t('validation.inputInternationalPhone'),
icon: 'none'
});
if (state.formData.idFile1[0].status != 'success' || state.formData.idFile2[0].status != 'success') return uni.showToast({
title: t('validation.uploadImg'),
icon: 'none'
});
if (state.hasVeriPerson) return updateAuthInfo();
uni.showLoading();
console.log(state);
getAuthApi.SubmitPersonCertification({
type: state.formData.type,
name: state.formData.name,
areaCode: state.formData.areaCode,
certificateNumber: state.formData.idCard,
certificateImgHead: state.formData.idFile1[0].url?.replace(watermarkURL, ''),
certificateImgTails: state.formData.idFile2[0].url?.replace(watermarkURL, ''),
phone: state.formData.phone,
email: state.formData.email,
abroadPhone: (state.formData.type == 3 || state.formData.type == 4) ? state.formData.abroadPhone : '',
emergencyPhone: state.formData.emerPhone,
}).then(res => {
uni.hideLoading();
if (res.code == 200) {
state.contentTips = res.data ? t('validation.vailSuccess') : t('verification.vailFail');
state.showAuthModal = true;
if (res.data && pages.length >= 2) {
if (pages[pages.length - 2].route == 'pages/index/index') {
navigateBack()
return
}
}
getVerifyInfo()
// uni.showToast({
// title: t('validation.submitSuccess'),
// icon: 'success'
// });
// navigateBack();
}
});
}
// 提交企业认证信息
const verifyEnterprise = () => {
// if (!agree.value) return uni.showToast({
// title: t('agreement.toast'),
// icon: 'none'
// });
if (!state.formData.enterpriseName) return uni.showToast({
title: t('validation.inputName2'),
icon: 'none'
});
if (!state.formData.license) return uni.showToast({
title: t('validation.inputLicense'),
icon: 'none'
});
if (!state.formData.licenseFile.length) return uni.showToast({
title: t('validation.uploadLicense'),
icon: 'none'
});
if (state.formData.licenseFile[0].status != 'success') return uni.showToast({
title: t('validation.uploadImg'),
icon: 'none'
});
if (state.hasVeriEnterprise) return updateAuthInfo();
uni.showLoading();
getAuthApi.SubmitEnterpriseCertification({
name: state.formData.enterpriseName,
certificateNumber: state.formData.license,
certificateImgHead: state.formData.licenseFile[0].url?.replace(watermarkURL, '')
}).then(res => {
if (res.code == 200) {
state.contentTips = res.data ? t('validation.vailSuccess') : t('verification.vailFail');
state.showAuthModal = true;
getVerifyInfo()
}
uni.hideLoading();
});
}
// 修改认证信息
const updateAuthInfo = () => {
let requestData = {};
if (state.vaildType == 1) {
requestData = {
type: state.formData.type,
enable: true,
id: state.hasVeriPerson.id,
name: state.formData.name,
areaCode: state.formData.areaCode,
certificateNumber: state.formData.idCard,
certificateImgHead: state.formData.idFile1[0].fileUrl?.replace(watermarkURL, '') || state.formData.idFile1[0].url?.replace(watermarkURL, ''),
certificateImgTails: state.formData.idFile2[0].fileUrl?.replace(watermarkURL, '') || state.formData.idFile2[0].url?.replace(watermarkURL, ''),
phone: state.formData.phone,
email: state.formData.email,
abroadPhone: (state.formData.type == 3 || state.formData.type == 4) ? state.formData.abroadPhone : '',
emergencyPhone: state.formData.emerPhone
}
} else {
requestData = {
type: 2,
enable: true,
id: state.hasVeriEnterprise.id,
name: state.formData.enterpriseName,
certificateNumber: state.formData.license,
certificateImgHead: state.formData.licenseFile[0].fileUrl?.replace(watermarkURL, '') || state.formData.licenseFile[0].url?.replace(watermarkURL, ''),
}
}
uni.showLoading();
getAuthApi.UpdateCertification(requestData).then(res => {
uni.hideLoading();
if (res.code == 200) {
state.contentTips = res.data ? t('validation.vailSuccess') : t('verification.vailFail');
state.showAuthModal = true;
if (res.data && requestData.type !== 2) {
if (pages.length >= 2) {
if (pages[pages.length - 2].route == 'pages/setOrder/index') {
navigateBack()
return
}
}
}
}
getVerifyInfo();
});
}
</script>
<style lang="scss" scoped>
@import "@/static/style/theme.scss";
.phoneForm-item-disabled{
:deep(.uv-form-item__body){
opacity: 0.4;
}
}
.container {
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
background-attachment: fixed;
padding-bottom: 200rpx;
.content {
width: 100%;
.formBox {
padding-top: 16rpx;
padding-bottom: 16rpx;
background-color: #FFF;
:deep(.uv-form-item__body__left__content__label) {
font-size: 26rpx;
font-weight: 600;
}
:deep(.uv-form-item){
.uv-line{
border-color: #787B7E10!important;
}
}
:deep(.uv-input__content__field-wrapper__field) {
font-size: 28rpx !important;
text-align: right!important;
font-weight: 600;
}
:deep(.uv-form-item__body) {
padding: 20rpx;
}
.ImgUpload{
// margin-left: auto; /* 左边自动占满 → 右对齐 */
padding: 20rpx 0;
}
}
.btn {
margin-top: 20rpx;
padding: 0 62rpx;
button {
font-size: 28rpx;
padding: 14rpx 0;
margin: 40rpx 16rpx;
font-weight: bold;
color: var(--text-color);
background: var(--active-color);
border-radius: 10rpx;
&.disabled {
opacity: 0.5;
}
}
}
}
}
.footer{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 100rpx;
display: flex;
justify-content: space-around;
align-items: center;
background-color: #fff;
view{
width: 50%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
color: #000;
font-size: 30rpx;
font-weight: bold;
}
}
</style>