feat: 初始化

This commit is contained in:
George
2025-07-07 16:05:18 +08:00
commit c169958240
986 changed files with 132574 additions and 0 deletions

View File

@ -0,0 +1,100 @@
.container {
padding: 0 24px 24px 16px;
.title {
margin: 14px 0 15px;
}
.content {
.voucherTypeWrapper {
display: flex;
column-gap: 12px;
.voucherType {
display: flex;
justify-content: center;
align-items: center;
column-gap: 10px;
flex: 1;
padding: 8px;
height: 81px;
border: 1px solid #e5e5e5;
box-sizing: border-box;
cursor: pointer;
&.active {
border: none;
box-shadow: 0px 2px 9px rgba(0, 0, 0, 0.15);
}
.voucherIcon {
width: 33px;
height: 27px;
flex-shrink: 0;
}
.label {
font-size: 20px;
font-weight: 700;
line-height: 24px;
}
}
}
.voucherImgTitle {
margin-top: 28px;
font-size: 20px;
font-weight: 700;
line-height: 29px;
}
.voucherImgDesc {
margin-top: 10px;
color: #999999;
font-size: 14px;
}
.voucherImgWrapper {
display: flex;
align-items: center;
column-gap: 20px;
margin-top: 20px;
::v-deep .uni-file-picker {
height: 100px;
}
::v-deep .uni-file-picker__container {
height: 100px;
}
::v-deep .file-picker__box {
padding-top: 0px;
width: 100% !important;
max-width: 152px;
height: 100% !important;
}
::v-deep .uni-forms-item {
flex: 1;
}
}
.normWrapper {
margin-bottom: 34px;
.normTitle {
font-size: 14px;
font-weight: 700;
color: #999999;
}
.normContent {
display: flex;
column-gap: 20px;
margin-top: 8px;
font-size: 12px;
color: #999999;
.normColumn {
display: flex;
flex-direction: column;
.normItem {
display: flex;
column-gap: 4px;
align-items: center;
.point {
width: 2px;
height: 2px;
border-radius: 10px;
background-color: #999999;
}
}
}
}
}
}
}

View File

