WholeProcessPlatform/frontend/src/views/register/index.vue

327 lines
8.3 KiB
Vue
Raw Normal View History

2026-04-27 11:57:26 +08:00
<template>
<div class="register-container">
<div class="register-wrapper">
<!-- 左侧背景图区域 -->
<div class="left-section">
<div class="slogan">
<p>{{ $t("login.titleSjtb") }}</p>
</div>
</div>
<!-- 右侧注册表单区域 -->
<div class="right-section">
<a-tabs v-model:activeKey="activeTab" class="register-tabs">
<a-tab-pane key="register" tab="用户注册">
<a-form
:model="registerData"
:rules="registerRules"
layout="vertical"
class="form-container"
@finish="onRegister"
>
<!-- 登录账号 -->
<a-form-item name="username" label="登录账号">
<a-input
v-model:value="registerData.username"
placeholder="请输入登录账号4-20个字符"
:prefix="h(UserOutlined)"
/>
</a-form-item>
<!-- 真实姓名 -->
<a-form-item name="realName" label="真实姓名">
<a-input
v-model:value="registerData.realName"
placeholder="请输入真实姓名"
/>
</a-form-item>
<!-- 手机号 -->
<a-form-item name="phone" label="手机号">
<a-input
v-model:value="registerData.phone"
placeholder="请输入11位手机号"
:prefix="h(MobileOutlined)"
/>
</a-form-item>
<!-- 密码 -->
<a-form-item name="password" label="密码">
<a-input-password
v-model:value="registerData.password"
placeholder="请设置密码6-20个字符"
:prefix="h(LockOutlined)"
/>
</a-form-item>
<!-- 确认密码 -->
<a-form-item name="confirmPassword" label="确认密码">
<a-input-password
v-model:value="registerData.confirmPassword"
placeholder="请再次输入密码"
:prefix="h(LockOutlined)"
/>
</a-form-item>
<!-- 验证码 -->
<a-form-item name="code" label="验证码">
<a-row :gutter="8">
<a-col :span="16">
<a-input
v-model:value="registerData.code"
placeholder="请输入验证码"
/>
</a-col>
<a-col :span="8">
<img
v-if="captchaImg"
:src="captchaImg"
@click="refreshCaptcha"
style="cursor: pointer; width: 100%; height: 36px;"
/>
</a-col>
</a-row>
</a-form-item>
<!-- 注册按钮 -->
<a-button
type="primary"
size="large"
block
htmlType="submit"
:loading="loading"
>
<span>立即注册</span>
</a-button>
<!-- 返回登录 -->
<a-button
type="link"
size="small"
block
@click="backToLogin"
:style="{ marginTop: '10px' }"
>
已有账号返回登录
</a-button>
</a-form>
</a-tab-pane>
</a-tabs>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted, h } from "vue";
import { UserOutlined, LockOutlined, MobileOutlined } from "@ant-design/icons-vue";
2026-04-27 13:43:34 +08:00
import { getCaptcha,
// registerUser
} from "@/api/auth";
2026-04-27 11:57:26 +08:00
import { message } from "ant-design-vue";
import router from "@/router";
import { encrypt } from "@/utils/rsaEncrypt";
// 注册表单数据
const registerData = reactive({
// 必填字段
username: "",
realName: "",
phone: "",
password: "",
confirmPassword: "",
code: "",
uuid: "",
// 系统字段
userType: 1,
status: 1,
regStatus: 0
});
// 表单验证规则
const registerRules = {
// 登录账号
username: [
{ required: true, message: "请输入登录账号", trigger: "blur" },
{ min: 4, max: 20, message: "账号长度4-20个字符", trigger: "blur" },
{ pattern: /^[a-zA-Z0-9_]+$/, message: "只能包含字母、数字和下划线", trigger: "blur" }
],
// 真实姓名
realName: [
{ required: true, message: "请输入真实姓名", trigger: "blur" },
{ min: 2, max: 20, message: "姓名长度2-20个字符", trigger: "blur" }
],
// 手机号
phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的11位手机号", trigger: "blur" }
],
// 密码
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 6, max: 20, message: "密码长度6-20个字符", trigger: "blur" }
],
// 确认密码
confirmPassword: [
{ required: true, message: "请再次输入密码", trigger: "blur" },
{
validator: (rule: any, value: string) => {
if (value && value !== registerData.password) {
return Promise.reject("两次输入的密码不一致");
}
return Promise.resolve();
},
trigger: "blur"
}
],
// 验证码
code: [
{ required: true, message: "请输入验证码", trigger: "blur" }
]
};
const loading = ref(false);
const captchaImg = ref("");
const activeTab = ref("register");
// 获取验证码
const refreshCaptcha = async () => {
try {
const res = await getCaptcha();
registerData.uuid = res.data.verifyCodeKey;
captchaImg.value = res.data.verifyCodeImg; // base64图片
} catch (error) {
message.error("获取验证码失败");
}
};
// 注册提交
const onRegister = async () => {
loading.value = true;
try {
// 密码加密
const encryptedPassword = encrypt(registerData.password);
// 构造注册数据
const registerParams = {
username: registerData.username,
realName: registerData.realName,
phone: registerData.phone,
password: encryptedPassword,
// 系统字段
userType: 1,
status: 1,
regStatus: 0,
// 验证码相关
code: registerData.code,
uuid: registerData.uuid
};
// 调用注册接口
2026-04-27 13:43:34 +08:00
// await registerUser(registerParams);
2026-04-27 11:57:26 +08:00
message.success("注册成功,等待管理员审核");
// 延迟跳转到登录页
setTimeout(() => {
router.push({ path: "/login" });
}, 1500);
} catch (error: any) {
message.error(error.message || "注册失败,请重试");
// 刷新验证码
refreshCaptcha();
} finally {
loading.value = false;
}
};
// 返回登录
const backToLogin = () => {
router.push({ path: "/login" });
};
// 初始化
onMounted(() => {
refreshCaptcha();
});
</script>
<style scoped lang="scss">
.register-container {
margin: 0 auto;
position: relative;
width: 100%;
height: 100%;
min-width: 1500px;
background-color: #fff;
.register-wrapper {
position: relative;
width: 100%;
height: 100%;
min-height: 600px;
background: url("@/assets/images/bg_sjtb.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
// 左侧背景区域
.left-section {
.slogan {
position: absolute;
top: 20%;
left: 18%;
width: 700px;
height: 112px;
color: #040504;
font-size: 40px;
}
}
// 右侧注册卡片区域
.right-section {
position: absolute;
left: 70%;
top: 15%;
width: 25%;
// max-height: 650px;
// max-width: 400px;
min-height: 650px;
border-radius: 3px;
padding: 20px 24px 24px;
background-color: #fff;
overflow-y: auto;
:deep(.ant-form-item) {
margin-bottom: 14px;
}
:deep(.ant-form-item-label > label) {
font-size: 13px;
}
:deep(.ant-input-prefix) {
display: flex;
width: 26px;
svg {
width: 18px;
height: 18px;
margin-right: 4px;
}
}
}
}
</style>