upload project
This commit is contained in:
commit
06961cae04
422 changed files with 110626 additions and 0 deletions
152
subpackages/realname/camera-verify.js
Normal file
152
subpackages/realname/camera-verify.js
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
Page({
|
||||
data:{
|
||||
photoPath: '',
|
||||
livenessSteps: ['请正对镜头', '请张张嘴', '请左右摇头', '请眨眨眼'],
|
||||
stepIndex: 0,
|
||||
isCapturing: false,
|
||||
isUploading: false
|
||||
},
|
||||
onLoad(){
|
||||
// 页面加载时检查并申请摄像头权限
|
||||
this.checkCameraPermission();
|
||||
},
|
||||
async checkCameraPermission(){
|
||||
try{
|
||||
const setting = await new Promise((resolve) => {
|
||||
wx.getSetting({ success: resolve, fail: () => resolve({}) });
|
||||
});
|
||||
// 检查是否已授权
|
||||
if(!setting.authSetting || !setting.authSetting['scope.camera']){
|
||||
// 未授权,主动申请
|
||||
const result = await new Promise((resolve) => {
|
||||
wx.authorize({
|
||||
scope: 'scope.camera',
|
||||
success: () => resolve({ granted: true }),
|
||||
fail: () => resolve({ granted: false })
|
||||
});
|
||||
});
|
||||
if(!result.granted){
|
||||
// 用户拒绝了授权,需要引导去设置页
|
||||
wx.showModal({
|
||||
title: '需要摄像头权限',
|
||||
content: '为了完成实名认证,需要访问您的摄像头。请在设置中开启摄像头权限。',
|
||||
confirmText: '去设置',
|
||||
success: (res) => {
|
||||
if(res.confirm){
|
||||
wx.openSetting({
|
||||
success: (settingRes) => {
|
||||
if(settingRes.authSetting && settingRes.authSetting['scope.camera']){
|
||||
wx.showToast({ title: '授权成功', icon: 'success' });
|
||||
} else {
|
||||
wx.showToast({ title: '授权失败,无法使用摄像头', icon: 'none' });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}catch(err){
|
||||
console.error('检查摄像头权限失败:', err);
|
||||
}
|
||||
},
|
||||
onCameraError(e){
|
||||
console.error('camera error', e);
|
||||
let msg = '摄像头打开失败';
|
||||
if(e.detail && e.detail.errMsg){
|
||||
if(e.detail.errMsg.includes('permission')){
|
||||
msg = '摄像头权限被拒绝,请前往设置开启';
|
||||
} else if(e.detail.errMsg.includes('not available')){
|
||||
msg = '摄像头不可用,请检查设备';
|
||||
}
|
||||
}
|
||||
wx.showModal({
|
||||
title: '摄像头错误',
|
||||
content: msg,
|
||||
confirmText: '去设置',
|
||||
success: (res) => {
|
||||
if(res.confirm){
|
||||
wx.openSetting();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
get currentHint(){
|
||||
const { livenessSteps, stepIndex } = this.data;
|
||||
return livenessSteps[Math.min(stepIndex, livenessSteps.length - 1)] || '';
|
||||
},
|
||||
canCapture(){
|
||||
const { stepIndex, livenessSteps } = this.data;
|
||||
return stepIndex >= livenessSteps.length;
|
||||
},
|
||||
onNextAction(){
|
||||
const { stepIndex, livenessSteps } = this.data;
|
||||
if (stepIndex < livenessSteps.length) {
|
||||
const nextIndex = stepIndex + 1;
|
||||
this.setData({ stepIndex: nextIndex }, () => {
|
||||
// 若所有动作完成,自动拍照
|
||||
if (nextIndex >= livenessSteps.length) {
|
||||
setTimeout(() => {
|
||||
this.onCapture();
|
||||
}, 600);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
async onCapture(){
|
||||
if (!this.canCapture()){
|
||||
wx.showToast({ title: '请先完成动作提示', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if(this.data.isCapturing){
|
||||
return; // 防止重复点击
|
||||
}
|
||||
this.setData({ isCapturing: true });
|
||||
wx.showLoading({ title: '拍照中...', mask: true });
|
||||
try{
|
||||
const ctx = wx.createCameraContext();
|
||||
const res = await new Promise((resolve, reject)=>{
|
||||
ctx.takePhoto({
|
||||
quality: 'high',
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
// 临时文件需要及时处理,这里先保存路径
|
||||
// 注意:tempImagePath 仅在当前会话有效,需要尽快上传
|
||||
this.setData({
|
||||
photoPath: res.tempImagePath,
|
||||
isCapturing: false
|
||||
});
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '拍照成功', icon: 'success', duration: 1500 });
|
||||
}catch(err){
|
||||
this.setData({ isCapturing: false });
|
||||
wx.hideLoading();
|
||||
console.error('拍照失败:', err);
|
||||
let msg = '拍照失败,请重试';
|
||||
if(err.errMsg){
|
||||
if(err.errMsg.includes('permission')){
|
||||
msg = '摄像头权限被拒绝,请前往设置开启';
|
||||
} else if(err.errMsg.includes('not available')){
|
||||
msg = '摄像头不可用';
|
||||
}
|
||||
}
|
||||
wx.showToast({ title: msg, icon: 'none', duration: 2000 });
|
||||
}
|
||||
},
|
||||
onRetake(){
|
||||
this.setData({ photoPath: '' });
|
||||
},
|
||||
onSubmit(){
|
||||
if(!this.data.photoPath){
|
||||
wx.showToast({ title: '请先拍照', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
// TODO: 上传并提交认证
|
||||
wx.showToast({ title: '已提交', icon: 'success' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
12
subpackages/realname/camera-verify.json
Normal file
12
subpackages/realname/camera-verify.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"navigationBarTitleText": "摄像头认证",
|
||||
"navigationBarBackgroundColor": "#000000",
|
||||
"navigationBarTextStyle": "white",
|
||||
"permission": {
|
||||
"scope.camera": {
|
||||
"desc": "需要使用您的摄像头进行实名认证,以核实您的真实身份"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
subpackages/realname/camera-verify.wxml
Normal file
38
subpackages/realname/camera-verify.wxml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<view class="camera-verify-container">
|
||||
<view class="header">
|
||||
<text class="title">摄像头实名认证</text>
|
||||
<text class="desc">请正对镜头,确保光线充足,按提示完成拍摄</text>
|
||||
</view>
|
||||
|
||||
<!-- 顶部动作说明(始终显示当前动作,强调眨眨眼) -->
|
||||
<view class="top-hint">
|
||||
<text class="top-hint-text">动作说明:{{livenessSteps[stepIndex] || '请眨眨眼'}}</text>
|
||||
</view>
|
||||
|
||||
<view class="camera-box">
|
||||
<camera device-position="front" flash="off" class="camera" mode="normal" frame-size="medium" binderror="onCameraError"></camera>
|
||||
<view class="liveness-hint">
|
||||
<text class="hint-text">{{livenessSteps[stepIndex]}}</text>
|
||||
<view class="hint-actions">
|
||||
<button class="hint-btn" bindtap="onNextAction">我已完成</button>
|
||||
</view>
|
||||
<view class="hint-dots">
|
||||
<block wx:for="{{livenessSteps}}" wx:key="index">
|
||||
<view class="dot {{index <= stepIndex-1 ? 'done' : ''}}"></view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="actions">
|
||||
<button class="btn capture {{stepIndex >= livenessSteps.length && !isCapturing ? 'enabled' : 'disabled'}}" bindtap="onCapture" disabled="{{isCapturing}}">{{isCapturing ? '拍照中...' : '拍照'}}</button>
|
||||
<button class="btn retake" wx:if="{{photoPath}}" bindtap="onRetake" disabled="{{isUploading}}">重拍</button>
|
||||
<button class="btn submit {{photoPath && !isUploading ? 'enabled' : 'disabled'}}" bindtap="onSubmit" disabled="{{isUploading}}">{{isUploading ? '提交中...' : '提交认证'}}</button>
|
||||
</view>
|
||||
|
||||
<view class="preview" wx:if="{{photoPath}}">
|
||||
<image class="preview-image" src="{{photoPath}}" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
176
subpackages/realname/camera-verify.wxss
Normal file
176
subpackages/realname/camera-verify.wxss
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
.camera-verify-container {
|
||||
min-height: 100vh;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 24rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
|
||||
.top-hint {
|
||||
margin: 8rpx 0 20rpx 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top-hint-text {
|
||||
font-size: 26rpx;
|
||||
color: #ffd666;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.camera-box {
|
||||
width: 560rpx;
|
||||
height: 560rpx;
|
||||
border: 4rpx solid #333;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #111;
|
||||
margin: 0 auto 32rpx auto;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.camera {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.liveness-hint {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 16rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.hint-text {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.hint-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.hint-btn {
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
padding: 0 24rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #2eadfb;
|
||||
color: #fff;
|
||||
border: none;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.hint-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.hint-dots {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
gap: 8rpx;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
background: #666;
|
||||
}
|
||||
|
||||
.dot.done {
|
||||
background: #2eadfb;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
justify-content: space-between;
|
||||
margin: 20rpx 0;
|
||||
width: 100%;
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 16rpx;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.btn.capture {
|
||||
background: #2b8a3e;
|
||||
}
|
||||
|
||||
.btn.capture.enabled {
|
||||
background: #2b8a3e;
|
||||
}
|
||||
|
||||
.btn.capture.disabled {
|
||||
background: #555;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.btn.retake {
|
||||
background: #6c757d;
|
||||
}
|
||||
|
||||
.btn.submit {
|
||||
background: #494949;
|
||||
}
|
||||
|
||||
.btn.submit.enabled {
|
||||
background: linear-gradient(124deg, #ff6460 1.58%, #ec42c8 34.28%, #435cff 54%, #00d5ff 84.05%);
|
||||
}
|
||||
|
||||
.btn.submit.disabled {
|
||||
background: #494949;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.preview {
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
border-radius: 12rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
42
subpackages/realname/faceid-webview.js
Normal file
42
subpackages/realname/faceid-webview.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
Page({
|
||||
data:{ url: '' },
|
||||
onLoad(options){
|
||||
if(options && options.url){
|
||||
try{
|
||||
const decoded = decodeURIComponent(options.url);
|
||||
this.setData({ url: decoded });
|
||||
}catch(e){
|
||||
this.setData({ url: options.url });
|
||||
}
|
||||
}
|
||||
else{
|
||||
// 如果没有URL,直接跳转到验证成功页面
|
||||
wx.redirectTo({
|
||||
url: '/subpackages/realname/verify-success'
|
||||
});
|
||||
}
|
||||
},
|
||||
// 监听网页传来的消息
|
||||
onWebViewMessage(e){
|
||||
console.log('收到网页消息:', e.detail.data);
|
||||
const data = e.detail.data || {};
|
||||
|
||||
// 检查是否是认证成功消息
|
||||
// 根据腾讯云 FaceID 的实际回调格式调整判断条件
|
||||
if(data.type === 'verify_success' || data.success === true || data.status === 'success' || data.verifySuccess){
|
||||
// 跳转到验证成功页面
|
||||
setTimeout(() => {
|
||||
wx.redirectTo({
|
||||
url: '/subpackages/realname/verify-success'
|
||||
});
|
||||
}, 500); // 延迟500ms确保网页消息处理完成
|
||||
}
|
||||
},
|
||||
// 页面显示时检查认证状态
|
||||
onShow(){
|
||||
// 如果认证已完成,可以直接跳转
|
||||
// 注意:实际逻辑可能需要根据腾讯云 FaceID 的回调方式调整
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
7
subpackages/realname/faceid-webview.json
Normal file
7
subpackages/realname/faceid-webview.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"navigationBarTitleText": "实人认证",
|
||||
"navigationBarBackgroundColor": "#000000",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
|
||||
|
||||
5
subpackages/realname/faceid-webview.wxml
Normal file
5
subpackages/realname/faceid-webview.wxml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<view class="faceid-webview-container">
|
||||
<web-view src="{{url}}" bindmessage="onWebViewMessage"></web-view>
|
||||
</view>
|
||||
|
||||
|
||||
1
subpackages/realname/faceid-webview.wxss
Normal file
1
subpackages/realname/faceid-webview.wxss
Normal file
|
|
@ -0,0 +1 @@
|
|||
/* subpackages/realname/faceid-webview.wxss */
|
||||
114
subpackages/realname/realname.js
Normal file
114
subpackages/realname/realname.js
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
Page({
|
||||
data: {
|
||||
realName: '',
|
||||
idNumber: '',
|
||||
canProceed: false,
|
||||
idError: '',
|
||||
showConfirm: false
|
||||
},
|
||||
// 简易中国二代身份证校验:格式+生日+校验位
|
||||
isValidChineseID(id) {
|
||||
if (!id || typeof id !== 'string') return false;
|
||||
const upper = id.trim().toUpperCase();
|
||||
if (!/^\d{17}[\dX]$/.test(upper)) return false;
|
||||
// 校验生日是否合法
|
||||
const y = parseInt(upper.slice(6, 10), 10);
|
||||
const m = parseInt(upper.slice(10, 12), 10);
|
||||
const d = parseInt(upper.slice(12, 14), 10);
|
||||
const date = new Date(y, m - 1, d);
|
||||
if (!(date.getFullYear() === y && date.getMonth() + 1 === m && date.getDate() === d)) return false;
|
||||
// 校验位
|
||||
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
||||
const parity = ['1','0','X','9','8','7','6','5','4','3','2'];
|
||||
let sum = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
sum += parseInt(upper[i], 10) * weights[i];
|
||||
}
|
||||
const code = parity[sum % 11];
|
||||
return code === upper[17];
|
||||
},
|
||||
onRealNameInput(e) {
|
||||
const realName = e.detail.value || '';
|
||||
this.setData({ realName }, this.updateProceedState);
|
||||
},
|
||||
onIdNumberInput(e) {
|
||||
// 仅保留数字与X,统一为大写
|
||||
const raw = (e.detail.value || '').toString();
|
||||
const cleaned = raw.replace(/[^0-9xX]/g, '').toUpperCase();
|
||||
const idNumber = cleaned;
|
||||
this.setData({ idNumber }, () => {
|
||||
// 输入中先不显示错误,但实时控制按钮可用
|
||||
this.updateProceedState(false);
|
||||
});
|
||||
},
|
||||
updateProceedState(showError = true) {
|
||||
const { realName, idNumber } = this.data;
|
||||
const trimmed = (idNumber || '').trim();
|
||||
const valid = this.isValidChineseID(trimmed);
|
||||
const ok = realName.trim().length > 0 && valid;
|
||||
const idError = !trimmed ? '' : (valid ? '' : '身份证格式不正确,请输入18位二代身份证');
|
||||
this.setData({ canProceed: ok, idError: showError ? idError : '' });
|
||||
},
|
||||
onIdBlur() {
|
||||
// 失去焦点时显示错误
|
||||
this.updateProceedState(true);
|
||||
},
|
||||
onNext() {
|
||||
const { realName, idNumber, canProceed } = this.data;
|
||||
if (!realName.trim()) {
|
||||
wx.showToast({ title: '请输入真实姓名', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (!this.isValidChineseID((idNumber || '').trim())) {
|
||||
this.setData({ idError: '身份证格式不正确,请输入18位二代身份证' });
|
||||
wx.showToast({ title: '身份证格式不正确', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (!canProceed) {
|
||||
wx.showToast({ title: '请完善信息', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
// 打开确认弹框
|
||||
this.setData({ showConfirm: true });
|
||||
},
|
||||
onConfirmCancel() {
|
||||
this.setData({ showConfirm: false });
|
||||
},
|
||||
async onConfirmAgree() {
|
||||
this.setData({ showConfirm: false });
|
||||
wx.navigateTo({
|
||||
url: `/subpackages/realname/faceid-webview?url=${encodeURIComponent('')}`
|
||||
});
|
||||
return;
|
||||
//
|
||||
try {
|
||||
const apiClient = require('../../../utils/api-client.js');
|
||||
const response = await apiClient.post('/api/faceid/create', {
|
||||
realName: this.data.realName,
|
||||
idNumber: this.data.idNumber,
|
||||
redirectUrl: encodeURIComponent('/subpackages/realname/faceid-webview')
|
||||
});
|
||||
|
||||
// 期望后端返回 { code:0, data: { certUrl: 'https://...' } }
|
||||
const certUrl = response?.data?.certUrl || response?.certUrl;
|
||||
if (certUrl) {
|
||||
wx.navigateTo({
|
||||
url: `/subpackages/realname/faceid-webview?url=${encodeURIComponent(certUrl)}`
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: response?.message || '创建认证会话失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建FaceID会话失败:', error);
|
||||
wx.showToast({
|
||||
title: error?.message || '网络异常,请稍后重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
7
subpackages/realname/realname.json
Normal file
7
subpackages/realname/realname.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"navigationBarTitleText": "实名认证",
|
||||
"navigationBarBackgroundColor": "#000000",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
|
||||
|
||||
44
subpackages/realname/realname.wxml
Normal file
44
subpackages/realname/realname.wxml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<view class="realname-container">
|
||||
<view class="top-image-box">
|
||||
<image class="check-image" src="/images/self/check.png" mode="widthFix" />
|
||||
</view>
|
||||
|
||||
<view class="form-row">
|
||||
<text class="label">真实姓名</text>
|
||||
<input class="input" placeholder="请输入真实姓名" value="{{realName}}" bindinput="onRealNameInput" />
|
||||
</view>
|
||||
|
||||
<view class="form-row">
|
||||
<text class="label">身份证号</text>
|
||||
<input class="input {{idError ? 'error' : ''}}" placeholder="请输入身份证号" value="{{idNumber}}" bindinput="onIdNumberInput" bindblur="onIdBlur" />
|
||||
<text wx:if="{{idError}}" class="error-text">{{idError}}</text>
|
||||
</view>
|
||||
|
||||
<view class="action-row">
|
||||
<button class="next-btn {{canProceed ? 'enabled' : 'disabled'}}" bindtap="onNext">下一步</button>
|
||||
</view>
|
||||
|
||||
<view class="tips-box">
|
||||
<text class="tips-title">温馨提示:</text>
|
||||
<view class="tips-list">
|
||||
<text class="tips-item">1. 目前仅支持二代身份证认证</text>
|
||||
<text class="tips-item">2. 请您填写正确的身份信息实名认证,以核实本人身份,保障账户安全</text>
|
||||
<text class="tips-item">3. 您所提交的身份信息仅仅被用于身份核验,会严格保密</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 确认弹框 -->
|
||||
<view wx:if="{{showConfirm}}" class="confirm-mask" bindtap="onConfirmCancel"></view>
|
||||
<view wx:if="{{showConfirm}}" class="confirm-modal">
|
||||
<view class="confirm-title">提示您注意</view>
|
||||
<view class="confirm-content">
|
||||
<text>为实现核实您真实身份并完成实名认证的目的,您需要向我们提供您的真实姓名、身份证号码。我们承诺此类信息将不会用于任何其他您未授权的场景,并且会对此类信息采取加密等安全保护技术措施。点击【同意】则表示本人同意我们根据以上的方式和目的收集、使用及储存您提供的本人身份信息用于实名认证。</text>
|
||||
</view>
|
||||
<view class="confirm-actions">
|
||||
<button class="confirm-btn cancel" bindtap="onConfirmCancel">取消</button>
|
||||
<button class="confirm-btn ok" bindtap="onConfirmAgree">同意</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
157
subpackages/realname/realname.wxss
Normal file
157
subpackages/realname/realname.wxss
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
.realname-container {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: #000000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 32rpx 80rpx 32rpx;
|
||||
}
|
||||
|
||||
.top-image-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.check-image {
|
||||
width: 420rpx;
|
||||
height: 150rpx;
|
||||
margin: 100rpx 0;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 42rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #bfbfbf;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 84rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #1a1a1a;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
padding: 0 28rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid #333333;
|
||||
}
|
||||
|
||||
.input.error {
|
||||
border: 1rpx solid #ff4d4f;
|
||||
}
|
||||
|
||||
.error-text{
|
||||
margin-top: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
width: 100%;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 44rpx;
|
||||
color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.next-btn.disabled {
|
||||
background: #494949;
|
||||
}
|
||||
|
||||
.next-btn.enabled {
|
||||
background: linear-gradient(124deg, #ff6460 1.58%, #ec42c8 34.28%, #435cff 54%, #00d5ff 84.05%);
|
||||
}
|
||||
|
||||
.next-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.tips-box{
|
||||
width: 100%;
|
||||
margin-top: 58rpx;
|
||||
padding: 24rpx;
|
||||
}
|
||||
.tips-title{
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.tips-list{display:flex;flex-direction:column;gap:10rpx;}
|
||||
.tips-item{font-size:24rpx;color:#555;line-height:1.6;}
|
||||
|
||||
|
||||
/* 自定义确认弹框 */
|
||||
.confirm-mask{
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 999;
|
||||
}
|
||||
.confirm-modal{
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 86%;
|
||||
max-width: 640rpx;
|
||||
background: #0e0e0e;
|
||||
color: #ffffff;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx 28rpx;
|
||||
z-index: 1000;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid #222;
|
||||
}
|
||||
.confirm-title{
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.confirm-content{
|
||||
font-size: 26rpx;
|
||||
line-height: 1.8;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.confirm-actions{
|
||||
margin-top: 28rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 24rpx;
|
||||
}
|
||||
.confirm-btn{
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
border-radius: 16rpx;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
}
|
||||
.confirm-btn::after{border:none;}
|
||||
.confirm-btn.cancel{
|
||||
background: linear-gradient(135deg, #242424 0%, #2eadfb 100%);
|
||||
}
|
||||
.confirm-btn.ok{
|
||||
background: linear-gradient(135deg, #c38eff 0%, #559cff 100%);
|
||||
}
|
||||
8
subpackages/realname/verify-success.js
Normal file
8
subpackages/realname/verify-success.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Page({
|
||||
data: {},
|
||||
onLoad(options) {
|
||||
// 可以接收认证结果参数
|
||||
console.log('实名认证成功页面', options);
|
||||
}
|
||||
});
|
||||
|
||||
6
subpackages/realname/verify-success.json
Normal file
6
subpackages/realname/verify-success.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"navigationBarTitleText": "认证成功",
|
||||
"navigationBarBackgroundColor": "#000000",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
|
||||
10
subpackages/realname/verify-success.wxml
Normal file
10
subpackages/realname/verify-success.wxml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<view class="verify-success-container">
|
||||
<view class="badge-box">
|
||||
<image class="badge-image" src="/images/self/approve_badge.png" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<view class="success-text-box">
|
||||
<text class="success-text">恭喜你,实名认证成功</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
37
subpackages/realname/verify-success.wxss
Normal file
37
subpackages/realname/verify-success.wxss
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
.verify-success-container {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: #000000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
/* justify-content: center; */
|
||||
padding: 40rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.badge-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 120rpx;
|
||||
}
|
||||
|
||||
.badge-image {
|
||||
width: 320rpx;
|
||||
height: 320rpx;
|
||||
}
|
||||
|
||||
.success-text-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-top: 160rpx;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
font-size: 64rpx;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue