Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
KimSeongHyeonn committed Sep 27, 2024
2 parents f380706 + a129ff0 commit 4941b86
Show file tree
Hide file tree
Showing 22 changed files with 407 additions and 88 deletions.
35 changes: 35 additions & 0 deletions src/common/file.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
DeleteObjectCommand,
ListObjectsV2Command,
PutObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
Expand Down Expand Up @@ -64,6 +65,35 @@ export class FileService {
}
}

// S3 내 특정 경로의 파일 URL들을 가져오는 함수
async getFileUrls(prefix: string): Promise<string[]> {
const command = new ListObjectsV2Command({
Bucket: this.bucketName,
Prefix: prefix,
});

const response = await this.s3.send(command);

if (response.$metadata.httpStatusCode !== 200) {
throw new BadRequestException('Failed get file metadata');
}

if (!response.Contents) {
return [];
}

return response.Contents.filter((object) => this.isFile(object.Key)).map(
(object) => {
return this.makeUrlByFileDir(object.Key);
},
);
}

// 파일 확장자가 있는 경우에만 true를 반환
isFile(key: string): boolean {
return !!key.split('/').pop().includes('.');
}

imagefilter(file: Express.Multer.File): boolean {
const filetype = file.mimetype.split('/');
return filetype[0] === 'image';
Expand All @@ -75,4 +105,9 @@ export class FileService {
fileDir
);
}