@ -0,0 +1,250 @@
<template>
<NavBar />
<view class="container">
<view class="title">
<PageTitle :title="$t('form.personalData.personalInformation.identityVerification')" />
</view>
<view class="content">
<uni-forms ref="identityForm" :modelValue="identityFormData" :rules="identityFormRules">
<!-- <uni-forms-item name="voucher_name">
<text class="uni-subtitle">{{ $t('form.fullName.label') }}</text>
<uni-easyinput trim="all" primaryColor="#29BBE4" v-model="identityFormData.voucher_name"></uni-easyinput>
</uni-forms-item> -->
<view class="voucherTypeWrapper">
<view :class="['voucherType', selectedVoucherType === 'SFZ' ? 'active' : '']" @click="selectVoucherType('SFZ')">
<image src="/static/IDCard.png" mode="aspectFit" class="voucherIcon"></image>
<text class="label">{{ $t('form.idCard.label') }}</text>
</view>
<view :class="['voucherType', selectedVoucherType === 'HZ' ? 'active' : '']" @click="selectVoucherType('HZ')">
<image src="/static/passport.png" mode="aspectFit" class="voucherIcon"></image>
<text class="label">{{ $t('form.passport.label') }}</text>
</view>
</view>
<view class="voucherImgTitle">{{ $t('form.voucher.label_voucher') }}</view>
<view class="voucherImgDesc">{{ $t('form.voucher.tips') }}</view>
<view class="voucherImgWrapper">
<uni-forms-item name="voucher_img_0">
<view>
<uni-file-picker ref="voucher_img_0" v-model="voucherImg0" file-mediatype="image" mode="grid" :limit="1" @select="(e) => select(e, 'voucher_img_0')" />
<view style="max-width: 140px">
<Progress :progress="voucher_img_0_progress" :error="voucher_img_0_error" />
</view>
</view>
</uni-forms-item>
<uni-forms-item name="voucher_img_1">
<uni-file-picker ref="voucher_img_1" v-model="voucherImg1" file-mediatype="image" mode="grid" :limit="1" @select="(e) => select(e, 'voucher_img_1')" />
<view style="max-width: 140px">
<Progress :progress="voucher_img_1_progress" :error="voucher_img_1_error" />
</view>
</uni-forms-item>
</view>
<view class="normWrapper">
<view class="normTitle">{{ $t('form.voucher.uploadNorm') }}</view>
<view class="normContent">
<view class="normColumn">
<view class="normItem">
<view class="point"></view>
{{ $t('form.voucher.norm1') }}
</view>
<view class="normItem">
<view class="point"></view>
{{ $t('form.voucher.norm3') }}
</view>
</view>
<view class="normColumn">
<view class="normItem">
<view class="point"></view>
{{ $t('form.voucher.norm2') }}
</view>
<view class="normItem">
<view class="point"></view>
{{ $t('form.voucher.norm4') }}
</view>
</view>
</view>
</view>
</uni-forms>
<view v-if="proven === 'false'">
<button :disabled="voucher_img_0_progress !== 100 || voucher_img_1_progress !== 100 || btnLoading" class="primaryButton" @click="handleSaveVoucher">
<image v-show="btnLoading" src="/static/loadingCircle.svg" mode="aspectFit" style="width: 16px; height: 16px"></image>
{{ $t('form.uploadDocument') }}
</button>
</view>
</view>
</view>
</template>
<script>
import { useUserStore } from '@/stores/user';
import { getAuthVoucher, saveVoucher } from '@/services/user/completeInfo.ts';
import { imgUpload, getImgPath } from '@/services/common.ts';
import { UserLanguage } from '../../../../utils/const';
export default {
data() {
return {
imgBaseUrl: '',
btnLoading: false,
proven: 'false',
voucherImg0: {
// url: ''
},
voucherImg1: {
// url: ''
},
voucher_img_0_progress: 100,
voucher_img_1_progress: 100,
voucher_img_0_error: false,
voucher_img_1_error: false,
selectedVoucherType: undefined,
rawIdentityFormData: {},
identityFormData: {},
identityFormRules: {
// voucher_name: {
// rules: [
// {
// required: true,
// errorMessage: this.$t('form.fullName.required')
// }
// ]
// },
voucher_img_0: {
rules: [
{
required: true,
errorMessage: this.$t('form.voucher.required')
}
]
},
voucher_img_1: {
rules: [
{
required: true,
errorMessage: this.$t('form.voucher.required')
}
]
}
},
fieldsNeedCheck: ['voucher_type', 'voucher_img_0', 'voucher_img_1']
};
},
methods: {
async getAuthInfo() {
const res = await getAuthVoucher();
if (res && res.code === 0 && res.data) {
this.rawIdentityFormData = { ...res.data } ?? {};
this.identityFormData = { ...res.data } ?? {};
this.selectedVoucherType = res.data.voucher_type;
this.voucherImg0 = {
url: this.imgBaseUrl + res.data.voucher_img_0
};
this.voucherImg1 = {
url: this.imgBaseUrl + res.data.voucher_img_1
};
}
},
async getImgPathData() {
const res = await getImgPath();
if (res && res.code === 0) {
this.imgBaseUrl = res.data;
}
},
selectVoucherType(type) {
this.selectedVoucherType = type;
this.identityFormData.voucher_type = type;
},
async select(e, field) {
this[`${field}_progress`] = 0;
this[`${field}_error`] = false;
let step = 1;
const timer = setInterval(() => {
if (this[`${field}_progress`] > 85) {
step = 0.1;
} else if (this[`${field}_progress`] > 35) {
step = 0.8;
} else if (this[`${field}_progress`] > 15) {
step = 0.4;
}
if (this[`${field}_progress`] + step > 98) {
clearInterval(timer);
return;
}
this[`${field}_progress`] += step;
}, 34);
this.$refs[field].files[0].progress = 100;
const res = await imgUpload(e);
if (res && res.code === 0) {
this[`${field}_progress`] = 100;
this.identityFormData[field] = res.data?.imgNameList?.[0];
uni.showToast({
icon: 'none',
title: this.$t('common.success.uploadSuccess')
});
} else {
this[`${field}_error`] = true;
this.$cusModal.showModal({
type: 'message',
status: 'warning',
contentText: res.msg ?? this.$t('common.error.uploadError')
});
}
},
async handleSaveVoucher() {
let params = {
qcc_language: UserLanguage,
voucher: [
{
id: this.rawIdentityFormData.id ?? ''
}
]
};
this.$refs.identityForm.validate().then(async (fields) => {
if (!this.selectedVoucherType) {
this.$cusModal.showModal({
type: 'message',
status: 'warning',
contentText: this.$t('form.voucherType.required')
});
return;
}
this.fieldsNeedCheck.forEach((field) => {
if (this.identityFormData[field] !== this.rawIdentityFormData[field]) {
params.voucher[0][field] = {
edit_power: 1,
nv: this.identityFormData[field],
ov: this.rawIdentityFormData[field],
voucher_type: this.selectedVoucherType
};
}
});
this.btnLoading = true;
const res = await saveVoucher(params);
this.btnLoading = false;
if (res && res.code === 0) {
uni.redirectTo({
url: '/pages/user/personalInformation/identity/success/index'
});
} else {
this.$cusModal.showModal({
type: 'message',
status: 'warning',
contentText: res.msg ?? this.$t('common.error.sysError')
});
}
});
}
},
async created() {
const userStore = useUserStore();
this.userEmail = userStore.userInfo.email;
await this.getImgPathData();
this.getAuthInfo();
this.selectVoucherType('SFZ');
},
onLoad(params) {
this.proven = params.proven;
}
};
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>

