feat: update
This commit is contained in:
111
schemas/auth.ts
Normal file
111
schemas/auth.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 认证相关的 Zod 验证 Schema
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* 登录表单 Schema
|
||||
*/
|
||||
export const loginSchema = z.object({
|
||||
email: z.string().min(1, '请输入邮箱').email('请输入有效的邮箱地址'),
|
||||
password: z.string().min(6, '密码至少6个字符').max(20, '密码最多20个字符'),
|
||||
rememberMe: z.boolean().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* 注册表单 Schema
|
||||
*/
|
||||
export const registerSchema = z
|
||||
.object({
|
||||
username: z
|
||||
.string()
|
||||
.min(3, '用户名至少3个字符')
|
||||
.max(20, '用户名最多20个字符')
|
||||
.regex(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线'),
|
||||
email: z.string().min(1, '请输入邮箱').email('请输入有效的邮箱地址'),
|
||||
password: z
|
||||
.string()
|
||||
.min(6, '密码至少6个字符')
|
||||
.max(20, '密码最多20个字符')
|
||||
.regex(/[A-Z]/, '密码必须包含至少一个大写字母')
|
||||
.regex(/[a-z]/, '密码必须包含至少一个小写字母')
|
||||
.regex(/[0-9]/, '密码必须包含至少一个数字'),
|
||||
confirmPassword: z.string().min(1, '请确认密码'),
|
||||
agreeToTerms: z.boolean().refine((val) => val === true, {
|
||||
message: '请同意服务条款',
|
||||
}),
|
||||
})
|
||||
.refine((data) => data.password === data.confirmPassword, {
|
||||
message: '两次输入的密码不一致',
|
||||
path: ['confirmPassword'],
|
||||
});
|
||||
|
||||
/**
|
||||
* 忘记密码 Schema
|
||||
*/
|
||||
export const forgotPasswordSchema = z.object({
|
||||
email: z.string().min(1, '请输入邮箱').email('请输入有效的邮箱地址'),
|
||||
});
|
||||
|
||||
/**
|
||||
* 重置密码 Schema
|
||||
*/
|
||||
export const resetPasswordSchema = z
|
||||
.object({
|
||||
code: z
|
||||
.string()
|
||||
.min(6, '验证码为6位')
|
||||
.max(6, '验证码为6位')
|
||||
.regex(/^\d{6}$/, '验证码必须是6位数字'),
|
||||
password: z.string().min(6, '密码至少6个字符').max(20, '密码最多20个字符'),
|
||||
confirmPassword: z.string().min(1, '请确认密码'),
|
||||
})
|
||||
.refine((data) => data.password === data.confirmPassword, {
|
||||
message: '两次输入的密码不一致',
|
||||
path: ['confirmPassword'],
|
||||
});
|
||||
|
||||
/**
|
||||
* 修改密码 Schema
|
||||
*/
|
||||
export const changePasswordSchema = z
|
||||
.object({
|
||||
oldPassword: z.string().min(1, '请输入当前密码'),
|
||||
newPassword: z.string().min(6, '新密码至少6个字符').max(20, '新密码最多20个字符'),
|
||||
confirmPassword: z.string().min(1, '请确认新密码'),
|
||||
})
|
||||
.refine((data) => data.newPassword === data.confirmPassword, {
|
||||
message: '两次输入的密码不一致',
|
||||
path: ['confirmPassword'],
|
||||
})
|
||||
.refine((data) => data.oldPassword !== data.newPassword, {
|
||||
message: '新密码不能与当前密码相同',
|
||||
path: ['newPassword'],
|
||||
});
|
||||
|
||||
/**
|
||||
* 手机号登录 Schema
|
||||
*/
|
||||
export const phoneLoginSchema = z.object({
|
||||
phone: z
|
||||
.string()
|
||||
.min(11, '请输入11位手机号')
|
||||
.max(11, '请输入11位手机号')
|
||||
.regex(/^1[3-9]\d{9}$/, '请输入有效的手机号'),
|
||||
code: z
|
||||
.string()
|
||||
.min(6, '验证码为6位')
|
||||
.max(6, '验证码为6位')
|
||||
.regex(/^\d{6}$/, '验证码必须是6位数字'),
|
||||
});
|
||||
|
||||
/**
|
||||
* TypeScript 类型推断
|
||||
*/
|
||||
export type LoginFormData = z.infer<typeof loginSchema>;
|
||||
export type RegisterFormData = z.infer<typeof registerSchema>;
|
||||
export type ForgotPasswordFormData = z.infer<typeof forgotPasswordSchema>;
|
||||
export type ResetPasswordFormData = z.infer<typeof resetPasswordSchema>;
|
||||
export type ChangePasswordFormData = z.infer<typeof changePasswordSchema>;
|
||||
export type PhoneLoginFormData = z.infer<typeof phoneLoginSchema>;
|
||||
36
schemas/index.ts
Normal file
36
schemas/index.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Schemas 模块统一导出
|
||||
*/
|
||||
|
||||
// Auth Schemas
|
||||
export {
|
||||
loginSchema,
|
||||
registerSchema,
|
||||
forgotPasswordSchema,
|
||||
resetPasswordSchema,
|
||||
changePasswordSchema,
|
||||
phoneLoginSchema,
|
||||
} from './auth';
|
||||
export type {
|
||||
LoginFormData,
|
||||
RegisterFormData,
|
||||
ForgotPasswordFormData,
|
||||
ResetPasswordFormData,
|
||||
ChangePasswordFormData,
|
||||
PhoneLoginFormData,
|
||||
} from './auth';
|
||||
|
||||
// User Schemas
|
||||
export {
|
||||
userSchema,
|
||||
updateUserSchema,
|
||||
bindPhoneSchema,
|
||||
bindEmailSchema,
|
||||
} from './user';
|
||||
export type {
|
||||
UserFormData,
|
||||
UpdateUserFormData,
|
||||
BindPhoneFormData,
|
||||
BindEmailFormData,
|
||||
} from './user';
|
||||
|
||||
68
schemas/user.ts
Normal file
68
schemas/user.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* 用户相关的 Zod 验证 Schema
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* 用户信息 Schema
|
||||
*/
|
||||
export const userSchema = z.object({
|
||||
id: z.string(),
|
||||
username: z.string(),
|
||||
email: z.string().email(),
|
||||
avatar: z.string().url().optional(),
|
||||
nickname: z.string().optional(),
|
||||
phone: z.string().optional(),
|
||||
createdAt: z.string().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* 更新用户资料 Schema
|
||||
*/
|
||||
export const updateProfileSchema = z.object({
|
||||
nickname: z.string().min(2, '昵称至少2个字符').max(20, '昵称最多20个字符').optional(),
|
||||
avatar: z.string().url('请输入有效的头像URL').optional(),
|
||||
phone: z
|
||||
.string()
|
||||
.regex(/^1[3-9]\d{9}$/, '请输入有效的手机号')
|
||||
.optional()
|
||||
.or(z.literal('')),
|
||||
bio: z.string().max(200, '个人简介最多200个字符').optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* 绑定手机号 Schema
|
||||
*/
|
||||
export const bindPhoneSchema = z.object({
|
||||
phone: z
|
||||
.string()
|
||||
.min(11, '请输入11位手机号')
|
||||
.max(11, '请输入11位手机号')
|
||||
.regex(/^1[3-9]\d{9}$/, '请输入有效的手机号'),
|
||||
code: z
|
||||
.string()
|
||||
.min(6, '验证码为6位')
|
||||
.max(6, '验证码为6位')
|
||||
.regex(/^\d{6}$/, '验证码必须是6位数字'),
|
||||
});
|
||||
|
||||
/**
|
||||
* 绑定邮箱 Schema
|
||||
*/
|
||||
export const bindEmailSchema = z.object({
|
||||
email: z.string().min(1, '请输入邮箱').email('请输入有效的邮箱地址'),
|
||||
code: z
|
||||
.string()
|
||||
.min(6, '验证码为6位')
|
||||
.max(6, '验证码为6位')
|
||||
.regex(/^\d{6}$/, '验证码必须是6位数字'),
|
||||
});
|
||||
|
||||
/**
|
||||
* TypeScript 类型推断
|
||||
*/
|
||||
export type User = z.infer<typeof userSchema>;
|
||||
export type UpdateProfileFormData = z.infer<typeof updateProfileSchema>;
|
||||
export type BindPhoneFormData = z.infer<typeof bindPhoneSchema>;
|
||||
export type BindEmailFormData = z.infer<typeof bindEmailSchema>;
|
||||
Reference in New Issue
Block a user