Skip to content

基础

Terminal window
nest --help
# 生成module
nest g mo user
# 生成controller
nest g co user
# 生成service
nest g s user
# 生成CRUD
nest g res user
# 生成logger中间件
nest g mi logger
# 生成user管道
nest g pi user
# 创建守卫
nest g gu role
# 创建自定义装饰器
nest g d user
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { VersioningType } from "@nestjs/common";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 开启版本控制,使用URI方式
app.enableVersioning({
type: VersioningType.URI,
});
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/t/t.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Version,
} from "@nestjs/common";
import { TService } from "./t.service";
import { CreateTDto } from "./dto/create-t.dto";
import { UpdateTDto } from "./dto/update-t.dto";
// @Controller('t')
@Controller({
path: "t",
version: "1", // http://localhost:3000/v1/t
})
export class TController {
constructor(private readonly tService: TService) {}
@Get()
// @Version("1") // http://localhost:3000/v1/t
findAll() {
return this.tService.findAll();
}
}
src/t/t.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Version,
Request,
Query,
HttpCode,
} from "@nestjs/common";
import { TService } from "./t.service";
import { CreateTDto } from "./dto/create-t.dto";
import { UpdateTDto } from "./dto/update-t.dto";
@Controller("t")
export class TController {
constructor(private readonly tService: TService) {}
@Post()
// create(@Request() req) {
// console.log(req.body);
// return {
// code: 0,
// msg: 'success',
// data: req.body,
// };
// }
create(@Body() createTDto: CreateTDto) {
console.log(createTDto);
return this.tService.create(createTDto);
}
@Get()
// findAll(@Request() req) {
// console.log(req.query);
// return this.tService.findAll();
// }
@HttpCode(200)
findAll(@Query() query) {
console.log(query);
return this.tService.findAll();
}
@Get(":id")
findOne(@Param("id") id: string) {
return this.tService.findOne(+id);
}
}
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import session from "express-session";
import { NestExpressApplication } from "@nestjs/platform-express";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.enableCors();
app.use(
session({
secret: process.env.SESSION_SECRET || "your-secret-key",
rolling: true,
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60 * 60 * 1000, // 1小时
httpOnly: true,
},
}),
);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/auth/auth.controller.ts
import { Controller, Post, Body, Get, Req, Res, Session } from "@nestjs/common";
import { AuthService } from "./auth.service";
import * as svgCaptcha from "svg-captcha";
import { UserLoginDto } from "./dto/user-login.dto";
@Controller("auth")
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post("login")
login(@Body() userLoginDto: UserLoginDto, @Session() session) {
console.log(session.captcha, createAuthDto.code);
if (
session.captcha.toLocaleLowerCase() ===
createAuthDto?.code?.toLocaleLowerCase()
) {
return {
code: 0,
msg: "验证成功",
};
} else {
return {
code: -1,
msg: "验证失败",
};
}
}
@Get("code")
getCode(@Req() req, @Res() res, @Session() session) {
const captcha = svgCaptcha.create({
size: 4,
fontSize: 50,
width: 100,
height: 34,
background: "#cc9966",
});
// console.log(captcha);
session.captcha = captcha.text;
res.type("image/svg+xml");
res.send(captcha.data);
}
}
src/pages/login.vue
<script setup lang="ts">
import type { FormInst, FormRules } from "naive-ui";
import { useMessage } from "naive-ui";
import { ref } from "vue";
interface LoginModel {
account: string;
password: string;
code: string;
}
const message = useMessage();
const formRef = ref<FormInst | null>(null);
const loading = ref(false);
const modelRef = ref<LoginModel>({
account: "",
password: "",
code: "",
});
const rules: FormRules = {
account: [
{
required: true,
message: "请输入账号",
trigger: ["blur", "input"],
},
],
password: [
{
required: true,
message: "请输入密码",
trigger: ["blur", "input"],
},
],
};
async function handleLogin() {
if (loading.value) return;
await formRef.value?.validate(async (errors) => {
if (errors) {
message.error("请填写正确信息");
return;
}
try {
loading.value = true;
fetch("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(modelRef.value),
})
.then((res) => {
if (!res.ok) {
throw new Error("登录失败");
}
return res.json();
})
.then((data) => {
if (data.code !== 0) {
throw new Error(data.msg);
}
return data.data;
});
message.success("登录成功");
// TODO
// router.push('/dashboard')
} catch (err) {
message.error("登录失败");
} finally {
loading.value = false;
}
});
}
function handleKeyDown(e: KeyboardEvent) {
if (e.key === "Enter") {
handleLogin();
}
}
const getCaptchaUrl = ref<string>("/api/auth/code");
const handleCaptchaClick = () => {
// getCaptchaUrl.value = `/api/auth/code?${Date.now()}`
getCaptchaUrl.value = getCaptchaUrl.value + "?" + Math.random();
};
</script>
<template>
<div class="login-wrapper">
<n-card title="系统登录" class="login-card">
<n-form
class="login-form"
ref="formRef"
:model="modelRef"
:rules="rules"
:label-width="70"
:show-require-mark="false"
>
<n-form-item path="account" label="账号">
<n-input
v-model:value="modelRef.account"
type="text"
placeholder="请输入账号"
@keydown="handleKeyDown"
/>
</n-form-item>
<n-form-item path="password" label="密码">
<n-input
v-model:value="modelRef.password"
type="password"
show-password-on="mousedown"
placeholder="请输入密码"
@keydown="handleKeyDown"
/>
</n-form-item>
<n-form-item path="code" label="验证码">
<n-input
v-model:value="modelRef.code"
placeholder="请输入验证码"
@keydown="handleKeyDown"
/>
<img :src="getCaptchaUrl" alt="验证码" @click="handleCaptchaClick" />
</n-form-item>
<div class="login-button">
<n-button
block
type="primary"
:loading="loading"
@click="handleLogin"
>
登录
</n-button>
</div>
</n-form>
</n-card>
</div>
</template>
<style scoped>
.login-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.login-card {
width: 380px;
}
.login-form {
text-align: left;
}
.login-button {
margin-top: 10px;
}
:deep(.n-form-item-feedback-wrapper) {
text-align: left;
}
</style>
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
@Module({
imports: [TModule, AuthModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
@Module({
imports: [TModule, AuthModule],
controllers: [AppController],
providers: [
{
provide: "APP_SERVICE",
useClass: AppService,
},
],
})
export class AppModule {}
src/app.controller.ts
import { Controller, Get, Inject } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(@Inject("APP_SERVICE") private readonly appService: AppService) {}
}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
@Module({
imports: [TModule, AuthModule],
controllers: [AppController],
providers: [
{
provide: "APP_SERVICE",
useClass: AppService,
},
{
provide: "APP_VALUE",
useValue: ["a", "b", "c"],
},
],
})
export class AppModule {}
src/app.controller.ts
import { Controller, Get, Inject } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(
@Inject("APP_SERVICE") private readonly appService: AppService,
@Inject("APP_VALUE") private readonly appValue: string[],
) {}
}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
@Module({
imports: [TModule, AuthModule],
controllers: [AppController],
providers: [
{
provide: "APP_SERVICE",
useClass: AppService,
},
{
provide: "APP_VALUE",
useValue: ["a", "b", "c"],
},
{
provide: "APP_FACTORY",
useFactory: (appService: AppService) => {
return `Factory value: ${appService.getHello()}`;
},
inject: ["APP_SERVICE"],
},
],
})
export class AppModule {}
src/app.controller.ts
import { Controller, Get, Inject } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(
@Inject("APP_SERVICE") private readonly appService: AppService,
@Inject("APP_VALUE") private readonly appValue: string[],
@Inject("APP_FACTORY") private readonly appFactory: string,
) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
import { UserModule } from "./user/user.module";
import { PostModule } from "./post/post.module";
@Module({
imports: [TModule, AuthModule, UserModule, PostModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
src/user/user.module.ts
import { Module } from "@nestjs/common";
import { UserService } from "./user.service";
import { UserController } from "./user.controller";
@Module({
controllers: [UserController],
providers: [UserService],
exports: [UserService], // 导出UserService变成共享模块
})
export class UserModule {}
src/post/post.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
} from "@nestjs/common";
import { PostService } from "./post.service";
import { CreatePostDto } from "./dto/create-post.dto";
import { UpdatePostDto } from "./dto/update-post.dto";
import { UserService } from "src/user/user.service";
@Controller("post")
export class PostController {
constructor(
private readonly postService: PostService,
private readonly userService: UserService,
) {}
}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
import { UserModule } from "./user/user.module";
import { PostModule } from "./post/post.module";
import { ConfigModule } from "./config/config.module";
@Module({
imports: [TModule, AuthModule, UserModule, PostModule, ConfigModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
src/config/config.module.ts
import { Global, Module } from "@nestjs/common";
@Global()
@Module({
providers: [
{
provide: "CONFIG",
useValue: {
baseURL: "/api",
},
},
],
exports: ["CONFIG"],
})
export class ConfigModule {}
src/user/user.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Inject,
} from "@nestjs/common";
import { UserService } from "./user.service";
import { CreateUserDto } from "./dto/create-user.dto";
import { UpdateUserDto } from "./dto/update-user.dto";
@Controller("user")
export class UserController {
constructor(
private readonly userService: UserService,
@Inject("CONFIG") private config: { baseURL: string },
) {}
}
src/app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { TModule } from "./t/t.module";
import { AuthModule } from "./auth/auth.module";
import { UserModule } from "./user/user.module";
import { PostModule } from "./post/post.module";
import { ConfigModule } from "./config/config.module";
@Module({
imports: [
TModule,
AuthModule,
UserModule,
PostModule,
ConfigModule.forRoot({ path: "/v1" }),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
src/config/config.module.ts
import { DynamicModule, Global, Module } from "@nestjs/common";
interface Options {
path: string;
}
@Global()
@Module({})
export class ConfigModule {
static forRoot(options: Options): DynamicModule {
return {
module: ConfigModule,
providers: [
{
provide: "CONFIG",
useValue: {
baseURL: "/api" + options.path,
},
},
],
exports: ["CONFIG"],
};
}
}
src/logger/logger.middleware.ts
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`${req.method} ${req.originalUrl}`);
next();
}
}
src/user/user.module.ts
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
import { UserService } from "./user.service";
import { UserController } from "./user.controller";
import { LoggerMiddleware } from "src/logger/logger.middleware";
@Module({
controllers: [UserController],
providers: [UserService],
exports: [UserService],
})
export class UserModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes("user");
}
}
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { Request, Response, NextFunction } from "express";
const whiteList = ["/user"];
function logger(req: Request, res: Response, next: NextFunction) {
// console.log(`${req.method} ${req.url}`);
// next();
if (whiteList.includes(req.originalUrl)) {
next();
} else {
res.status(403).json({ msg: "Forbidden" });
}
}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { Response } from "./common/response";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useGlobalInterceptors(new Response());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/common/response.ts
import { CallHandler, Injectable, NestInterceptor } from "@nestjs/common";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
interface Data<T> {
data: T;
}
@Injectable()
export class Response<T> implements NestInterceptor {
intercept(context: any, next: CallHandler): Observable<Data<T>> {
return next.handle().pipe(
map((data) => {
return {
status: 0,
message: "success",
success: true,
data: data,
};
}),
);
}
}
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { Response } from "./common/response";
import { HttpFilter } from "./common/filter";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useGlobalFilters(new HttpFilter());
app.useGlobalInterceptors(new Response());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/common/filter.ts
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
} from "@nestjs/common";
import { Request, Response } from "express";
@Catch(HttpException)
export class HttpFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
response.status(status).json({
status,
success: false,
message: exception.message,
data: null,
time: new Date(),
path: request.url,
});
}
}
src/p/p.controller.ts
import { Controller, Get, Param, ParseIntPipe } from "@nestjs/common";
import { PService } from "./p.service";
@Controller("p")
export class PController {
constructor(private readonly pService: PService) {}
@Get(":id")
findOne(@Param("id", ParseIntPipe) id: number) {
console.log(typeof id);
return this.pService.findOne(+id);
}
}

Custom pipes (不推荐)

src/auth/dto/user-register.dto.ts
import { IsNotEmpty, IsString, Length } from "class-validator";
export class UserRegisterDto {
@IsNotEmpty()
@IsString()
@Length(5, 20, {
message: "账号长度为5-20个字符",
})
account: string;
@IsString()
password: string;
@IsString()
code: string;
}
src/auth/validation.pipe.ts
import {
PipeTransform,
Injectable,
ArgumentMetadata,
HttpException,
HttpStatus,
} from "@nestjs/common";
import { validate } from "class-validator";
import { plainToInstance } from "class-transformer";
@Injectable()
export class ValidationPipe implements PipeTransform {
async transform(value: any, metadata: ArgumentMetadata) {
if (!metadata.metatype || !this.toValidate(metadata.metatype)) {
return value;
}
const object = plainToInstance(metadata.metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new HttpException(errors, HttpStatus.BAD_REQUEST);
}
return value;
}
private toValidate(metatype: Function): boolean {
const types: Function[] = [String, Boolean, Number, Array, Object];
return !types.includes(metatype);
}
}
src/auth/auth.controller.ts
import { Controller, Post, Body, Session } from "@nestjs/common";
import { AuthService } from "./auth.service";
import { ValidationPipe } from "./validation.pipe";
import { UserLoginDto } from "./dto/user-login.dto";
@Controller("auth")
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post("login")
login(@Body(ValidationPipe) userLoginDto: UserLoginDto, @Session() session) {}
}

