<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.type = 'file';
input.click();
input.addEventListener('change', (ev) => {
if (input.files) {
const files = input.files;
for (const file of Array.from(files)) {
const formData = new FormData();
formData.append('file', file);
this.http
.post('https://서버 호스트/api/upload.php', formData)
.subscribe({
next: (data: any) => {
this.Form.controls['document'].setValue(
'https://서버 호스트/api/upload.php' + data.url
);
},
error: (error) => {}, 에러 처리
});
}
}
});
}
- 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', {
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();
}
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}`;
}
}
- backend