490 lines
12 KiB
Vue
490 lines
12 KiB
Vue
<template>
|
||
<view class="register-container">
|
||
<view class="register-title">
|
||
<view class="title">
|
||
用户注册
|
||
</view>
|
||
<view class="sub-title">
|
||
创建你的账号,欢迎来到炬融圈
|
||
</view>
|
||
</view>
|
||
|
||
<view class="register-main">
|
||
<u-form :model="userRegister.userRegisterForm" class="register-form" ref="userRegisterRef"
|
||
:border-bottom="false" :error-type="['message']" label-width="0">
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Phone.png" prop="phone">
|
||
<u-input v-model="userRegister.userRegisterForm.phone" placeholder="请输入手机号" maxlength="11"
|
||
type="number" placeholder-style="color: #737373;" />
|
||
</u-form-item>
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Mail.png" prop="smsCode">
|
||
<u-input v-model="userRegister.userRegisterForm.smsCode" placeholder="请输入短信验证码" maxlength="6"
|
||
type="number" placeholder-style="color: #737373;" />
|
||
<template v-slot:right>
|
||
<u-verification-code ref="msgCodeRef" @change="codeMsgChange"></u-verification-code>
|
||
<u-button :disabled="!canSendSMS" size="mini" type="primary"
|
||
@tap="getMsgCode">{{msgCodeBtn}}</u-button>
|
||
</template>
|
||
</u-form-item>
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Map pin.png" prop="regionLabel">
|
||
<u-input type="select" v-model="userRegister.userRegisterForm.regionLabel" placeholder="请选择省市区"
|
||
placeholder-style="color: #737373;" @click="showRegitionPicker = true" />
|
||
</u-form-item>
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Lock.png" prop="password">
|
||
<u-input type="password" v-model="userRegister.userRegisterForm.password" placeholder="请输入密码"
|
||
maxlength="20" placeholder-style="color: #737373;" />
|
||
</u-form-item>
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Lock.png" prop="confirmPassword">
|
||
<u-input type="password" v-model="userRegister.userRegisterForm.confirmPassword" maxlength="20"
|
||
placeholder="请输入确认密码" placeholder-style="color: #737373;" />
|
||
</u-form-item>
|
||
<u-form-item :left-icon-style="inputIcon" left-icon="../../static/icon/Globe.png" prop="captcha">
|
||
<u-input v-model="userRegister.userRegisterForm.captcha" placeholder="请输入验证码" maxlength="4"
|
||
placeholder-style="color: #737373;" />
|
||
<template v-slot:right>
|
||
<image @click="loadCaptcha" class="captcha-img" :src="captcha" mode=""></image>
|
||
</template>
|
||
</u-form-item>
|
||
</u-form>
|
||
|
||
<view class="reflash" @click="loadCaptcha">
|
||
<image class="reflash-icon" src="/static/icon/Repeat.png" mode=""></image>
|
||
刷新验证码
|
||
</view>
|
||
<u-checkbox v-model="is_read" size="26" class="must-read" :label-disabled="true">
|
||
我已阅读并同意<span @click="showFile1=true">《用户协议》</span>和<span @click="showFile2=true">《隐私政策》</span>
|
||
</u-checkbox>
|
||
<u-button type="primary" class="register-btn" @click="handleRegister">立即注册</u-button>
|
||
|
||
<view class="login">
|
||
<view class="login-text">没有账号?</view>
|
||
<view class="login-link" @click="handleLogin">立即登录</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 省市区 -->
|
||
<u-select v-model="showRegitionPicker" :list="regionOptions" mode="mutil-column-auto" label-name="label"
|
||
value-name="code" child-name="children" @confirm="handleRegion"></u-select>
|
||
<!-- 协议1 -->
|
||
<u-popup v-model="showFile1" mode="bottom" border-radius="14" :closeable="true">
|
||
<view class="file">
|
||
<h3>用户协议</h3>
|
||
<p>1. 用户应当遵守法律法规,不得发布违法违规内容。</p>
|
||
<p>2. 用户对自己发布的内容承担全部责任。</p>
|
||
<p>3. 平台有权对违规内容进行删除或限制。</p>
|
||
<p>4. 用户应当保护好自己的账号安全。</p>
|
||
<p>5. 平台保留修改本协议的权利。</p>
|
||
</view>
|
||
</u-popup>
|
||
<!-- 协议2 -->
|
||
<u-popup v-model="showFile2" mode="bottom" border-radius="14" :closeable="true">
|
||
<view class="file">
|
||
<h3>隐私政策</h3>
|
||
<p>1. 我们重视用户隐私保护。</p>
|
||
<p>2. 我们只收集必要的用户信息。</p>
|
||
<p>3. 用户信息仅用于提供服务。</p>
|
||
<p>4. 我们不会向第三方泄露用户信息。</p>
|
||
<p>5. 用户有权查看、修改或删除个人信息。</p>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import {
|
||
onMounted,
|
||
reactive,
|
||
ref,
|
||
computed
|
||
} from 'vue';
|
||
import {
|
||
onReady
|
||
} from '@dcloudio/uni-app';
|
||
import {
|
||
captchaAPI
|
||
} from '../../api/captcha.js';
|
||
import {
|
||
commonAPI
|
||
} from '../../api/common.js';
|
||
import {
|
||
authAPI
|
||
} from '../../api/auth.js';
|
||
|
||
|
||
// 输入框图标样式
|
||
const inputIcon = {
|
||
width: '32rpx',
|
||
verticalAlign: 'middle'
|
||
}
|
||
|
||
// 省市区
|
||
const showRegitionPicker = ref(false)
|
||
const regionOptions = ref()
|
||
|
||
// 加载省市区
|
||
const loadRegion = () => {
|
||
commonAPI.getRegion().then(res => {
|
||
if (res.success) {
|
||
regionOptions.value = res.data
|
||
}
|
||
})
|
||
}
|
||
|
||
// 选择省市区
|
||
const handleRegion = (e) => {
|
||
console.log(e);
|
||
userRegister.userRegisterForm.regionLabel = e[0].label + "/" + e[1].label + "/" + e[2].label
|
||
userRegister.userRegisterForm.region = e[2].value
|
||
}
|
||
|
||
|
||
// 验证码
|
||
const captcha = ref()
|
||
const captchaId = ref()
|
||
|
||
// 请求验证码
|
||
const loadCaptcha = () => {
|
||
captchaAPI.generate().then(res => {
|
||
captcha.value = res.data.image
|
||
captchaId.value = res.data.captchaId
|
||
})
|
||
}
|
||
|
||
|
||
// 校验规则
|
||
const validatePassword = (rule, value, callback) => {
|
||
if (!value) {
|
||
callback(new Error('请输入密码'));
|
||
} else if (value.length < 6) {
|
||
callback(new Error('密码至少6个字符'));
|
||
} else if (value.length > 20) {
|
||
callback(new Error('密码不能超过20个字符'));
|
||
} else if (!/(?=.*[a-zA-Z])(?=.*\d)/.test(value)) {
|
||
callback(new Error('密码必须包含字母和数字'));
|
||
} else {
|
||
// 如果确认密码已输入,重新验证确认密码
|
||
if (userRegister.userRegisterForm.confirmPassword) {
|
||
userRegisterRef.value?.validateField('confirmPassword');
|
||
}
|
||
callback();
|
||
}
|
||
};
|
||
|
||
const validateConfirmPassword = (rule, value, callback) => {
|
||
if (!value) {
|
||
callback(new Error('请确认密码'));
|
||
} else if (value !== userRegister.userRegisterForm.password) {
|
||
callback(new Error('两次输入的密码不一致'));
|
||
} else {
|
||
callback();
|
||
}
|
||
};
|
||
|
||
// 注册表单
|
||
const userRegisterRef = ref()
|
||
const userRegister = reactive({
|
||
userRegisterForm: {
|
||
username: '13758452159',
|
||
phone: '13758452159',
|
||
smsCode: 'asrfdv',
|
||
region: '',
|
||
regionLabel: '',
|
||
password: 's123456s',
|
||
confirmPassword: 's123456s',
|
||
captcha: 'vfjs',
|
||
},
|
||
rules: {
|
||
phone: [{
|
||
required: true,
|
||
message: '请输入手机号',
|
||
trigger: ['blur']
|
||
},
|
||
{
|
||
pattern: /^1[3-9]\d{9}$/,
|
||
message: '请输入正确的手机号格式',
|
||
trigger: ['blur']
|
||
}
|
||
],
|
||
smsCode: [{
|
||
required: true,
|
||
message: '请输入短信验证码',
|
||
trigger: ['blur']
|
||
},
|
||
{
|
||
pattern: /^\d{6}$/,
|
||
message: '短信验证码为6位数字',
|
||
trigger: ['blur']
|
||
},
|
||
],
|
||
regionLabel: [{
|
||
required: true,
|
||
message: '请选择省市区',
|
||
trigger: ['change']
|
||
}],
|
||
password: [{
|
||
validator: validatePassword,
|
||
trigger: ['blur']
|
||
}],
|
||
confirmPassword: [{
|
||
validator: validateConfirmPassword,
|
||
trigger: ['blur']
|
||
}],
|
||
captcha: [{
|
||
required: true,
|
||
message: '请输入验证码',
|
||
trigger: ['blur']
|
||
},
|
||
{
|
||
min: 4,
|
||
max: 4,
|
||
message: '验证码长度为4位',
|
||
trigger: 'blur'
|
||
}
|
||
],
|
||
}
|
||
})
|
||
|
||
// 注册处理
|
||
const handleRegister = async () => {
|
||
if (!is_read.value) {
|
||
uni.showToast({
|
||
title: '请先同意协议',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 等待表单验证完成
|
||
const valid = await userRegisterRef.value.validate();
|
||
if (valid) {
|
||
console.log(valid);
|
||
}
|
||
// userRegisterRef.value.validate((valid : any) => {
|
||
// if (valid) {
|
||
// // 验证验证码
|
||
// captchaAPI.verify({
|
||
// captchaId: captchaId.value,
|
||
// captchaText: userRegister.userRegisterForm.captcha
|
||
// }).then(verifyResponse => {
|
||
// console.log(verifyResponse);
|
||
// if (!verifyResponse.data.success) {
|
||
// uni.showToast({
|
||
// title: verifyResponse.data.message || '验证码错误',
|
||
// icon: 'error'
|
||
// })
|
||
// // 重新加载验证码
|
||
// loadCaptcha()
|
||
// return
|
||
// }
|
||
// })
|
||
// const registerData = {
|
||
// username: userRegister.userRegisterForm.phone,
|
||
// phone: userRegister.userRegisterForm.phone,
|
||
// city: userRegister.userRegisterForm.region,
|
||
// password: userRegister.userRegisterForm.password,
|
||
// smsCode: userRegister.userRegisterForm.smsCode,
|
||
// captchaId: captchaId.value,
|
||
// captchaText: userRegister.userRegisterForm.captcha,
|
||
// province: userRegister.userRegisterForm.region,
|
||
// }
|
||
// authAPI.register(registerData).then(response => {
|
||
// // 直接注册成功的情况
|
||
// // setToken(response.data.token)
|
||
// // setUser(response.data.user)
|
||
// console.log(response);
|
||
// })
|
||
// }
|
||
// })
|
||
}
|
||
|
||
// 手机验证码
|
||
const msgCodeBtn = ref()
|
||
const msgCodeRef = ref()
|
||
|
||
|
||
// 手机验证码变化
|
||
const codeMsgChange = (text) => {
|
||
msgCodeBtn.value = text;
|
||
}
|
||
|
||
// 是否能够发送手机验证码
|
||
const canSendSMS = computed(() => {
|
||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||
return phoneRegex.test(userRegister.userRegisterForm.phone);
|
||
});
|
||
|
||
// 获取手机验证码
|
||
const getMsgCode = () => {
|
||
// 校验手机号
|
||
if (msgCodeRef.value.canGetCode) {
|
||
console.log("发送验证码");
|
||
msgCodeRef.value.start();
|
||
} else {
|
||
uni.showToast({
|
||
title: '等待...'
|
||
})
|
||
}
|
||
}
|
||
|
||
// 是否阅读
|
||
const is_read = ref(false)
|
||
const showFile1 = ref(false)
|
||
const showFile2 = ref(false)
|
||
|
||
// 跳转登录页面
|
||
const handleLogin = () => {
|
||
uni.redirectTo({
|
||
url: '/pages/login/login'
|
||
})
|
||
}
|
||
|
||
onMounted(() => {
|
||
loadCaptcha()
|
||
loadRegion()
|
||
})
|
||
|
||
onReady(() => {
|
||
userRegisterRef.value.setRules(userRegister.rules)
|
||
})
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.register-container {
|
||
width: 100%;
|
||
height: 100vh;
|
||
background: linear-gradient(180deg, #BAC9FF 0%, #FFFFFF 100%);
|
||
|
||
.register-title {
|
||
padding-top: 114rpx;
|
||
|
||
.title {
|
||
font-family: SF Pro;
|
||
font-weight: 650;
|
||
font-style: Expanded Semibold;
|
||
font-size: 48rpx;
|
||
leading-trim: NONE;
|
||
line-height: 80rpx;
|
||
letter-spacing: 0%;
|
||
text-align: center;
|
||
color: #000000;
|
||
}
|
||
|
||
.sub-title {
|
||
font-family: Work Sans;
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
leading-trim: NONE;
|
||
line-height: 100%;
|
||
letter-spacing: -2%;
|
||
text-align: center;
|
||
color: #5B5B5B;
|
||
}
|
||
}
|
||
|
||
.register-main {
|
||
|
||
.register-form {
|
||
padding: 20rpx 98rpx 10rpx;
|
||
}
|
||
|
||
.captcha-img {
|
||
width: 200rpx;
|
||
height: 80rpx;
|
||
}
|
||
|
||
.reflash {
|
||
width: 90%;
|
||
margin-bottom: 30rpx;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
|
||
|
||
// 文字
|
||
font-family: Work Sans;
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
leading-trim: NONE;
|
||
line-height: 100%;
|
||
letter-spacing: -2%;
|
||
color: #3781EF;
|
||
|
||
.reflash-icon {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
margin-right: 10rpx;
|
||
}
|
||
}
|
||
|
||
.must-read {
|
||
padding: 0 76rpx;
|
||
font-family: Work Sans;
|
||
font-weight: 400;
|
||
leading-trim: NONE;
|
||
line-height: 100%;
|
||
letter-spacing: -2%;
|
||
text-align: center;
|
||
color: #000000;
|
||
text-align: left;
|
||
|
||
span {
|
||
font-family: Work Sans;
|
||
font-weight: 400;
|
||
font-size: 26rpxpx;
|
||
leading-trim: NONE;
|
||
line-height: 100%;
|
||
letter-spacing: -2%;
|
||
text-align: center;
|
||
color: #3781EF;
|
||
|
||
}
|
||
}
|
||
|
||
.register-btn {
|
||
margin: 40rpx 54rpx 20rpx;
|
||
font-family: SF Pro;
|
||
font-weight: 650;
|
||
font-style: Expanded Semibold;
|
||
font-size: 40rpx;
|
||
leading-trim: NONE;
|
||
line-height: 46rpx;
|
||
letter-spacing: 0%;
|
||
text-align: center;
|
||
}
|
||
|
||
|
||
.login {
|
||
margin: 40rpx 0 80rpx;
|
||
padding-bottom: 80rpx;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
|
||
// 文字
|
||
font-family: Work Sans;
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
leading-trim: NONE;
|
||
line-height: 100%;
|
||
letter-spacing: -2%;
|
||
text-align: center;
|
||
|
||
|
||
.login-text {
|
||
color: #737373;
|
||
}
|
||
|
||
.login-link {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #3781EF;
|
||
}
|
||
}
|
||
}
|
||
|
||
.file {
|
||
padding: 80rpx 40rpx;
|
||
}
|
||
|
||
}
|
||
</style> |