View File

@ -0,0 +1,70 @@
.container {
padding: 0 24px 24px 16px;
.title {
margin: 14px 0 15px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 10px;
margin-top: 62px;
.successTitle {
font-size: 24px;
font-weight: 700;
color: #333333;
text-align: center;
}
.successTitle2 {
font-size: 18px;
font-weight: 700;
color: #333333;
text-align: center;
}
.successDesc {
margin-top: 19px;
font-size: 12px;
color: #aaaaaa;
text-align: center;
}
}
.btns {
display: flex;
flex-direction: column;
row-gap: 12px;
.btn {
width: 100%;
}
}
.stepsWrapper {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 8px;
color: #999999;
font-size: 12px;
margin: 34px 0 20px;
.steps {
display: flex;
justify-content: space-between;
align-items: center;
column-gap: 3px;
width: 100%;
height: 10px;
padding: 0 3px;
border: 1px solid #e5e5e5;
border-radius: 10px;
box-sizing: border-box;
.stepItem {
flex: 1;
height: 5px;
background-color: #e5e5e5;
border-radius: 10px;
box-sizing: border-box;
&.active {
background-image: linear-gradient(to right, #103776 0%, #6474af 100%);
}
}
}
}
}

View File

@ -0,0 +1,76 @@
<template>
<NavBar />
<view class="container">
<view class="title">
<PageTitle :title="$t('form.personalData.personalInformation.identityVerification')" />
</view>
<view class="content">
<image src="/static/success.png" mode="aspectFit" style="width: 56px; height: 56px"></image>
<text class="successTitle">{{ $t('form.voucher.success') }}</text>
<text class="successDesc">{{ $t('form.voucher.successDesc') }}</text>
<text class="successTitle2" style="padding: 40px 0px;">{{ $t('form.voucher.successText') }}</text>
</view>
<view class="btns">
<button class="btn primaryButton" type="button" @click="start3">
{{ $t('form.voucher.start3') }}
</button>
</view>
<view class="stepsWrapper">
<view class="steps">
<view :class="['stepItem', currentStep >= 1 ? 'active' : '']"></view>
<view :class="['stepItem', currentStep >= 2 ? 'active' : '']"></view>
<view :class="['stepItem', currentStep >= 3 ? 'active' : '']"></view>
</view>
<text>{{ $t('form.personalData.personalInformation.progress') + `${completePercent}` }}</text>
</view>
</view>
</template>
<script>
import { getPersonalAuthStatus } from '@/services/user.ts';
export default {
name: '',
data() {
return {
authStatus: {}
};
},
methods: {
start3() {
uni.redirectTo({
url: `/pages/user/personalInformation/address/index?proven=${this.getProven()}&authStatus=${JSON.stringify(this.authStatus)}`
});
},
async getAuthStatus() {
const res = await getPersonalAuthStatus();
if (res && res.code === 0) {
this.authStatus = res.data;
}
},
getProven() {
if (this.authStatus.address === 1){
return true;
}else {
return false
}
}
},
created() {
this.getAuthStatus();
},
computed: {
currentStep() {
const keys = Object.keys(this.authStatus);
return keys.filter((key) => this.authStatus[key] === 1).length;
},
completePercent() {
const keys = Object.keys(this.authStatus);
return `${keys.filter((key) => this.authStatus[key] === 1).length} / ${keys.length}`;
}
}
};
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>