TypeScript NestJS文件上传下载接口
我这里用了mongodb保存文件上传记录 mongoose框架
- 安装依赖
修改package.json 后yarn install
"dependencies": {
"@grpc/proto-loader": "^0.6.1",
"@nestjs/common": "^7.6.15",
"@nestjs/config": "^0.6.3",
"@nestjs/core": "^7.6.15",
"@nestjs/microservices": "^7.6.15",
"@nestjs/mongoose": "^7.2.4",
"@nestjs/platform-express": "^7.6.15",
"@nestjs/swagger": "^4.8.0",
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
"dayjs": "^1.10.4",
"grpc": "^1.24.6",
"md5": "^2.3.0",
"mongoose": "^5.12.3",
"nest-winston": "^1.4.0",
"nuid": "^1.1.4",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.6.6",
"swagger-ui-express": "^4.1.6",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.1"
},
"devDependencies": {
"@nestjs/cli": "^7.6.0",
"@nestjs/schematics": "^7.3.0",
"@nestjs/testing": "^7.6.15",
"@types/express": "^4.17.11",
"@types/jest": "^26.0.22",
"@types/logform": "^1.10.1",
"@types/node": "^14.14.36",
"@types/supertest": "^2.0.10",
"@types/winston": "^2.4.4",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"jest": "^26.6.3",
"prettier": "^2.2.1",
"supertest": "^6.1.3",
"ts-jest": "^26.5.4",
"ts-loader": "^8.0.18",
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3"
}
- 在app创建的时候加入
const app = await NestFactory.create<NestExpressApplication>(AdminModule, {
});
// 静态文件
app.useStaticAssets(config.uploads, {
prefix: '/uploads/',
});
- schema (mongoose的持久化用的) file.log.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema({ collection: 't_file_log' })
export class FileLog extends Document {
@Prop()
filename: string;
@Prop()
path: string;
@Prop()
time: number;
}
export const FileLogSchema = SchemaFactory.createForClass(FileLog);
- service file.log.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { FileLog } from "../schema/file.log.schema";
@Injectable()
export class FileLogService {
constructor(
@InjectModel('FileLog') private readonly fileLogModel: Model<FileLog>,
) {}
/**
* 后台管理需要的四个基本接口
* @param id
* @param obj
*/
async adminAdd(obj:object){
return this.fileLogModel.create(obj)
}
async adminUpdate(id:string, obj:object){
return this.fileLogModel.findByIdAndUpdate(id,obj)
}
async adminDelete(id:string){
return this.fileLogModel.findByIdAndDelete(id)
}
async adminList(current:number, size:number): Promise<FileLog[]> {
return this.fileLogModel.find({}).skip((current-1)*size).limit(size);
}
async adminCount(){
return this.fileLogModel.count({})
}
/**
* 后台管理需要的四个基本接口
*/
async add(obj:object){
return this.fileLogModel.create(obj)
}
}
- controller 接口实现
import {
Controller,
Post,
UploadedFiles, UseInterceptors
} from "@nestjs/common";
import { FilesInterceptor } from "@nestjs/platform-express";
import { FileLogService } from "../service/file.log.service";
import config from "../config";
import { Util } from "../util/Util";
@Controller('file')
export class FileController {
constructor(private readonly fileLogService: FileLogService) {}
@Post('upload')
@UseInterceptors(FilesInterceptor('file'))
async upload(@UploadedFiles() files){
console.log('收到请求');
let file = files[0]
if (file){
let time = new Date().getTime()
//文件的真实存储路径
let path = +'C://uploads/' + Util.getToday() + '/' + file.filename
//下载这个文件的链接
let url = 'http://192.168.0.140:3001/uploads/' + Util.getToday() + '/' + file.filename;
let log = {
filename: file.originalname,
path: path,
time: time
}
log = await this.fileLogService.add(log);
return {
// errno 即错误代码,0 表示没有错误。
// 如果有错误,errno != 0,可通过下文中的监听函数 fail 拿到该错误码进行自定义处理
"errno": 0,
// data 是一个数组,返回图片Object,Object中包含需要包含url、alt和href三个属性,它们分别代表图片地址、图片文字说明和跳转链接,alt和href属性是可选的,可以不设置或设置为空字符串,需要注意的是url是一定要填的。
"data": [
{
url: url,
alt: file.originalname,
}
]
};
}
}
}
- 接口调用了Util.getToday 每天一个文件夹存储,你也可以去掉
// 获取今天日期
static getToday() {
const Dates = new Date();
//年份
const Year: number = Dates.getFullYear();
//月份下标是0-11
const Months: any =
Dates.getMonth() + 1 < 10
? '0' + (Dates.getMonth() + 1)
: Dates.getMonth() + 1;
//具体的天数
const Day: any =
Dates.getDate() < 10 ? '0' + Dates.getDate() : Dates.getDate();
//返回数据格式
return Year + '-' + Months + '-' + Day;
}