实名
This commit is contained in:
parent
914b5b3d2b
commit
7b0b5ac9a4
|
|
@ -103,31 +103,35 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 步骤2: 身份证上传页面 (Requirements 12.2, 12.3) -->
|
||||
<view v-if="currentStep === 2" class="step-upload">
|
||||
<view class="upload-content">
|
||||
<!-- 提示文字 -->
|
||||
<view class="upload-tip-text">
|
||||
<text class="tip-main">请上传您的身份证正反面</text>
|
||||
<text class="tip-sub">(我们仅用于实名认证)</text>
|
||||
<!-- 步骤2: 身份信息输入页面 -->
|
||||
<view v-if="currentStep === 2" class="step-input">
|
||||
<view class="input-content">
|
||||
<!-- 身份证号输入 -->
|
||||
<view class="input-group">
|
||||
<text class="input-label">请输入您的身份证号码</text>
|
||||
<view class="input-box">
|
||||
<input
|
||||
type="idcard"
|
||||
v-model="idCardNumber"
|
||||
placeholder="请输入身份证号码"
|
||||
maxlength="18"
|
||||
class="input-field"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 身份证正面 -->
|
||||
<view class="upload-card-new" @click="chooseIdCardFront">
|
||||
<view class="card-frame">
|
||||
<image v-if="idCardFront" :src="idCardFront" mode="aspectFill" class="card-image-uploaded" />
|
||||
<image v-else src="/static/real_name_card_1.png" mode="aspectFit" class="card-placeholder-img" />
|
||||
<!-- 姓名输入 -->
|
||||
<view class="input-group">
|
||||
<text class="input-label">请输入您的姓名</text>
|
||||
<view class="input-box">
|
||||
<input
|
||||
type="text"
|
||||
v-model="realName"
|
||||
placeholder="请输入姓名"
|
||||
maxlength="20"
|
||||
class="input-field"
|
||||
/>
|
||||
</view>
|
||||
<text class="card-label-new">拍照上传身份证正面</text>
|
||||
</view>
|
||||
|
||||
<!-- 身份证反面 -->
|
||||
<view class="upload-card-new" @click="chooseIdCardBack">
|
||||
<view class="card-frame">
|
||||
<image v-if="idCardBack" :src="idCardBack" mode="aspectFill" class="card-image-uploaded" />
|
||||
<image v-else src="/static/real_name_card_2.png" mode="aspectFit" class="card-placeholder-img" />
|
||||
</view>
|
||||
<text class="card-label-new">拍照上传身份证反面</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -214,16 +218,13 @@
|
|||
maskIdNumber
|
||||
} from '@/utils/format.js'
|
||||
import {
|
||||
get
|
||||
get,
|
||||
post
|
||||
} from '@/api/request.js'
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/storage.js'
|
||||
import Loading from '@/components/Loading/index.vue'
|
||||
import config from '@/config/index.js'
|
||||
|
||||
// 从统一配置获取 API 基础地址
|
||||
const BASE_URL = config.API_BASE_URL
|
||||
|
||||
export default {
|
||||
name: 'RealnamePage',
|
||||
|
|
@ -247,9 +248,9 @@
|
|||
// 认证费用 - 从配置中获取
|
||||
const verificationFee = computed(() => configStore.realNamePrice || 88)
|
||||
|
||||
// 身份证照片
|
||||
const idCardFront = ref('')
|
||||
const idCardBack = ref('')
|
||||
// 身份信息输入(二要素验证)
|
||||
const idCardNumber = ref('')
|
||||
const realName = ref('')
|
||||
|
||||
// 认证结果
|
||||
const verificationResult = ref(null)
|
||||
|
|
@ -277,8 +278,9 @@
|
|||
// 是否可以跳过支付(会员或已支付)
|
||||
const canSkipPayment = computed(() => userStore.isMember || isPaid.value)
|
||||
|
||||
// 是否可以提交(身份证号18位 + 姓名不为空)
|
||||
const canSubmit = computed(() => {
|
||||
return idCardFront.value && idCardBack.value
|
||||
return idCardNumber.value.length === 18 && realName.value.trim().length > 0
|
||||
})
|
||||
|
||||
const maskedName = computed(() => {
|
||||
|
|
@ -455,54 +457,39 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* 选择身份证正面照片
|
||||
*/
|
||||
const chooseIdCardFront = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
idCardFront.value = res.tempFilePaths[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择身份证反面照片
|
||||
*/
|
||||
const chooseIdCardBack = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
idCardBack.value = res.tempFilePaths[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交实名认证 (Requirements 12.3)
|
||||
* 提交实名认证(二要素验证:姓名+身份证号)
|
||||
*/
|
||||
const handleSubmitVerification = async () => {
|
||||
if (!canSubmit.value || submitting.value) return
|
||||
|
||||
// 简单校验身份证号格式
|
||||
const idCardRegex = /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/
|
||||
if (!idCardRegex.test(idCardNumber.value)) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的身份证号',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
|
||||
try {
|
||||
// 上传身份证照片并提交认证
|
||||
const result = await uploadIdCards()
|
||||
// 调用二要素验证接口
|
||||
const result = await post('/realname/submit', {
|
||||
realName: realName.value.trim(),
|
||||
idCard: idCardNumber.value.trim()
|
||||
})
|
||||
|
||||
if (result && (result.success || result.code === 0)) {
|
||||
if (result && (result.success || result.code === 0) && result.data?.success) {
|
||||
// 认证成功,更新状态
|
||||
userStore.setRealNameStatus(true)
|
||||
verificationResult.value = {
|
||||
name: result.data.name,
|
||||
idNumber: result.data.idNumber
|
||||
name: result.data.maskedName,
|
||||
idNumber: result.data.maskedIdCard
|
||||
}
|
||||
|
||||
// 进入结果页面 (Requirements 12.4)
|
||||
// 进入结果页面
|
||||
currentStep.value = 3
|
||||
|
||||
uni.showToast({
|
||||
|
|
@ -511,7 +498,7 @@
|
|||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: result?.message || '认证失败,请重试',
|
||||
title: result?.data?.message || result?.message || '认证失败,请检查信息是否正确',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
|
@ -526,103 +513,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传身份证照片进行实名认证
|
||||
*/
|
||||
const uploadIdCards = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const token = getToken()
|
||||
|
||||
// 同时上传正反面
|
||||
uni.uploadFile({
|
||||
url: `${BASE_URL}/api/app/realname/verify`,
|
||||
filePath: idCardFront.value,
|
||||
name: 'frontImage',
|
||||
header: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: async (uploadRes) => {
|
||||
if (uploadRes.statusCode === 200) {
|
||||
try {
|
||||
const response = JSON.parse(uploadRes.data)
|
||||
|
||||
// 检查API响应
|
||||
if (response.success || response.code === 0) {
|
||||
const data = response.data
|
||||
|
||||
// 如果需要单独上传反面
|
||||
if (data.needBackImage) {
|
||||
const backResult = await uploadBackImage(token)
|
||||
resolve(backResult)
|
||||
} else {
|
||||
resolve(response)
|
||||
}
|
||||
} else {
|
||||
reject(new Error(response.message || '认证失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
reject(new Error('解析响应失败'))
|
||||
}
|
||||
} else if (uploadRes.statusCode === 401) {
|
||||
reject(new Error('未授权,请重新登录'))
|
||||
} else {
|
||||
try {
|
||||
const errorData = JSON.parse(uploadRes.data)
|
||||
reject(new Error(errorData.message || '认证失败'))
|
||||
} catch (e) {
|
||||
reject(new Error('认证失败'))
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('上传失败:', err)
|
||||
reject(new Error('网络连接失败'))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传身份证反面
|
||||
*/
|
||||
const uploadBackImage = (token) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: `${BASE_URL}/api/app/realname/verify/back`,
|
||||
filePath: idCardBack.value,
|
||||
name: 'backImage',
|
||||
header: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
success: (uploadRes) => {
|
||||
if (uploadRes.statusCode === 200) {
|
||||
try {
|
||||
const response = JSON.parse(uploadRes.data)
|
||||
|
||||
if (response.success || response.code === 0) {
|
||||
resolve(response)
|
||||
} else {
|
||||
reject(new Error(response.message || '上传失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
reject(new Error('解析响应失败'))
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const errorData = JSON.parse(uploadRes.data)
|
||||
reject(new Error(errorData.message || '上传失败'))
|
||||
} catch (e) {
|
||||
reject(new Error('上传失败'))
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
reject(new Error('网络连接失败'))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成认证,返回上一页
|
||||
*/
|
||||
|
|
@ -679,8 +569,8 @@
|
|||
submitting,
|
||||
currentStep,
|
||||
verificationFee,
|
||||
idCardFront,
|
||||
idCardBack,
|
||||
idCardNumber,
|
||||
realName,
|
||||
isVerified,
|
||||
canSubmit,
|
||||
canSkipPayment,
|
||||
|
|
@ -692,8 +582,6 @@
|
|||
handleNextStep,
|
||||
handleContactService,
|
||||
handleStepClick,
|
||||
chooseIdCardFront,
|
||||
chooseIdCardBack,
|
||||
handleSubmitVerification,
|
||||
handleDone
|
||||
}
|
||||
|
|
@ -1190,7 +1078,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 步骤2: 上传页面
|
||||
// 步骤2: 身份信息输入页面
|
||||
.step-input {
|
||||
.input-content {
|
||||
padding: 40rpx 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 40rpx;
|
||||
|
||||
.input-group {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
|
||||
.input-label {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.input-box {
|
||||
background: #F6F8FA;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
|
||||
.input-field {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤2: 上传页面(保留旧样式兼容)
|
||||
.step-upload {
|
||||
.upload-content {
|
||||
padding: 40rpx 30rpx;
|
||||
|
|
|
|||
|
|
@ -98,5 +98,14 @@
|
|||
"SecretId": "AKIDVyMfzKZdZP8zkNyOdsFuSsBJDB7EScs0",
|
||||
"SecretKey": "89GWr7JPWYTL8ueHlAYowGZnvzKZjqs9",
|
||||
"Region": "ap-shanghai"
|
||||
},
|
||||
"RealName": {
|
||||
"Provider": "Tencent",
|
||||
"Tencent": {
|
||||
"SecretId": "AKIDVyMfzKZdZP8zkNyOdsFuSsBJDB7EScs0",
|
||||
"SecretKey": "89GWr7JPWYTL8ueHlAYowGZnvzKZjqs9",
|
||||
"Region": "ap-shanghai",
|
||||
"SimilarityThreshold": 80
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user