Angular file Upload

agnusdei·2023년 7월 5일
0
post-custom-banner
<div class="flex w-full" (click)="handleUpload()">
	파일첨부
</div>
Form = new FormGroup({ // 입력 폼
    name: new FormControl<string>('', [Validators.required]),
    tel: new FormControl<string>('', [Validators.required]),
    email: new FormGroup({
      username: new FormControl<string>('', [Validators.required]),
      domain: new FormControl<string>('', [
        Validators.required,
        Validators.pattern(/([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,})/),
      ]),
    }),
    title: new FormControl<string>('', [Validators.required]),
    content: new FormControl<string>('', [Validators.required]),
    links: new FormControl(),
    document: new FormControl(), // 첨부파일
  });






handleUpload() {
    const input = document.createElement('input'); // input 생성
    input.type = 'file'; // 타입 file 설정
    input.click(); // 생성한 input 클릭

    input.addEventListener('change', (ev) => { // 변경 감지 (파일 선택)
      if (input.files) { // 파일은 배열로 들어오기에 files 속성 체크
        const files = input.files; // 변수 할당

        for (const file of Array.from(files)) {
          const formData = new FormData(); // 데이터 통신을 위해 formData 사용
          formData.append('file', file); // 파일 담기

          this.http // API 통신
            .post('https://서버 호스트/api/upload.php', formData)
            .subscribe({
              next: (data: any) => {
                this.Form.controls['document'].setValue( // 입력 From 값 설정
                  'https://서버 호스트/api/upload.php' + data.url
                );
              },
              error: (error) => {}, 에러 처리
            });
        }
      }
    });
  }
  1. frontend
import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { Express } from 'express';
import { diskStorage } from 'multer';
import { join } from 'path';
import dayjs from 'dayjs';
import { VideoUploadService } from './video-upload.service';
import { File } from '@namdorang/interface';

@ApiTags('파일 업로드')
@Controller({ version: '1' })
export class VideoUploadController {
  constructor(private readonly videoUploadService: VideoUploadService) {}

  @Post()
  @UseInterceptors(
    FileInterceptor('file', {
      // 'file'이라는 필드의 파일을 인터셉트함
      dest: join(__dirname, 'temp'), // 파일 저장 디렉토리 설정
      storage: diskStorage({
        destination: join(__dirname, 'temp'), // 파일 저장 경로 설정
        filename: (req, file, cb) => {
          cb(null, `${dayjs().unix()}_${file.originalname}`); // 현재 시간과 파일 원본 이름을 조합하여 파일 이름 생성
        },
      }),
    })
  )
  @ApiOperation({
    summary: '숏폼 업로드',
    description: '비디오 파일을 업로드합니다.',
  })
  upload(@UploadedFile() video: Express.Multer.File): Promise<string> {
    return this.videoUploadService.upload(video);
  }
}
import { BadGatewayException, Injectable, Logger } from '@nestjs/common';
import * as fs from 'fs';
import { join } from 'path';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

@Injectable()
export class VideoUploadService {
  private logger: Logger = new Logger(VideoUploadService.name);

  async upload(file: Express.Multer.File): Promise<string> {
    const check = fs.readFileSync(join(__dirname, 'temp', file.filename)); // 파일을 동기적으로 읽어옴

    if (!check) {
      throw new BadGatewayException();
      // 파일이 존재하지 않으면 BadGatewayException
    }

    const s3Client = new S3Client({
      region: 'KR1', 
      credentials: {
        accessKeyId: process.env.NAVER_CLOUD_KEY,
        secretAccessKey: process.env.NAVER_CLOUD_SECRET,
      },
    });

    const command = new PutObjectCommand({
      Bucket: 'assets',
      Key: file.filename,
      ACL: 'public-read',
      Body: fs.createReadStream(join(__dirname, 'temp', file.filename)),
    });

    const result = await s3Client.send(command);

    fs.rmSync(join(__dirname, 'temp', file.filename)); // 업로드 완료 후 임시 파일 삭제
    return `${process.env.NAVER_CLOUD_BUCKET_ENDPOINT}/${file.filename}`; // 업로드된 파일의 공개 URL 반환
  }
}

  1. backend
post-custom-banner

0개의 댓글