Global scoped pipes (推荐)

src/main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

守卫在每个中间件之后执行,在每个拦截器或管道之前执行。

src/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
import { Observable } from "rxjs";
import { Reflector } from "@nestjs/core";
import type { Request } from "express";
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const admin = this.reflector.get<string[]>("role", context.getHandler());
const request = context.switchToHttp().getRequest<Request>();
if (admin.includes(request.query.role as string)) {
return true;
}
return false;
}
}
src/user/user.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Inject,
UseGuards,
SetMetadata,
} from "@nestjs/common";
import { UserService } from "./user.service";
import { CreateUserDto } from "./dto/create-user.dto";
import { UpdateUserDto } from "./dto/update-user.dto";
import { AuthGuard } from "src/auth.guard";
@Controller("user")
@UseGuards(AuthGuard)
export class UserController {
constructor(
private readonly userService: UserService,
@Inject("CONFIG") private config: { baseURL: string },
) {}
@Get()
@SetMetadata("role", ["admin"])
findAll() {
return this.userService.findAll();
}
}
src/role.decorator.ts
import {
SetMetadata,
createParamDecorator,
ExecutionContext,
} from "@nestjs/common";
import type { Request } from "express";
export const Role = (...args: string[]) => SetMetadata("role", args);
// 自定义参数装饰器
export const ReqURL = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest<Request>();
console.log(data);
return request.url;
},
);
src/user/user.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Inject,
UseGuards,
SetMetadata,
} from "@nestjs/common";
import { UserService } from "./user.service";
import { ReqURL, Role } from "src/role.decorator";
@Controller("user")
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
@Role("admin")
findAll(@ReqURL("12") url: string) {
console.log(url);
return this.userService.findAll();
}
}
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { NestExpressApplication } from "@nestjs/platform-express";
import { join } from "path";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.enableCors();
// 配置静态资源访问
app.useStaticAssets(join(__dirname, "uploads"), {
prefix: "/images",
});
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/file/file.module.ts
import { Module } from "@nestjs/common";
import { FileService } from "./file.service";
import { FileController } from "./file.controller";
import { MulterModule } from "@nestjs/platform-express";
import { diskStorage } from "multer";
import { extname, join } from "path";
@Module({
imports: [
MulterModule.register({
storage: diskStorage({
destination: join(__dirname, "../uploads"),
filename: (_, file, callback) => {
const fileName = `${new Date().getTime() + extname(file.originalname)}`;
callback(null, fileName);
},
}),
}),
],
controllers: [FileController],
providers: [FileService],
})
export class FileModule {}
src/file/file.controller.ts
import {
Controller,
Post,
UseInterceptors,
UploadedFile,
UploadedFiles,
Get,
Res,
} from "@nestjs/common";
import { FileService } from "./file.service";
import {
FileFieldsInterceptor,
FileInterceptor,
} from "@nestjs/platform-express";
import { join } from "path";
import type { Response } from "express";
import { zip } from "compressing";
@Controller("file")
export class FileController {
constructor(private readonly fileService: FileService) {}
@Post("upload")
@UseInterceptors(FileInterceptor("file"))
uploadFile(@UploadedFile() file: Express.Multer.File) {
console.log(file);
}
@Post("uploads")
@UseInterceptors(
FileFieldsInterceptor([
{ name: "avatar", maxCount: 1 },
{ name: "background", maxCount: 1 },
]),
)
uploadFiles(
@UploadedFiles()
files: {
avatar?: Express.Multer.File[];
background?: Express.Multer.File[];
},
) {
console.log(files);
}
@Get("download")
downloadFile(@Res() res: Response) {
const url = join(__dirname, "../images/1.png");
res.download(url);
}
@Get("dl")
async downloadFileWithStream(@Res() res: Response) {
const url = join(__dirname, "../images/1.png");
const stream = new zip.Stream();
await stream.addEntry(url);
res.setHeader("Content-Type", "application/octet-stream");
res.setHeader("Content-Disposition", 'attachment; filename="1.zip"');
stream.pipe(res);
}
}
src/pages/download.vue
<script setup lang="ts">
const useFetch = async (link: string) => {
const res = await fetch(link).then((res) => res.arrayBuffer());
const blob = new Blob([res]);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "1.zip";
a.click();
URL.revokeObjectURL(url);
};
const download = () => {
useFetch("http://localhost:3000/file/dl");
// window.open('http://localhost:3000/file/download')
};
</script>
<template>
<button @click="download">Download</button>
</template>
<style scoped></style>
src/spider/spider.service.ts
import { Injectable } from "@nestjs/common";
import * as cheerio from "cheerio";
import axios from "axios";
import path from "path";
import fs from "fs";
@Injectable()
export class SpiderService {
async findAll() {
const urls: string[] = [];
const baseURL = "";
const nextText = "下一页";
let index = 0;
const getData = async () => {
const body = await axios
.get(`https://exmple.com/${index ? "_" + index : ""}`)
.then(async (res) => res.data);
const $ = cheerio.load(body);
const page = $(".pagination").eq(0).find("span");
const pageArray = page
.map(function () {
return $(this).text();
})
.toArray();
if (pageArray.includes(nextText)) {
$(".content-area a .post-title").each(function () {
urls.push(baseURL + $(this).attr("href"));
});
index++;
await getData();
}
};
await getData();
this.downloadFile(urls);
return `This action returns all spider`;
}
downloadFile(urls: string[]) {
urls.forEach(async (url) => {
const res = await axios
.get(url, { responseType: "arraybuffer" })
.then((res) => res.data);
const ws = fs.createWriteStream(
path.join(__dirname, "../downloads/" + new Date().getTime() + ".png"),
);
ws.write(res);
ws.end();
});
}
}
src/main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { NestExpressApplication } from "@nestjs/platform-express";
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const config = new DocumentBuilder()
.addBearerAuth()
.setTitle("Users example")
.setDescription("The users API description")
.setVersion("1.0")
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup("/api-docs", app, documentFactory);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
src/user/user.controller.ts
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
Inject,
UseGuards,
SetMetadata,
} from "@nestjs/common";
import { UserService } from "./user.service";
import {
ApiBearerAuth,
ApiOperation,
ApiParam,
ApiQuery,
ApiTags,
} from "@nestjs/swagger";
@ApiBearerAuth()
@ApiTags("user")
@Controller("user")
export class UserController {
constructor(private readonly userService: UserService) {}
@Post()
@ApiOperation({ summary: "Create user" })
create(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}
@Get()
@ApiQuery({
name: "page",
description: "page list",
})
findAll() {
return this.userService.findAll();
}
@Get(":id")
@ApiParam({
name: "id",
description: "user id",
required: true,
type: "string",
example: "11",
})
findOne(@Param("id") id: string) {
return this.userService.findOne(+id);
}
}
src/user/dto/create-user.dto.ts
import { ApiProperty } from "@nestjs/swagger";
export class CreateUserDto {
@ApiProperty({ example: "login_name" })
account: string;
@ApiProperty({ example: "password" })
password: string;
}