NestJs上传文件到本地磁盘和minio

浅浅记录一下Nestjs上传 这几天也研究了mysql ngnix minio 这些服务器里面的东西

本地磁盘上传

  1. 首先创建模块
  2. 注册表
  3. 编写module 导入需要的插件
  4. 编写controll
  5. 编写service 并上传到表里面

创建模块

下载依赖

npm i @type/multer dayjs multer @nestjs/platform-express

创建文件夹
在这里插入图片描述
模块里面的内容

import { Module } from '@nestjs/common';
import { FileController } from './file.controller';
import * as dayjs from 'dayjs';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MulterModule } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { FileEntity } from './file.entity';
import { FileService } from './file.service';
@Module({
  controllers: [FileController],
  imports: [TypeOrmModule.forFeature([FileEntity]),
  MulterModule.register({
    // storage: diskStorage({
    //   //设置上传文件的路径
    //   destination: `./public/uploads/${dayjs().format('YYYY-MM-DD')}`,
    //   filename: (req, file, cb) => {
    //     //文件上传之后的回调,文件为空不走
    //     //取出结尾的类型为扩展名
    //     let ext = file.originalname.split('.').at(-1)
    //     // 在此处自定义保存后的文件名称,仍然使用原后缀名,没有就不用
    //     let filename = `${new Date().getTime()}.${ext ? ext : ''}`
    //     return cb(null, filename)

    //   },
    // }),
  }),
  ],
  providers: [FileService]

})
export class FileModule {

}

如果你需要上传到磁盘就打开注释 直接上传到minio就不需要

注册表

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

//文件表 后续弄远程url
@Entity('file')
export class FileEntity {
    @PrimaryGeneratedColumn()
    id: number;
    
    @Column()
    originalname :string
    
    @Column()
    mimetype:string

    @Column()
    size:number
   
    @Column({ type: 'varchar', length: 500 })
    path:string


}

因为上传到minio字符太长了就改成了这个类型

Controller层

使用Express.Multer.File处理文件类型

export class FileController {
    constructor(private fileService: FileService) { }
    @Post('/upload')
    @UseInterceptors(FileInterceptor('file'))
    upload(@UploadedFile() file: Express.Multer.File) {
        //单上传到磁盘
        return wrapperResponse(
             this.fileService.uploadFile(file),
            '上传文件成功'
        )
      

    }
    }

service层

拿到上传的文件并放入数据库

import { Injectable } from '@nestjs/common';
import { HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { FileEntity } from './file.entity'; // 你的文件实体
import { minioClient } from './minio';
import { join } from 'path';
import { existsSync, unlink, unlinkSync } from 'fs';
@Injectable()
export class FileService {
    constructor(
        @InjectRepository(FileEntity)
        private readonly fileRepository: Repository<FileEntity>,
    ) { }

    uploadFile(mfile: Express.Multer.File): Promise<FileEntity> {
        console.log(mfile);
        if (!mfile) {``
            throw new HttpException('文件不存在', HttpStatus.BAD_REQUEST);
        }

        // 创建文件实体
        const fileEntity = new FileEntity();
        fileEntity.originalname = mfile.originalname;
        fileEntity.mimetype = mfile.mimetype;
        fileEntity.size = mfile.size;
        fileEntity.path = mfile.path;

        // 保存到数据库
        return this.fileRepository.save(fileEntity);
    }
    }

但是要想访问到 需要在我们的main.ts配置

  app.use('/public', express.static(`${__dirname}/../public`));

即可访问到
在这里插入图片描述

上传minio

上传到磁盘并且上传到minio

准备工作

首先需要在你服务器上下载minio 并且启动服务
然后进入到这个页面
在这里插入图片描述
可以先创建一个buchets 我这里叫nest
在这里插入图片描述

在这里插入图片描述
在这里申请你的acesskey 并且记录下来我们一会会用
在这里插入图片描述

配置minio

按理说文件应该放在.env中 但是我还没写
配置如下 需要配置IP地址并且配置你之前申请的acesskey
在这里插入图片描述

Service层处理

导入这个minioClient 写入几个方法 putFile 和putFileBuffer 均为推送到minio

    putFile(filename, path) {
        console.log(filename, path);
        return minioClient.fPutObject('nest', filename,
            path)
    }


    putFilebuffer(filename: string, buffer: Buffer) {
        //如果想两个端都存在文件,可以使用 fPutObject 逻辑更简单
        return minioClient.putObject(
            'nest',
            filename,
            buffer
        )
    }
    //获取url签名
    presUrl(filename: string) {
        return minioClient.presignedUrl(
            'GET',
            'nest',
            filename,

        )
    }
单上传到minio

单上传到minio并且返回一个url代码如下

   async uploadMinio(mfile: Express.Multer.File) {
        console.log(mfile);

        if (!mfile) {
            throw new HttpException('文件不存在', HttpStatus.BAD_REQUEST);
        }

        // 确保 originalname 是字符串
        const { originalname } = mfile;
        if (typeof originalname !== 'string') {
            throw new HttpException('文件名无效', HttpStatus.BAD_REQUEST);
        }

        // 生成文件扩展名
        let ext = originalname.split('.').at(-1);
        let filename = `${new Date().getTime()}.${ext ? ext : ''}`;

        try {

            if (!Buffer.isBuffer(mfile.buffer)) {
                throw new HttpException('文件数据无效', HttpStatus.BAD_REQUEST);
            }

            await this.putFilebuffer(filename, mfile.buffer);

            let url = await this.presUrl(filename);
            console.log(url);

            return { url };
        } catch (e) {
     
            throw new HttpException('上传失败', HttpStatus.BAD_REQUEST);
        }
    }
上传到磁盘又上传到服务器
    //即上传到服务器也上传到磁盘
    async uploadFileMinio(mfile: Express.Multer.File) {
        if (!mfile) {
            throw new HttpException('文件不存在', HttpStatus.BAD_REQUEST);
        }
        let url = null
        const linkPath = join(__dirname, `../../${mfile.path}`)
        try {
            await this.putFile(mfile.filename, mfile.path)
            url = await this.presUrl(mfile.filename)
        } catch (e) {
            existsSync(linkPath) && unlinkSync(linkPath)

            throw new HttpException('上传失败', HttpStatus.BAD_REQUEST);
        }
        existsSync(linkPath) && unlinkSync(linkPath)
        return { url }
    }

无非是上传path和buffer的区别但是不知道为啥删除磁盘的文件有问题路径是有的 但是一直报错找不到目录 不知道是为啥 希望大佬解答

formdata
async generatePresignedPostPolicy(filename: string) {
        const policy = new PostPolicy();
        policy.setBucket(this.MINIO_BUCKETNAME);
        policy.setContentType('multipart/form-data');
        policy.setKey(filename);
        policy.setContentLengthRange(1, 5 * 1024 * 1024 * 1024); // 5G
        return this.client.presignedPostPolicy(policy);
    }

可以添加这段代码去实现多个参数的情况

总结

之前nestjs因为顾虑太多然后一直没有正式的学 不过现在快学完了 还有连表查询和过滤器统一响应处理基本就没了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值