Files
account/resources/mobile/pages/ucenter/register/index.vue
2026-01-18 17:42:46 +08:00

402 lines
7.8 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.
<template>
<view class="register-container">
<view class="register-content">
<!-- Logo 区域 -->
<view class="logo-section">
<image src="/static/logo.png" class="logo" mode="aspectFit"></image>
<text class="app-name">用户注册</text>
<text class="welcome-text">创建您的家庭记账账号</text>
</view>
<!-- 表单区域 -->
<view class="form-section">
<view class="form-item">
<uni-icons type="person" size="20" color="#999"></uni-icons>
<input
class="input"
type="text"
v-model="formData.username"
placeholder="请输入用户名"
placeholder-class="input-placeholder"
maxlength="30"
/>
</view>
<view class="form-item">
<uni-icons type="locked" size="20" color="#999"></uni-icons>
<input
class="input"
:type="showPassword ? 'text' : 'password'"
v-model="formData.password"
placeholder="请设置密码6-20位"
placeholder-class="input-placeholder"
/>
<uni-icons
:type="showPassword ? 'eye-slash' : 'eye'"
size="20"
color="#999"
@tap="togglePassword"
></uni-icons>
</view>
<view class="form-item">
<uni-icons type="locked" size="20" color="#999"></uni-icons>
<input
class="input"
:type="showConfirmPassword ? 'text' : 'password'"
v-model="formData.confirmPassword"
placeholder="请再次输入密码"
placeholder-class="input-placeholder"
/>
<uni-icons
:type="showConfirmPassword ? 'eye-slash' : 'eye'"
size="20"
color="#999"
@tap="toggleConfirmPassword"
></uni-icons>
</view>
<view class="form-item">
<uni-icons type="info" size="20" color="#999"></uni-icons>
<input
class="input"
type="text"
v-model="formData.nickname"
placeholder="请设置昵称"
placeholder-class="input-placeholder"
maxlength="20"
/>
</view>
<view class="agreement-item">
<uni-icons
:type="formData.agreed ? 'checkbox-filled' : 'circle'"
:color="formData.agreed ? '#4CAF50' : '#999'"
size="20"
@tap="toggleAgreement"
></uni-icons>
<text class="agreement-text">
我已阅读并同意
<text class="agreement-link" @tap="handleAgreement('user')">用户协议</text>
<text class="agreement-link" @tap="handleAgreement('privacy')">隐私政策</text>
</text>
</view>
<button class="register-btn" type="primary" @tap="handleRegister" :loading="loading">
{{ loading ? '注册中...' : '立即注册' }}
</button>
<view class="login-tip">
<text class="tip-text">已有账号</text>
<text class="login-link" @tap="goToLogin">立即登录</text>
</view>
</view>
</view>
</view>
</template>
<script>
import authApi from '@/api/modules/auth'
export default {
data() {
return {
// 不需要登录验证
needLogin: false,
formData: {
username: '',
password: '',
confirmPassword: '',
nickname: '',
agreed: false
},
showPassword: false,
showConfirmPassword: false,
loading: false
}
},
methods: {
// 切换密码显示/隐藏
togglePassword() {
this.showPassword = !this.showPassword
},
toggleConfirmPassword() {
this.showConfirmPassword = !this.showConfirmPassword
},
// 切换协议同意
toggleAgreement() {
this.formData.agreed = !this.formData.agreed
},
// 注册
async handleRegister() {
// 表单验证
if (!this.validateForm()) {
return
}
try {
this.loading = true
// 调用注册接口
const result = await authApi.register.post({
username: this.formData.username,
password: this.formData.password,
nickname: this.formData.nickname
})
uni.showToast({
title: '注册成功',
icon: 'success',
duration: 1500
})
// 跳转到登录页
setTimeout(() => {
uni.redirectTo({
url: '/pages/ucenter/login/index'
})
}, 1500)
} catch (error) {
console.error('注册失败:', error)
} finally {
this.loading = false
}
},
// 表单验证
validateForm() {
const { username, password, confirmPassword, nickname, agreed } = this.formData
// 验证用户名
if (!username) {
uni.showToast({
title: '请输入用户名',
icon: 'none',
duration: 2000
})
return false
}
if (username.length < 3) {
uni.showToast({
title: '用户名至少3个字符',
icon: 'none',
duration: 2000
})
return false
}
// 验证密码
if (!password) {
uni.showToast({
title: '请设置密码',
icon: 'none',
duration: 2000
})
return false
}
if (password.length < 6 || password.length > 20) {
uni.showToast({
title: '密码长度为6-20位',
icon: 'none',
duration: 2000
})
return false
}
// 验证确认密码
if (!confirmPassword) {
uni.showToast({
title: '请再次输入密码',
icon: 'none',
duration: 2000
})
return false
}
if (password !== confirmPassword) {
uni.showToast({
title: '两次输入的密码不一致',
icon: 'none',
duration: 2000
})
return false
}
// 验证昵称
if (!nickname) {
uni.showToast({
title: '请设置昵称',
icon: 'none',
duration: 2000
})
return false
}
// 验证协议
if (!agreed) {
uni.showToast({
title: '请阅读并同意用户协议和隐私政策',
icon: 'none',
duration: 2000
})
return false
}
return true
},
// 查看协议
handleAgreement(type) {
let url = ''
if (type === 'user') {
url = '/pages/ucenter/agreement/user'
} else if (type === 'privacy') {
url = '/pages/ucenter/agreement/privacy'
}
if (url) {
uni.navigateTo({
url: url
})
}
},
// 跳转到登录页
goToLogin() {
uni.navigateBack()
}
}
}
</script>
<style lang="scss" scoped>
.register-container {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 0 60rpx;
box-sizing: border-box;
}
.register-content {
padding-top: 80rpx;
}
.logo-section {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 60rpx;
.logo {
width: 140rpx;
height: 140rpx;
margin-bottom: 30rpx;
border-radius: 20rpx;
background: rgba(255, 255, 255, 0.9);
padding: 20rpx;
}
.app-name {
font-size: 44rpx;
font-weight: bold;
color: #fff;
margin-bottom: 16rpx;
}
.welcome-text {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.9);
}
}
.form-section {
.form-item {
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.95);
border-radius: 16rpx;
padding: 30rpx 40rpx;
margin-bottom: 24rpx;
.input {
flex: 1;
margin-left: 20rpx;
margin-right: 20rpx;
font-size: 32rpx;
color: #333;
}
.input-placeholder {
color: #999;
}
}
.agreement-item {
display: flex;
align-items: flex-start;
margin-bottom: 30rpx;
padding: 0 10rpx;
.agreement-text {
flex: 1;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.9);
line-height: 1.6;
margin-left: 10rpx;
.agreement-link {
color: #fff;
font-weight: bold;
text-decoration: underline;
}
}
}
.register-btn {
width: 100%;
height: 100rpx;
line-height: 100rpx;
border-radius: 50rpx;
background: linear-gradient(90deg, #f093fb 0%, #f5576c 100%);
color: #fff;
font-size: 36rpx;
font-weight: bold;
border: none;
box-shadow: 0 8rpx 20rpx rgba(245, 87, 108, 0.4);
margin-bottom: 40rpx;
&::after {
border: none;
}
}
.login-tip {
display: flex;
justify-content: center;
align-items: center;
.tip-text {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.9);
}
.login-link {
font-size: 28rpx;
color: #fff;
font-weight: bold;
margin-left: 10rpx;
text-decoration: underline;
}
}
}
</style>