Files
OCS_service/app/pages/register.vue
T
2026-05-23 23:08:00 +08:00

144 lines
3.9 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.
<!-- app/pages/register.vue - 新用户注册页 -->
<script lang="ts" setup>
import { toTypedSchema } from "@vee-validate/zod";
import { useForm } from "vee-validate";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { useAuthStore } from "@/stores/auth";
definePageMeta({
pageOrder: 4,
pageTransition: { name: "slide-left" }
});
useHead({ title: "注册 - OCS AI 答题服务" });
const authStore = useAuthStore();
// 已登录用户访问注册页,直接跳首页
watchEffect(() => {
if (authStore.isOnline) navigateTo("/");
});
const formSchema = toTypedSchema(
z.object({
name: z
.string({ required_error: "昵称不能为空" })
.min(1, "昵称不能为空")
.max(20, "昵称不能超过 20 个字符"),
email: z
.string({ required_error: "邮箱不能为空" })
.min(1, "邮箱不能为空")
.email("请输入有效的邮箱地址"),
password: z
.string({ required_error: "密码不能为空" })
.min(8, "密码至少 8 位")
.max(100, "密码不能超过 100 位")
.regex(/[a-zA-Z]/, "密码必须包含英文字母")
.regex(/[0-9]/, "密码必须包含数字")
})
);
const { handleSubmit, isSubmitting } = useForm({
validationSchema: formSchema
});
const onSubmit = handleSubmit(async (values) => {
const ok = await authStore.signUp(values.name, values.email, values.password);
if (ok) {
await navigateTo("/");
}
});
</script>
<template>
<div class="flex min-h-[60vh] items-center justify-center">
<div class="w-full max-w-sm space-y-6">
<div class="space-y-1 text-center">
<h1 class="text-2xl font-semibold">注册</h1>
<p class="text-sm text-muted-foreground">创建新账号</p>
</div>
<form class="space-y-4" @submit="onSubmit">
<FormField v-slot="{ componentField }" name="name">
<FormItem>
<FormLabel>昵称</FormLabel>
<FormControl>
<Input
type="text"
autocomplete="name"
placeholder="你的昵称"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="email">
<FormItem>
<FormLabel>邮箱</FormLabel>
<FormControl>
<Input
type="email"
autocomplete="email"
placeholder="your@email.com"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="password">
<FormItem>
<FormLabel>密码</FormLabel>
<FormControl>
<Input
type="password"
autocomplete="new-password"
placeholder="至少 8 位"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<p v-if="authStore.error" class="text-sm text-destructive">
{{ authStore.error }}
</p>
<Button
type="submit"
:disabled="
isSubmitting || authStore.loading || !authStore.initialized
"
class="w-full"
>
{{ authStore.loading ? "注册中..." : "注册" }}
</Button>
</form>
<p class="text-center text-sm text-muted-foreground">
已有账号
<NuxtLink
to="/login"
class="underline underline-offset-4 hover:text-primary"
>
登录
</NuxtLink>
</p>
</div>
</div>
</template>