/** * 登录业务数据传输对象 * * 功能描述: * - 定义登录相关API的请求数据结构 * - 提供数据验证规则和错误提示 * - 确保API接口的数据格式一致性 * * @author moyin * @version 1.0.0 * @since 2025-12-17 */ import { IsString, IsEmail, IsPhoneNumber, IsNotEmpty, Length, IsOptional, Matches, IsNumberString } from 'class-validator'; /** * 登录请求DTO */ export class LoginDto { /** * 登录标识符 * 支持用户名、邮箱或手机号登录 */ @IsString({ message: '登录标识符必须是字符串' }) @IsNotEmpty({ message: '登录标识符不能为空' }) @Length(1, 100, { message: '登录标识符长度需在1-100字符之间' }) identifier: string; /** * 密码 */ @IsString({ message: '密码必须是字符串' }) @IsNotEmpty({ message: '密码不能为空' }) @Length(1, 128, { message: '密码长度需在1-128字符之间' }) password: string; } /** * 注册请求DTO */ export class RegisterDto { /** * 用户名 */ @IsString({ message: '用户名必须是字符串' }) @IsNotEmpty({ message: '用户名不能为空' }) @Length(1, 50, { message: '用户名长度需在1-50字符之间' }) @Matches(/^[a-zA-Z0-9_]+$/, { message: '用户名只能包含字母、数字和下划线' }) username: string; /** * 密码 */ @IsString({ message: '密码必须是字符串' }) @IsNotEmpty({ message: '密码不能为空' }) @Length(8, 128, { message: '密码长度需在8-128字符之间' }) @Matches(/^(?=.*[a-zA-Z])(?=.*\d)/, { message: '密码必须包含字母和数字' }) password: string; /** * 昵称 */ @IsString({ message: '昵称必须是字符串' }) @IsNotEmpty({ message: '昵称不能为空' }) @Length(1, 50, { message: '昵称长度需在1-50字符之间' }) nickname: string; /** * 邮箱(可选) */ @IsOptional() @IsEmail({}, { message: '邮箱格式不正确' }) email?: string; /** * 手机号(可选) */ @IsOptional() @IsPhoneNumber(null, { message: '手机号格式不正确' }) phone?: string; } /** * GitHub OAuth登录请求DTO */ export class GitHubOAuthDto { /** * GitHub用户ID */ @IsString({ message: 'GitHub ID必须是字符串' }) @IsNotEmpty({ message: 'GitHub ID不能为空' }) @Length(1, 100, { message: 'GitHub ID长度需在1-100字符之间' }) github_id: string; /** * 用户名 */ @IsString({ message: '用户名必须是字符串' }) @IsNotEmpty({ message: '用户名不能为空' }) @Length(1, 50, { message: '用户名长度需在1-50字符之间' }) username: string; /** * 昵称 */ @IsString({ message: '昵称必须是字符串' }) @IsNotEmpty({ message: '昵称不能为空' }) @Length(1, 50, { message: '昵称长度需在1-50字符之间' }) nickname: string; /** * 邮箱(可选) */ @IsOptional() @IsEmail({}, { message: '邮箱格式不正确' }) email?: string; /** * 头像URL(可选) */ @IsOptional() @IsString({ message: '头像URL必须是字符串' }) avatar_url?: string; } /** * 忘记密码请求DTO */ export class ForgotPasswordDto { /** * 邮箱或手机号 */ @IsString({ message: '标识符必须是字符串' }) @IsNotEmpty({ message: '邮箱或手机号不能为空' }) @Length(1, 100, { message: '标识符长度需在1-100字符之间' }) identifier: string; } /** * 重置密码请求DTO */ export class ResetPasswordDto { /** * 邮箱或手机号 */ @IsString({ message: '标识符必须是字符串' }) @IsNotEmpty({ message: '邮箱或手机号不能为空' }) @Length(1, 100, { message: '标识符长度需在1-100字符之间' }) identifier: string; /** * 验证码 */ @IsString({ message: '验证码必须是字符串' }) @IsNotEmpty({ message: '验证码不能为空' }) @Matches(/^\d{6}$/, { message: '验证码必须是6位数字' }) verification_code: string; /** * 新密码 */ @IsString({ message: '新密码必须是字符串' }) @IsNotEmpty({ message: '新密码不能为空' }) @Length(8, 128, { message: '新密码长度需在8-128字符之间' }) @Matches(/^(?=.*[a-zA-Z])(?=.*\d)/, { message: '新密码必须包含字母和数字' }) new_password: string; } /** * 修改密码请求DTO */ export class ChangePasswordDto { /** * 用户ID * 实际应用中应从JWT令牌中获取,这里为了演示放在请求体中 */ @IsNumberString({}, { message: '用户ID必须是数字字符串' }) @IsNotEmpty({ message: '用户ID不能为空' }) user_id: string; /** * 旧密码 */ @IsString({ message: '旧密码必须是字符串' }) @IsNotEmpty({ message: '旧密码不能为空' }) @Length(1, 128, { message: '旧密码长度需在1-128字符之间' }) old_password: string; /** * 新密码 */ @IsString({ message: '新密码必须是字符串' }) @IsNotEmpty({ message: '新密码不能为空' }) @Length(8, 128, { message: '新密码长度需在8-128字符之间' }) @Matches(/^(?=.*[a-zA-Z])(?=.*\d)/, { message: '新密码必须包含字母和数字' }) new_password: string; }