getFileDirFromUrl(url: string): string {
const baseUrl = `https://${this.configService.get('AWS_BUCKET_NAME')}.s3.${this.configService.get('AWS_BUCKET_REGION')}.amazonaws.com/`;
return url.slice(baseUrl.length);
}
}
2 changes: 1 addition & 1 deletion src/community/comment/comment.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class CommentRepository extends Repository<CommentEntity> {
async getCommentByCommentId(commentId: number) {
const comment = await this.findOne({
where: { id: commentId },
relations: ['parentComment', 'user.character', 'commentLikes'],
relations: ['parentComment', 'user.character', 'commentLikes', 'post'],
});

return comment;
Expand Down
4 changes: 2 additions & 2 deletions src/community/comment/comment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class CommentService {
if (myAnonymousNumber) {
anonymousNumber = myAnonymousNumber.anonymousNumber;
} else {
if (post.userId === user.id) {
if (post.isAnonymous && post.userId === user.id) {
anonymousNumber = 0;
} else {
const recentAnonymousNumber = await transactionManager.findOne(
Expand Down Expand Up @@ -142,7 +142,7 @@ export class CommentService {

const createdComment = await transactionManager.findOne(CommentEntity, {
where: { id: newCommentId },
relations: ['parentComment', 'user.character', 'commentLikes'],
relations: ['parentComment', 'user.character', 'commentLikes', 'post'],
});
if (post.userId !== user.id) {
await this.noticeService.emitNotice(
Expand Down
9 changes: 8 additions & 1 deletion src/community/comment/dto/get-comment.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ export class GetCommentResponseDto {
constructor(
commentEntity: CommentEntity,
userId: number,
anonymousNumber: number,
anonymousNumber?: number,
) {
this.id = commentEntity.id;
this.isDeleted = commentEntity.deletedAt ? true : false;
this.createdAt = commentEntity.createdAt;
this.updatedAt = commentEntity.updatedAt;
if (this.isDeleted) {
this.isMyComment = false;
this.isAuthor = false;
this.content = null;
this.user = {
username: null,
Expand All @@ -25,6 +26,9 @@ export class GetCommentResponseDto {
this.myLike = false;
} else {
this.isMyComment = commentEntity.userId === userId;
this.isAuthor =
commentEntity.post.isAnonymous === commentEntity.isAnonymous &&
commentEntity.post.userId === commentEntity.userId;
this.content = commentEntity.content;
this.user = new CommunityUser(
commentEntity.user,
Expand Down Expand Up @@ -52,6 +56,9 @@ export class GetCommentResponseDto {
@ApiProperty({ description: '본인이 작성한 댓글인지 여부' })
isMyComment?: boolean;

@ApiProperty({ description: '게시글 작성자의 댓글인지 여부' })
isAuthor?: boolean;

@ApiProperty({ description: '댓글 내용' })
content?: string;

Expand Down
5 changes: 3 additions & 2 deletions src/community/post/dto/get-post.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Comment extends GetCommentResponseDto {
constructor(
commentEntity: CommentEntity,
userId: number,
anonymousNumber: number,
anonymousNumber?: number,
) {
super(commentEntity, userId, anonymousNumber);
if (!commentEntity.parentCommentId) {
Expand Down Expand Up @@ -85,7 +85,8 @@ export class GetPostResponseDto {
const anonymousNumber = postEntity.commentAnonymousNumbers.filter(
(commentAnonymousNumber) =>
commentAnonymousNumber.userId === comment.userId,
)[0].anonymousNumber;
)[0]?.anonymousNumber;
comment.post = postEntity;
if (!comment.parentCommentId) {
this.comments.push(new Comment(comment, userId, anonymousNumber));
} else {
Expand Down
45 changes: 16 additions & 29 deletions src/home/calendar/calendar.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,8 @@ import {
ApiQuery,
ApiTags,
} from '@nestjs/swagger';
import {
GetDailyCalendarDataResponseDto,
GetMonthlyCalendarDataResponseDto,
} from './dto/get-calendar-data-response-dto';
import {
GetMonthlyCalendarDataRequestDto,
GetYearlyCalendarDataRequestDto,
} from './dto/get-calendar-data-request-dto';
import { GetDailyCalendarDataResponseDto } from './dto/get-calendar-data-response-dto';
import { GetMonthlyCalendarDataRequestDto } from './dto/get-calendar-data-request-dto';
import { CreateCalendarDataRequestDto } from './dto/create-calendar-data-request.dto';
import { CreateCalendarDataResponseDto } from './dto/create-calendar-data-response.dto';
import { UpdateCalendarDataRequestDto } from './dto/update-calendar-data-request.dto';
Expand All @@ -39,6 +33,7 @@ import { Roles } from 'src/decorators/roles.decorator';
import { Role } from 'src/enums/role.enum';
import { GetAcademicScheduleDataRequestDto } from './dto/get-academic-schedule-request.dto';
import { GetAcademicScheduleDataResponseDto } from './dto/get-academic-schedule-response.dto';
import { GetBannerImageUrlResponseDto } from './dto/get-banner-images-response.dto';

@Controller('calendar')
@ApiTags('calendar')
Expand Down Expand Up @@ -89,27 +84,6 @@ export class CalendarController {
);
}

@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(Role.admin)
@Get('yearly')
@ApiBearerAuth('accessToken')
@ApiOperation({
summary: '연도별 행사/일정 전체 조회',
description:
'연도별 행사/일정 전체를 조회합니다. 행사/일정이 존재하는 날짜의 경우에만 가져옵니다.',
})
@ApiQuery({ name: 'year', required: true, description: '연도' })
@ApiOkResponse({
description: '특정 연도별 행사/일정 데이터 반환',
isArray: true,
type: GetMonthlyCalendarDataResponseDto,
})
async getYearlyCalendarData(
@Query() queryDto: GetYearlyCalendarDataRequestDto,
): Promise<GetMonthlyCalendarDataResponseDto[]> {
return await this.calendarService.getYearlyCalendarData(queryDto.year);
}

@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(Role.admin)
@Post()
Expand Down Expand Up @@ -170,4 +144,17 @@ export class CalendarController {
): Promise<DeleteCalendarDataResponseDto> {
return await this.calendarService.deleteCalendarData(calendarId);
}

@Get('banner-image-urls')
@ApiOperation({
summary: '메인 홈 배너 이미지 URL 목록 조회',
description: 'S3에 저장된 메인 홈 배너 이미지 URL 목록을 조회합니다.',
})
@ApiOkResponse({
description: 'URL 목록 반환',
type: [GetBannerImageUrlResponseDto],
})
async getBannerImageUrls(): Promise<GetBannerImageUrlResponseDto[]> {
return await this.calendarService.getBannerImageUrls();
}
}
3 changes: 2 additions & 1 deletion src/home/calendar/calendar.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { CalendarRepository } from './calendar.repository';
import { CalendarEntity } from 'src/entities/calendar.entity';
import { UserRepository } from 'src/user/user.repository';
import { CommonModule } from 'src/common/common.module';

@Module({
imports: [TypeOrmModule.forFeature([CalendarEntity])],
imports: [TypeOrmModule.forFeature([CalendarEntity]), CommonModule],
providers: [CalendarService, CalendarRepository, UserRepository],
controllers: [CalendarController],
})
Expand Down
33 changes: 13 additions & 20 deletions src/home/calendar/calendar.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import {
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CalendarRepository } from './calendar.repository';
import {
GetDailyCalendarDataResponseDto,
GetMonthlyCalendarDataResponseDto,
} from './dto/get-calendar-data-response-dto';
import { GetDailyCalendarDataResponseDto } from './dto/get-calendar-data-response-dto';
import { CreateCalendarDataRequestDto } from './dto/create-calendar-data-request.dto';
import { CreateCalendarDataResponseDto } from './dto/create-calendar-data-response.dto';
import { UpdateCalendarDataRequestDto } from './dto/update-calendar-data-request.dto';
import { UpdateCalendarDataResponseDto } from './dto/update-calendar-data-response.dto';
import { DeleteCalendarDataResponseDto } from './dto/delete-calendar-data-response-dto';
import { GetAcademicScheduleDataResponseDto } from './dto/get-academic-schedule-response.dto';
import { GetBannerImageUrlResponseDto } from './dto/get-banner-images-response.dto';
import { FileService } from 'src/common/file.service';

@Injectable()
export class CalendarService {
constructor(
@InjectRepository(CalendarRepository)
private readonly calendarRepository: CalendarRepository,
private readonly fileService: FileService,
) {}

async getMonthlyCalendarData(
Expand Down Expand Up @@ -57,22 +57,6 @@ export class CalendarService {
return monthCalendarData;
}

async getYearlyCalendarData(year: number) {
const allCalendarData: GetMonthlyCalendarDataResponseDto[] = [];
for (let month = 1; month <= 12; month++) {
const monthCalendarData = await this.getMonthlyCalendarData(year, month);
const filteredData = monthCalendarData.filter(
(dayCalendarData) =>
dayCalendarData.date.getMonth() === month - 1 &&
dayCalendarData.eventCount !== 0,
);
allCalendarData.push(
new GetMonthlyCalendarDataResponseDto(month, filteredData),
);
}
return allCalendarData;
}

async getAcademicScheduleData(
year: number,
semester: number,
Expand Down Expand Up @@ -163,6 +147,15 @@ export class CalendarService {
return new DeleteCalendarDataResponseDto(true);
}

async getBannerImageUrls(): Promise<GetBannerImageUrlResponseDto[]> {
const prefix = 'fe/home/homeBanners/';
const imageUrls = await this.fileService.getFileUrls(prefix);

return imageUrls.map((imageUrl) => {
return new GetBannerImageUrlResponseDto(imageUrl);
});
}

// 연도, 월 정보를 받아 캘린더의 시작 - 끝 날짜를 반환하는 함수
private getStartAndEndDate(
year: number,
Expand Down
4 changes: 4 additions & 0 deletions src/home/calendar/dto/get-academic-schedule-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ enum DayOfWeek {
}

class AcademicSchedule {
@ApiProperty({ description: '행사/일정 id' })
id: number;

@ApiProperty({ description: '행사/일정 제목' })
title: string;

Expand All @@ -31,6 +34,7 @@ class AcademicSchedule {
endDay: string;

constructor(calendar: CalendarEntity) {
this.id = calendar.id;
this.title = calendar.title;
this.description = calendar.description;
this.startDate = calendar.startDate;
Expand Down
10 changes: 10 additions & 0 deletions src/home/calendar/dto/get-banner-images-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';

export class GetBannerImageUrlResponseDto {
@ApiProperty({ description: 'S3에 저장된 배너 이미지 url' })
imageUrl: string;

constructor(imageUrl: string) {
this.imageUrl = imageUrl;
}
}
9 changes: 0 additions & 9 deletions src/home/calendar/dto/get-calendar-data-request-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,3 @@ export class GetMonthlyCalendarDataRequestDto {
@ApiProperty({ description: '조회할 월' })
month: number;
}

export class GetYearlyCalendarDataRequestDto {
@IsInt()
@IsNotEmpty()
@Max(2030)
@Min(2024)
@ApiProperty({ description: '조회할 연도' })
year: number;
}
16 changes: 0 additions & 16 deletions src/home/calendar/dto/get-calendar-data-response-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,3 @@ export class GetDailyCalendarDataResponseDto {
this.eventCount = this.event.length;
}
}

export class GetMonthlyCalendarDataResponseDto {
@ApiProperty({ description: '월' })
month: number;

@ApiProperty({
description: '월별 행사/일정',
type: [GetDailyCalendarDataResponseDto],
})
monthEvents: GetDailyCalendarDataResponseDto[];

constructor(month: number, monthEvents: GetDailyCalendarDataResponseDto[]) {
this.month = month;
this.monthEvents = monthEvents;
}
}
Loading

0 comments on commit 4941b86

Please sign in to comment.