Web Development

/ 2评 / 6/ 最后更新:2021-12-24
nestjs 上传文件(本地或七牛云)

上传文件至本地

//file.module.ts
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MulterModule } from '@nestjs/platform-express';
import { FileController } from './file.controller';
import { FileService } from './file.service';
import { diskStorage } from 'multer';
import * as dayjs from 'dayjs';
import { nanoid } from 'nanoid';
import { SequelizeModule } from '@nestjs/sequelize';
import { File } from './file.model';
import * as mkdirp from 'mkdirp';

@Module({
  imports: [
    SequelizeModule.forFeature([File]),
    MulterModule.registerAsync({
      useFactory: async (configService: ConfigService) => ({
        storage: diskStorage({
          destination: (req, file, cb) => {
            const dest = `${configService.get('UPLOAD_DEST')}/${dayjs().format(
              'YYYY-MM-DD',
            )}`;
            mkdirp(dest, function () {
              return cb(null, dest);
            });
          },
          filename: (req, file, cb) => {
            const uniqueSuffix = Date.now() + '-' + nanoid();
            cb(null, uniqueSuffix + '-' + file.originalname);
          },
        }),
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [FileController],
  providers: [FileService],
})
export class FileModule {}
//file.controller.ts
import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileService } from './file.service';

@Controller('file')
export class FileController {
  constructor(private fileService: FileService) {}

  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(@UploadedFile() file: Express.Multer.File) {
    const data = await this.fileService.upload(file);
    return {
      errcode: 0,
      data,
    };
  }
}

上传至七牛云

//file.module.ts
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MulterModule } from '@nestjs/platform-express';
import { FileController } from './file.controller';
import { FileService } from './file.service';
import { SequelizeModule } from '@nestjs/sequelize';
import { File } from './file.model';

@Module({
  imports: [
    SequelizeModule.forFeature([File]),
    MulterModule.registerAsync({
      useFactory: async (configService: ConfigService) => ({
        dest: configService.get('UPLOAD_DEST'),
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [FileController],
  providers: [FileService],
})
export class FileModule {}
//file.service.ts
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { File } from './file.model';
import * as qiniu from 'qiniu';
import { ConfigService } from '@nestjs/config';
import { nanoid } from 'nanoid';
import * as fs from 'fs-extra';
import * as path from 'path';

@Injectable()
export class FileService {
  constructor(
    private configService: ConfigService,

    @InjectModel(File)
    private fileModel: typeof File,
  ) {}

  async upload(file: Express.Multer.File) {
    const url = await this.uploadToQiniu(file);
    const fileInfo = {
      originalname: file.originalname,
      size: file.size,
      mimetype: file.mimetype,
      url: url,
    };
    await this.fileModel.create(fileInfo);
    await fs.remove(file.path);
    return fileInfo;
  }

  async uploadToQiniu(file: Express.Multer.File): Promise<string> {
    const mac = new qiniu.auth.digest.Mac(
      this.configService.get('QINIU_ACCESSKEY_ID'),
      this.configService.get('QINIU_ACCESSKEY_SECRET'),
    );
    const putPolicy = new qiniu.rs.PutPolicy({
      scope: this.configService.get('QINIU_BUCKET'),
    });
    const uploadToken = putPolicy.uploadToken(mac);

    const formUploader = new qiniu.form_up.FormUploader(
      new qiniu.conf.Config({
        zone: qiniu.zone.Zone_z0,
      }),
    );

    const filename =
      Date.now() + '-' + nanoid() + path.extname(file.originalname);

    const qiniuHost = this.configService.get('QINIU_HOST');
    return new Promise((resolve) => {
      formUploader.put(
        uploadToken,
        filename,
        file.buffer,
        new qiniu.form_up.PutExtra(),
        function (respErr, respBody, respInfo) {
          if (respErr) {
            console.error(respErr);
            throw new InternalServerErrorException(respErr.message);
          }
          if (respInfo.statusCode == 200) {
            resolve(new URL(respBody.key, qiniuHost).href);
          } else {
            console.error(respInfo.statusCode, respBody);
            throw new InternalServerErrorException(respInfo);
          }
        },
      );
    });
  }
}
6
  1. amma says:

    import { File } from ‘./file.model’; 请问这个是什么

Leave a Reply

Your email address will not be published. Required fields are marked *