ruoyi-geek-App/pages_mine/pages/register/index.vue
2025-11-25 20:43:09 +08:00

277 lines
6.7 KiB
Vue

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { getCodeImg, sendEmailCode, sendPhoneCode } from "@/api/login";
import useUserStore from "@/store/modules/user";
// 定义 props
const props = defineProps<{
register: boolean;
captchaEnabled: boolean;
method: 'password' | 'phone' | 'email';
}>();
// 响应式数据
const registerForm = ref({
username: "",
password: "",
confirmPassword: "",
email: '',
phonenumber: '',
code: "",
uuid: "",
});
const codeUrl = ref("");
// 分开控制发送验证码和注册的 loading 状态
const sendCodeLoading = ref(false);
const registerLoading = ref(false);
const registerRef = ref<any>(null);
// 表单校验规则
const registerRules = {
username: [
{ required: true, message: "请输入您的账号", trigger: "blur" },
{ min: 2, max: 20, message: "用户账号长度必须介于 2 和 20 之间", trigger: "blur" }
],
password: [
{ required: true, message: "请输入您的密码", trigger: "blur" },
{ min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
],
confirmPassword: [
{ required: true, message: "请再次输入您的密码", trigger: "blur" },
{
validator: (rule: any, value: any, callback: any) => {
if (registerForm.value.password !== value) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
},
trigger: "blur"
}
],
code: [{ required: true, message: "请输入验证码", trigger: "change" }]
};
// 用户仓库
const userStore = useUserStore();
// 获取图形验证码
function getCode() {
if (!props.captchaEnabled) return;
getCodeImg().then((res: any) => {
codeUrl.value = "data:image/gif;base64," + res.img;
registerForm.value.uuid = res.uuid;
});
}
// 发送验证码
function sendCode() {
if (props.method === 'email') {
sendEmailCode(registerForm.value, 'register');
} else if (props.method === 'phone') {
sendPhoneCode(registerForm.value, 'register');
}
}
// 注册提交
function handleRegister() {
registerRef.value.validate((valid: boolean) => {
if (valid) {
loading.value = true;
userStore.register(registerForm.value, props.method).then(() => {
uni.showModal({
title: "系统提示",
content: `<font color='red'>恭喜你,您的账号 ${registerForm.value.username} 注册成功!</font>`,
showCancel: false,
success: () => {
uni.redirectTo({
url: "/pages/login/login" // 跳转到登录页
});
}
});
}).catch(() => {
getCode();
}).finally(() => {
loading.value = false;
});
}
});
}
// 页面加载时获取验证码
onMounted(() => {
getCode();
});
</script>
<template>
<view class="register-container">
<uni-forms
ref="registerRef"
:model="registerForm"
:rules="registerRules"
class="register-form"
>
<!-- 邮箱输入 -->
<uni-forms-item prop="email" v-if="method === 'email'">
<uni-easyinput
v-model="registerForm.email"
type="text"
placeholder="邮箱"
prefixIcon="email"
/>
</uni-forms-item>
<!-- 手机号输入 -->
<uni-forms-item prop="phonenumber" v-else-if="method === 'phone'">
<uni-easyinput
v-model="registerForm.phonenumber"
type="text"
placeholder="手机号"
prefixIcon="phone"
/>
</uni-forms-item>
<!-- 用户名输入 -->
<uni-forms-item prop="username" v-else>
<uni-easyinput
v-model="registerForm.username"
type="text"
placeholder="账号"
prefixIcon="user"
/>
</uni-forms-item>
<!-- 密码输入 -->
<uni-forms-item prop="password">
<uni-easyinput
v-model="registerForm.password"
type="password"
placeholder="密码"
prefixIcon="lock"
@keyup.enter="handleRegister"
/>
</uni-forms-item>
<!-- 确认密码输入 -->
<uni-forms-item prop="confirmPassword">
<uni-easyinput
v-model="registerForm.confirmPassword"
type="password"
placeholder="确认密码"
prefixIcon="lock"
@keyup.enter="handleRegister"
/>
</uni-forms-item>
<!-- 验证码输入 -->
<uni-forms-item prop="code">
<view class="code-input">
<uni-easyinput
v-model="registerForm.code"
type="text"
placeholder="验证码"
prefixIcon="code"
@keyup.enter="handleRegister"
/>
<!-- 图形验证码或发送按钮 -->
<view class="code-action">
<uni-image
v-if="captchaEnabled && method === 'password'"
:src="codeUrl"
class="code-img"
@click="getCode"
mode="aspectFill"
/>
<uni-button
v-else
type="primary"
size="mini"
@click="sendCode"
:loading="loading"
>
发送验证码
</uni-button>
</view>
</view>
</uni-forms-item>
<!-- 注册按钮 -->
<uni-forms-item>
<button
type="primary"
size="default"
class="register-btn"
:loading="loading"
@click="handleRegister"
>
注册
</button>
</uni-forms-item>
<!-- 已有账号跳转 -->
<view class="login-link">
<text class="question-text">已有账号?</text>
<navigator url="/pages/login" class="link-type">立即登录</navigator>
</view>
</uni-forms>
</view>
</template>
<style scoped lang="scss">
.register-container {
padding: 40rpx;
}
.register-form {
background-color: #fff;
padding: 60rpx;
border-radius: 16rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.05);
}
.code-input {
display: flex;
align-items: center;
gap: 20rpx;
}
.code-action {
flex-shrink: 0;
}
.code-img {
width: 180rpx;
height: 70rpx;
border-radius: 8rpx;
}
.register-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
border-radius: 40rpx;
margin-top: 20rpx;
}
.login-link {
display: flex;
justify-content: center;
align-items: center;
margin-top: 40rpx;
font-size: 26rpx;
color: #666;
}
.link-type {
color: #007aff;
margin-left: 10rpx;
text-decoration: underline;
}
</style>