You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

433 lines
9.0 KiB
Vue

<!-- pages/queue/index.vue -->
<template>
<view class="queue-container">
<!-- 页面标题 -->
<div class="top-div">
<div></div>
<tn-button width="80px" height="32px" :plain="true" text-color="#0099ff" @click="backToIndex">
<uni-icons type="arrow-left" size="18" color="#0099ff" style="margin-right: 5px;"></uni-icons>
</tn-button>
</div>
<!-- 表单区域 -->
<view class="form-container">
<form @submit="handleSubmit">
<!-- -->
<view class="form-item">
<text class="form-label">姓名</text>
<input v-model="formData.name" class="form-input" placeholder="请输入您的真实姓名" type="text" maxlength="10"
@blur="validateName" />
<text v-if="nameError" class="error-text">{{ nameError }}</text>
</view>
<!-- 手机号码输入 -->
<view class="form-item">
<text class="form-label">手机号码</text>
<input v-model="formData.phone" class="form-input" placeholder="请输入11位手机号码" type="number"
maxlength="11" @blur="validatePhone" />
<text v-if="phoneError" class="error-text">{{ phoneError }}</text>
</view>
<!-- 身份证号码输入 -->
<view class="form-item">
<text class="form-label">身份证号码</text>
<IDCardInput v-model="formData.idCard" @change="validateIDCard" />
<text v-if="idCardError" class="error-text">{{ idCardError }}</text>
</view>
<!-- 提交按钮 -->
<button class="submit-btn" :class="{ 'disabled': !formValid }" :disabled="!formValid || isLoading"
form-type="submit">
<text v-if="!isLoading">下一步</text>
<view v-else class="loading-wrapper">
<uni-load-more :status="'loading'" color="#007AFF" size="20"></uni-load-more>
<text>验证中...</text>
</view>
</button>
</form>
</view>
<!-- 实名认证提示弹窗 -->
<uni-popup ref="authPopup" type="center" :is-mask-click="false">
<view class="popup-content auth-popup">
<view class="popup-header">
<text class="popup-title">实名认证提示</text>
</view>
<view class="popup-body">
<text class="auth-icon">🔐</text>
<text class="auth-message">您尚未完成实名认证</text>
<text class="auth-detail">请先完成实名认证后才能办理业务</text>
</view>
<view class="popup-footer">
<button class="popup-btn secondary" @click="closeAuthPopup">稍后认证</button>
<button class="popup-btn primary" @click="gotoRealNameAuth">去认证</button>
</view>
</view>
</uni-popup>
<!-- 网络错误提示 -->
<uni-popup ref="errorPopup" type="center">
<view class="popup-content error-popup">
<text class="error-icon">⚠️</text>
<text class="error-message">{{ errorMessage }}</text>
<button class="error-btn" @click="closeErrorPopup"></button>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
computed
} from 'vue';
import {
onLoad
} from '@dcloudio/uni-app';
import IDCardInput from '@/components/IDCardInput.vue';
import {
validateChineseName,
validatePhoneNumber,
validateIDCard
} from '@/utils/validator';
// import {
// checkRealNameAuth,
// getBusinessList
// } from '@/utils/api';
// 表单数据
const formData = reactive({
name: '',
phone: '',
idCard: ''
});
// 错误信息
const nameError = ref('');
const phoneError = ref('');
const idCardError = ref('');
// 状态控制
const isLoading = ref(false);
const errorMessage = ref('');
// 弹窗引用
const authPopup = ref(null);
const errorPopup = ref(null);
// 表单验证状态
const formValid = computed(() => {
return formData.name &&
formData.phone &&
formData.idCard &&
!nameError.value &&
!phoneError.value &&
!idCardError.value;
});
// 验证姓名
const validateName = () => {
const result = validateChineseName(formData.name);
nameError.value = result.valid ? '' : result.message;
};
// 验证手机号
const validatePhone = () => {
const result = validatePhoneNumber(formData.phone);
phoneError.value = result.valid ? '' : result.message;
};
// 验证身份证
const handleIdCardChange = (value, isValid) => {
idCardError.value = isValid ? '' : '请输入正确的身份证号码';
};
// 表单提交
const handleSubmit = async () => {
// 验证所有字段
validateName();
validatePhone();
if (nameError.value || phoneError.value || idCardError.value) {
showError('请检查填写的信息是否正确');
return;
}
isLoading.value = true;
try {
// 实名认证通过,跳转到业务选择页面
uni.navigateTo({
url: `/pages/queue/business-select?name=${encodeURIComponent(formData.name)}&phone=${formData.phone}&idCard=${formData.idCard}`,
success: () => {
// 清空表单数据
Object.keys(formData).forEach(key => formData[key] = '');
}
});
} catch (error) {
console.error('实名验证失败:', error);
showError(error.message || '网络异常,请稍后重试');
} finally {
isLoading.value = false;
}
};
// 显示错误提示
const showError = (message) => {
errorMessage.value = message;
errorPopup.value.open();
};
// 关闭错误提示
const closeErrorPopup = () => {
errorPopup.value.close();
};
// 关闭实名认证提示
const closeAuthPopup = () => {
authPopup.value.close();
};
// 跳转到实名认证页面
const gotoRealNameAuth = () => {
authPopup.value.close();
uni.navigateTo({
url: '/pages/auth/real-name'
});
};
const backToIndex = () => {
uni.navigateTo({
url: '/pages/index/index'
})
}
// 页面加载
onLoad(() => {
// 可以在这里预填充测试数据(开发环境)
if (process.env.NODE_ENV === 'development') {
formData.name = '测试用户';
formData.phone = '13800138000';
formData.idCard = '110101199003077436';
}
});
</script>
<style scoped>
.queue-container {
display: flex;
flex-direction: column;
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.page-header {
text-align: center;
margin-bottom: 60rpx;
}
.top-div {
display: flex;
justify-content: space-between;
background-color: #fff;
padding: 6vh 20px 10px 20px;
}
.page-title {
font-size: 48rpx;
font-weight: bold;
color: #1a1a1a;
display: block;
margin-bottom: 16rpx;
}
.page-subtitle {
font-size: 28rpx;
color: #666;
display: block;
}
.form-container {
flex: 1;
min-height: 100%;
background: white;
padding: 48rpx 40rpx;
}
.form-item {
margin-bottom: 40rpx;
}
.form-label {
display: block;
font-size: 30rpx;
color: #333;
font-weight: 500;
margin-bottom: 20rpx;
}
.form-input {
width: 100%;
height: 88rpx;
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx;
background: #fafafa;
box-sizing: border-box;
}
.form-input:focus {
border-color: #007AFF;
background: white;
}
.error-text {
display: block;
font-size: 24rpx;
color: #ff4444;
margin-top: 8rpx;
}
.submit-btn {
width: 100%;
height: 96rpx;
background: linear-gradient(135deg, #007AFF 0%, #0056CC 100%);
color: white;
border-radius: 16rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
margin-top: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.submit-btn.disabled {
background: #cccccc;
opacity: 0.6;
}
.loading-wrapper {
display: flex;
align-items: center;
gap: 16rpx;
}
/* 实名认证弹窗样式 */
.auth-popup {
width: 600rpx;
max-width: 90vw;
background: white;
border-radius: 24rpx;
overflow: hidden;
}
.popup-header {
padding: 40rpx 40rpx 20rpx;
text-align: center;
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.popup-body {
padding: 40rpx;
text-align: center;
}
.auth-icon {
font-size: 80rpx;
display: block;
margin-bottom: 24rpx;
}
.auth-message {
font-size: 32rpx;
font-weight: 600;
color: #333;
display: block;
margin-bottom: 16rpx;
}
.auth-detail {
font-size: 26rpx;
color: #666;
display: block;
line-height: 1.5;
}
.popup-footer {
display: flex;
gap: 20rpx;
padding: 0 40rpx 40rpx;
}
.popup-btn {
flex: 1;
height: 80rpx;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 500;
border: none;
}
.popup-btn.secondary {
background: #f0f0f0;
color: #666;
}
.popup-btn.primary {
background: #007AFF;
color: white;
}
/* 错误弹窗样式 */
.error-popup {
width: 500rpx;
padding: 60rpx 40rpx;
background: white;
border-radius: 24rpx;
text-align: center;
}
.error-icon {
font-size: 60rpx;
display: block;
margin-bottom: 24rpx;
}
.error-message {
font-size: 28rpx;
color: #333;
display: block;
margin-bottom: 40rpx;
line-height: 1.5;
}
.error-btn {
width: 100%;
height: 80rpx;
background: #007AFF;
color: white;
border-radius: 12rpx;
font-size: 28rpx;
border: none;
}
/* 响应式设计 */
@media (max-width: 750px) {
.queue-container {
padding: 32rpx 24rpx;
}
.form-container {
padding: 40rpx 32rpx;
}
}
</style>