Files
financial/src/views/auth/signup.vue

622 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang='ts' setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const formData = ref({
phoneNumber: "",
password: "",
confirmPassword: "",
realName: "",
idCard: "",
inviteCode: "",
});
const agreed = ref(false);
const showPassword = ref(false);
const showConfirmPassword = ref(false);
function handleSignup() {
// 验证手机号
if (!formData.value.phoneNumber) {
// TODO: 显示提示信息
return;
}
// 验证密码
if (!formData.value.password) {
// TODO: 提示输入密码
return;
}
// 验证确认密码
if (formData.value.password !== formData.value.confirmPassword) {
// TODO: 提示密码不一致
return;
}
// 验证姓名
if (!formData.value.realName) {
// TODO: 提示输入姓名
return;
}
// 验证身份证
if (!formData.value.idCard) {
// TODO: 提示输入身份证
return;
}
if (!agreed.value) {
// TODO: 提示需要同意条款
return;
}
// TODO: 实现注册逻辑
console.log("注册", formData.value);
}
function handleLogin() {
router.push("/auth/login");
}
function goToTerms(type: "service" | "privacy") {
router.push(`/auth/term?type=${type}`);
}
</script>
<template>
<ion-page>
<ion-content :fullscreen="true" class="signup-page">
<!-- 渐变背景 -->
<div class="gradient-bg" />
<!-- 装饰元素 - 顶部飞鸟 -->
<div class="decoration-top">
<div class="bird bird-1" />
<div class="bird bird-2" />
<div class="bird bird-3" />
</div>
<!-- 主要内容区域 -->
<div class="content-wrapper">
<!-- 顶部Logo和标题 -->
<div class="header-section">
<div class="emblem">
<div class="emblem-circle">
<div class="emblem-inner">
<div class="star">
</div>
<div class="emblem-text">
中华人民共和国
</div>
</div>
</div>
</div>
<h1 class="welcome-title">
创建账号
</h1>
<h2 class="welcome-subtitle">
加入深化改革平台
</h2>
</div>
<!-- 注册表单 -->
<div class="form-section">
<!-- 手机号输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.phoneNumber"
type="tel"
placeholder="请输入手机号"
class="custom-input"
:maxlength="11"
/>
</ion-item>
<!-- 密码输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.password"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入密码"
class="custom-input"
/>
<ion-icon
slot="end"
:icon="showPassword ? 'eye-outline' : 'eye-off-outline'"
class="password-toggle"
@click="showPassword = !showPassword"
/>
</ion-item>
<!-- 确认密码输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.confirmPassword"
:type="showConfirmPassword ? 'text' : 'password'"
placeholder="请确认密码"
class="custom-input"
/>
<ion-icon
slot="end"
:icon="showConfirmPassword ? 'eye-outline' : 'eye-off-outline'"
class="password-toggle"
@click="showConfirmPassword = !showConfirmPassword"
/>
</ion-item>
<!-- 姓名输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.realName"
type="text"
placeholder="请输入真实姓名"
class="custom-input"
/>
</ion-item>
<!-- 身份证输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.idCard"
type="text"
placeholder="请输入身份证号码"
class="custom-input"
:maxlength="18"
/>
</ion-item>
<!-- 邀请码输入 -->
<ion-item lines="none" class="input-item">
<ion-input
v-model="formData.inviteCode"
type="text"
placeholder="请输入邀请码(选填)"
class="custom-input"
/>
</ion-item>
<!-- 协议同意 -->
<div class="agreement-section">
<ion-checkbox v-model="agreed" class="agreement-checkbox" />
<span class="agreement-text">
我已阅读并同意
<a class="link-service" @click="goToTerms('service')">服务条款</a>
<a class="link-privacy" @click="goToTerms('privacy')">隐私政策</a>
</span>
</div>
<!-- 注册按钮 -->
<ion-button
expand="block"
class="signup-button"
@click="handleSignup"
>
注册
</ion-button>
<!-- 登录按钮 -->
<ion-button
expand="block"
fill="outline"
class="login-button"
@click="handleLogin"
>
已有账号立即登录
</ion-button>
</div>
</div>
<!-- 底部装饰 - 天安门和飞鸟 -->
<div class="decoration-bottom">
<div class="building-wrapper">
<div class="building" />
<div class="birds-bottom">
<div class="bird-small bird-b-1" />
<div class="bird-small bird-b-2" />
<div class="bird-small bird-b-3" />
<div class="bird-small bird-b-4" />
</div>
</div>
<div class="wave-red" />
</div>
</ion-content>
</ion-page>
</template>
<style lang='css' scoped>
.signup-page {
--background: transparent;
position: relative;
overflow: hidden;
}
/* 渐变背景 */
.gradient-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
180deg,
#c41e3a 0%,
#e8756d 15%,
#f5d5c8 35%,
#fef5f1 50%,
#fef5f1 65%,
#f5d5c8 85%,
#e8756d 100%
);
z-index: 0;
}
/* 顶部装饰飞鸟 */
.decoration-top {
position: absolute;
top: 60px;
left: 20px;
z-index: 1;
}
.bird {
width: 16px;
height: 16px;
background: linear-gradient(135deg, #c41e3a 0%, #8b1a2e 100%);
position: absolute;
clip-path: polygon(50% 0%, 0% 40%, 20% 50%, 0% 60%, 50% 100%, 100% 60%, 80% 50%, 100% 40%);
opacity: 0.8;
animation: float 3s ease-in-out infinite;
}
.bird-1 {
left: 0;
top: 0;
animation-delay: 0s;
}
.bird-2 {
left: 25px;
top: 10px;
width: 14px;
height: 14px;
animation-delay: 0.5s;
}
.bird-3 {
left: 15px;
top: 30px;
width: 12px;
height: 12px;
animation-delay: 1s;
}
@keyframes float {
0%,
100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-10px) rotate(5deg);
}
}
/* 内容包装器 */
.content-wrapper {
position: relative;
z-index: 2;
height: 100%;
display: flex;
flex-direction: column;
padding: 30px 24px 20px;
overflow-y: auto;
}
/* 头部区域 */
.header-section {
text-align: center;
margin-bottom: 30px;
flex-shrink: 0;
}
/* 国徽 */
.emblem {
display: flex;
justify-content: center;
margin-bottom: 16px;
}
.emblem-circle {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(196, 30, 58, 0.3);
border: 3px solid #c41e3a;
}
.emblem-inner {
width: 48px;
height: 48px;
background: linear-gradient(135deg, #c41e3a 0%, #8b1a2e 100%);
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
.star {
font-size: 20px;
color: #ffd700;
font-weight: bold;
margin-bottom: -3px;
}
.emblem-text {
font-size: 5px;
color: #ffd700;
font-weight: bold;
letter-spacing: 0.5px;
text-align: center;
line-height: 1.2;
width: 36px;
}
/* 欢迎文字 */
.welcome-title {
font-size: 28px;
font-weight: bold;
color: #1a1a1a;
margin: 0 0 6px 0;
letter-spacing: 2px;
}
.welcome-subtitle {
font-size: 18px;
font-weight: 600;
color: #2c3e50;
margin: 0;
letter-spacing: 1px;
}
/* 表单区域 */
.form-section {
flex: 1;
display: flex;
flex-direction: column;
gap: 12px;
max-width: 400px;
width: 100%;
margin: 0 auto;
padding-bottom: 200px;
}
/* 输入框 */
.input-item {
--background: rgba(255, 255, 255, 0.95);
--border-radius: 12px;
--padding-start: 16px;
--padding-end: 16px;
--inner-padding-end: 0;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
margin: 0;
}
.custom-input {
--padding-start: 0;
--padding-end: 0;
font-size: 16px;
color: #2c3e50;
}
.password-toggle {
color: #8b949e;
font-size: 22px;
cursor: pointer;
}
/* 协议同意 */
.agreement-section {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 4px 4px;
}
.agreement-checkbox {
--size: 20px;
--border-radius: 4px;
--background-checked: #c41e3a;
--border-color-checked: #c41e3a;
margin: 0;
flex-shrink: 0;
}
.agreement-text {
font-size: 13px;
color: #666;
line-height: 1.4;
}
.link-service,
.link-privacy {
color: #c41e3a;
text-decoration: none;
cursor: pointer;
font-weight: 500;
}
.link-service:hover,
.link-privacy:hover {
text-decoration: underline;
}
/* 注册按钮 */
.signup-button {
--background: linear-gradient(135deg, #c41e3a 0%, #8b1a2e 100%);
--background-hover: linear-gradient(135deg, #a01830 0%, #6b1424 100%);
--border-radius: 25px;
--box-shadow: 0 4px 12px rgba(196, 30, 58, 0.3);
height: 50px;
font-size: 18px;
font-weight: 600;
letter-spacing: 2px;
margin-top: 8px;
text-transform: none;
}
/* 登录按钮 */
.login-button {
--border-color: #8b1a2e;
--border-width: 2px;
--border-radius: 25px;
--color: #8b1a2e;
--background: transparent;
--background-hover: rgba(196, 30, 58, 0.05);
height: 50px;
font-size: 16px;
font-weight: 600;
letter-spacing: 1px;
text-transform: none;
}
/* 底部装饰 */
.decoration-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
pointer-events: none;
}
.building-wrapper {
position: relative;
height: 180px;
overflow: hidden;
}
.building {
position: absolute;
bottom: 40px;
left: 0;
right: 0;
height: 140px;
background: linear-gradient(
to top,
rgba(196, 30, 58, 0.9) 0%,
rgba(196, 30, 58, 0.8) 20%,
rgba(232, 117, 109, 0.7) 40%,
rgba(232, 117, 109, 0.5) 60%,
rgba(232, 117, 109, 0.3) 80%,
transparent 100%
);
clip-path: polygon(
0% 100%,
0% 60%,
10% 55%,
15% 50%,
15% 45%,
18% 45%,
18% 40%,
22% 40%,
22% 35%,
28% 35%,
28% 30%,
35% 30%,
35% 25%,
42% 25%,
45% 22%,
50% 20%,
55% 22%,
58% 25%,
65% 25%,
65% 30%,
72% 30%,
72% 35%,
78% 35%,
78% 40%,
82% 40%,
82% 45%,
85% 45%,
85% 50%,
90% 55%,
100% 60%,
100% 100%
);
}
.birds-bottom {
position: absolute;
bottom: 80px;
right: 20px;
}
.bird-small {
width: 12px;
height: 12px;
background: linear-gradient(135deg, #c41e3a 0%, #8b1a2e 100%);
position: absolute;
clip-path: polygon(50% 0%, 0% 40%, 20% 50%, 0% 60%, 50% 100%, 100% 60%, 80% 50%, 100% 40%);
opacity: 0.9;
animation: float-bottom 2.5s ease-in-out infinite;
}
.bird-b-1 {
right: 0;
bottom: 0;
animation-delay: 0s;
}
.bird-b-2 {
right: 20px;
bottom: 15px;
width: 14px;
height: 14px;
animation-delay: 0.3s;
}
.bird-b-3 {
right: 45px;
bottom: 8px;
animation-delay: 0.6s;
}
.bird-b-4 {
right: 70px;
bottom: 20px;
width: 10px;
height: 10px;
animation-delay: 0.9s;
}
@keyframes float-bottom {
0%,
100% {
transform: translate(0, 0) rotate(0deg);
}
50% {
transform: translate(-5px, -8px) rotate(-5deg);
}
}
/* 红色波浪 */
.wave-red {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(180deg, transparent 0%, #c41e3a 100%);
}
</style>