1.项目结构
src
auth
dto (包含数据传输对象,Data Transfer Object,相关的文件)
register.dto.ts 注册DTO,用于传输注册用户的信息
auth.controller.ts 负责处理身份验证相关的路由和控制逻辑
auth.module.ts 身份验证模块,定义身份验证相关的模块和服务提供者
auth.service.ts 身份验证服务,处理用户身份验证的逻辑
common
rules 包含通用的验证规则相关的文件
is-not-exists.rule.ts 定义了一个验证规则,检查某些条件是否不存在
validate.ts 通用的验证逻辑,用于执行验证逻辑
app.module.ts 项目的主模块文件,定义了整个项目的根模块
main.ts 项目的入口文件启动整个应用程序
2.dto例
register.dto.ts
import { IsNotEmpty } from "class-validator";
import { IsNotExistsRule } from "../../common/rules/is-not-exists.rule";
export default class RegisterDto {
@IsNotEmpty({ message: '用户名不能为空' })
@IsNotExistsRule("user" , {message: "用户已存在"})
name: string;
@IsNotEmpty({ message: '密码不能为空' })
password: string;
}
3.auth例
auth.controller.ts
import { AuthService } from "./auth.service";
import { Controller , Body , Post } from "@nestjs/common";
import RegisterDto from "./dto/register.dto";
@Controller()
export class AuthController {
constructor(private auth:AuthService) {}
@Post("register")
register(@Body() body:RegisterDto) {
return body;
}
@Post("login")
login(){
return "abc"
}
}
auth.module.ts
import { Module } from "@nestjs/common";
import { AuthService } from "./auth.service";
import { AuthController } from './auth.controller';
@Module({
controllers: [AuthController],
providers: [AuthService],
})
export class AuthMoudule {}
auth.service.ts
import { Injectable } from "@nestjs/common";
@Injectable()
export class AuthService {
}
4.common例
rules
is-not-exists.rule.ts
import { PrismaClient } from "@prisma/client";
import {
registerDecorator,
ValidationArguments,
ValidationOptions,
} from "class-validator";
//自定义验证规则,用于检查数据库表中指定字段的值是否唯一
export function IsNotExistsRule(
table: string, // 数据库表名
validationOptions?: ValidationOptions // 验证选项
){
return function (object: Record<string, any>, propertyName: string){
registerDecorator({
name: "isNotExistsRule", // 规则名称
target: object.constructor, // 被装饰的类
propertyName: propertyName, // 被装饰的属性名
constraints: [table], // 约束参数,指定数据库表名
options: validationOptions, // 验证选项
validator: {
// 异步验证函数,检查数据库表中是否已存在相同值
async validate(value: string, args: ValidationArguments){
const prisma = new PrismaClient();
const res = await prisma[table].findFirst({
where: {
[args.property]: value // 使用 propertyName 属性名和传入的值查找记录
}
})
// 返回判断结果,如果 res 存在则返回 false,表示不符合规则
return !Boolean(res)
}
}
})
}
}
validate.ts
import { HttpException, HttpStatus, ValidationPipe } from "@nestjs/common"
import { ValidationError } from "class-validator"
export default class Validate extends ValidationPipe {
protected flattenValidationErrors(validationErrors: ValidationError[]): string[] {
const messages = {};
validationErrors.forEach(error => {
messages[error.property] = Object.values(error.constraints)[0];
});
throw new HttpException({
code:422,
messages,
},HttpStatus.UNPROCESSABLE_ENTITY)
}
}