Skip to content

Commit

Permalink
Merge pull request #29 from LocalMingle/dev
Browse files Browse the repository at this point in the history
[완료] 에릭, 종화 코드 병합 - 설렉터 이모티콘 추가, 삭제된 호스트 이벤트 제외하고 리스팅, 참석/참석취소 로그, 관심있는 이벤트 북마크 추가/삭제 및 리스팅
  • Loading branch information
erickimme authored Oct 18, 2023
2 parents 128acd4 + e8bda2e commit cf2294e
Show file tree
Hide file tree
Showing 23 changed files with 220 additions and 121 deletions.
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"passport-jwt": "^4.0.1",
"passport-kakao": "^1.0.1",
"passport-local": "^1.0.0",
"prisma": "^5.4.2",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.0"
Expand All @@ -71,7 +70,7 @@
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"prisma": "^5.4.1",
"prisma": "^5.4.2",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
Expand Down
61 changes: 47 additions & 14 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ datasource db {

// 사용자 모델
model User {
userId Int @id @default(autoincrement()) // Primary Key
email String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
refreshToken String? @db.Text
UserDetail UserDetail[]
HostEvents HostEvent[]
GuestEvents GuestEvent[]
userId Int @id @default(autoincrement()) // Primary Key
email String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime? // null이면 삭제되지 않은 것으로 간주
refreshToken String? @db.Text
UserDetail UserDetail[]
HostEvents HostEvent[]
GuestEvents GuestEvent[]
EventBookmark EventBookmark[]
@@map("User")
}
Expand All @@ -39,6 +41,7 @@ model UserDetail {
User User @relation(fields: [UserId], references: [userId], onDelete: Cascade)
Viewlogs Viewlog[]
RsvpLogs RsvpLog[]
@@map("UserInfo")
}
Expand All @@ -60,14 +63,30 @@ model Event {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
HostEvents HostEvent[]
GuestEvents GuestEvent[]
Viewlogs Viewlog[]
Category Category[]
HostEvents HostEvent[]
GuestEvents GuestEvent[]
Viewlogs Viewlog[]
Category Category[]
RsvpLog RsvpLog[]
EventBookmark EventBookmark[]
@@map("Event")
}

// 북마크한 이벤트 모델
model EventBookmark {
eventBookmarkId Int @id @default(autoincrement()) // Primary Key
EventId Int
UserId Int
status String // "bookmarked", "unbookmarked"
updatedAt DateTime?
Event Event @relation(fields: [EventId], references: [eventId])
User User @relation(fields: [UserId], references: [userId])
@@map("EventBookmark")
}

// 조회 기록 모델
model Viewlog {
viewlogId Int @id @default(autoincrement()) // Primary Key
Expand All @@ -80,6 +99,20 @@ model Viewlog {
@@map("Viewlog")
}

// 참가 신청/취소 기록 모델
model RsvpLog {
rsvpLogId Int @id @default(autoincrement()) // Primary Key
EventId Int
UserId Int
status String // 'applied', 'canceled' 등의 상태
createdAt DateTime @default(now()) // 참석 신청이나 취소가 이루어진 시간
Event Event @relation(fields: [EventId], references: [eventId])
UserDetail UserDetail @relation(fields: [UserId], references: [userDetailId])
@@map("RsvpLog")
}

// 호스트 이벤트 매핑 모델
model HostEvent {
hostEventId Int @id @default(autoincrement()) // Primary Key
Expand Down
6 changes: 3 additions & 3 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class AuthService {
const refreshToken = this.setRefreshToken({ user, res });

// 5. 액세스 토큰 및 리프레시 토큰을 반환
const accessToken = await this.getAccessToken({ user, res });
const accessToken = this.getAccessToken({ user, res });

// 6. DB에 리프레시 토큰을 저장한다.
await this.prisma.user.update({
Expand All @@ -62,7 +62,7 @@ export class AuthService {
getAccessToken({ user, res }): string {
const accessToken = this.jwtService.sign(
{ sub: user.userId },
{ secret: process.env.JWT_ACCESS_KEY, expiresIn: '3600s' }
{ secret: process.env.JWT_ACCESS_KEY, expiresIn: '36000s' }
);
//console.log('엑세스 토큰 확인용 로그', user);
return accessToken;
Expand Down Expand Up @@ -140,4 +140,4 @@ export class AuthService {

return { accessToken, refreshToken, userId: user.userId };
}
}
}
10 changes: 6 additions & 4 deletions src/aws/aws.s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class AwsS3Service {
});
}

// S3 업로드 로직
// S3 프로필 이미지 업로드 로직
async uploadFile(file) {
if (!file) {
throw new BadRequestException('No file uploaded');
Expand All @@ -36,16 +36,18 @@ export class AwsS3Service {
});
}

// 이벤트 이미지 업로드
// S3 이벤트 이미지 업로드
async uploadEventFile(file) {
console.log("file1", file)
if (!file) {
throw new BadRequestException('No file uploaded');
}

const params = {
Bucket: process.env.AWS_BUCKET_NAME || 'aws-s3-local-mingle', // AWS S3 버킷 이름
Key: `eventImg/${String(Date.now())}`, // 폴더와 파일 이름
Body: file.buffer, // 파일 내용
ContentType: file.mimetype, // 파일 타입
};
console.log(params)

return new Promise((resolve, reject) => {
this.s3.upload(params, (err, data) => {
Expand Down
4 changes: 2 additions & 2 deletions src/data/interface/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export interface Verify {
const verifies: Verify[] = [{ verify: 'yes' }, { verify: 'no' }];

export const toss = {
category: [':커피:️ 맛집/커피', ':주자::피부톤-2: 운동/건강', ':발: 애완동물', ':책: 공부/교육'],
verify: [' :한_손을_들고_있는_사람::피부톤-2: 아무나', ':정원이_있는_집: 동네만'],
category: ['맛집/커피', '🏃‍♂️운동/건강', '🐾애완동물', '📕공부/교육'],
verify: ['🙋‍♀️아무나', '🏡동네만'],
};
63 changes: 44 additions & 19 deletions src/events/events.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
ApiOperation,
ApiTags,
ApiConsumes,
ApiBody
ApiBody,
} from '@nestjs/swagger';
import { EventEntity } from './entities/event.entity';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
Expand All @@ -42,8 +42,8 @@ interface RequestWithUser extends Request {
export class EventsController {
constructor(
private readonly eventsService: EventsService,
private readonly awsS3Service: AwsS3Service,
) {}
private readonly awsS3Service: AwsS3Service
) {}

@Post()
@UseGuards(JwtAuthGuard) // passport를 사용하여 인증 확인
Expand All @@ -60,7 +60,7 @@ export class EventsController {
@UseGuards(JwtAuthGuard) // passport를 사용하여 인증 확인
@ApiBearerAuth() // Swagger 문서에 Bearer 토큰 인증 추가
@ApiOperation({ summary: 'Event 이미지 업로드' })
@ApiConsumes('multipart/form-data')
@ApiConsumes('multipart/form-data')
@UseInterceptors(FileInterceptor('file'))
@ApiBody({
description: 'event image',
Expand All @@ -76,34 +76,32 @@ export class EventsController {
},
},
})
async uploadFile(
@UploadedFile()
file
) {
console.log("file", file)
const img = this.eventsService.uploadFile(file)
console.log(img)
async uploadFile(@UploadedFile() file) {
console.log('file', file);

// const uploadedFile = await this.awsS3Service.uploadEventFile(file) as { Location: string };
// return uploadedFile
const uploadedFile = (await this.awsS3Service.uploadEventFile(file)) as {
Location: string;
};
return {
message: '이미지가 업로드되었습니다',
ImgURL: uploadedFile,
};
}

@Get()
@ApiOperation({ summary: 'Event 전체 조회' })
@ApiOkResponse({ type: EventEntity, isArray: true })
async findAll() {
const events = await this.eventsService.findAll();

console.log(events)
const event = events.map((item) => {
const { GuestEvents, HostEvents, ...rest } = item;
const hostUser = item.HostEvents[0].User.UserDetail;
const guestUser = item.GuestEvents[0]

return {
event: rest,
guestList: item.GuestEvents.length,
hostUser: hostUser,
guestUser: guestUser,
};
});
return event;
Expand All @@ -124,7 +122,9 @@ export class EventsController {
event: rest,
guestList: event.GuestEvents.length,
hostUser: HostEvents[0].User.UserDetail,
guestUser: GuestEvents[0]?.User?.UserDetail
guestUser: GuestEvents.map((item)=>{
return item.User.UserDetail
})
};
}

Expand All @@ -133,18 +133,23 @@ export class EventsController {
@ApiBearerAuth() // Swagger 문서에 Bearer 토큰 인증 추가
@ApiOperation({ summary: 'Guest로서 Event 참가신청' })
@ApiCreatedResponse({ description: `모임 참석 신청 / 취소` })
async join(@Param('eventId', ParseIntPipe) eventId: number, @Req() req: RequestWithUser) {
async join(
@Param('eventId', ParseIntPipe) eventId: number,
@Req() req: RequestWithUser
) {
const event = await this.eventsService.findOne(eventId);
if (!event) throw new NotFoundException(`${eventId}번 이벤트가 없습니다`);

const { userId } = req.user;
const isJoin = await this.eventsService.isJoin(+eventId, userId);
const isJoin = await this.eventsService.isJoin(eventId, userId);
if (!isJoin) {
this.eventsService.join(+eventId, userId);
this.eventsService.createRsvpLog(eventId, userId, 'applied'); // 로그 생성
return `${eventId}번 모임 참석 신청!`;
}
if (isJoin) {
this.eventsService.cancelJoin(isJoin.guestEventId);
this.eventsService.createRsvpLog(eventId, userId, 'canceled'); // 로그 생성
return `${eventId}번 모임 신청 취소!`;
}
}
Expand All @@ -171,4 +176,24 @@ export class EventsController {

return this.eventsService.remove(eventId);
}

// 북마크 추가
@Post(':eventId/bookmark')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOperation({ summary: 'Event 북마크 추가' })
async addBookmark(@Param('eventId', ParseIntPipe) eventId: number, @Req() req: RequestWithUser) {
const { userId } = req.user;
return this.eventsService.addBookmark(eventId, userId, 'bookmarked');
}

// 북마크 제거
@Delete(':eventId/bookmark')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiOperation({ summary: 'Event 북마크 제거' })
async removeBookmark(@Param('eventId', ParseIntPipe) eventId: number, @Req() req: RequestWithUser) {
const { userId } = req.user;
return this.eventsService.removeBookmark(eventId, userId, 'unbookmarked');
}
}
7 changes: 2 additions & 5 deletions src/events/events.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import { Module } from '@nestjs/common';
import { EventsService } from './events.service';
import { EventsController } from './events.controller';
import { PrismaModule } from 'src/prisma/prisma.module';
import { MulterModule } from '@nestjs/platform-express';
import { MulterConfigService } from './multer/multer.config';
import { AwsS3Service } from 'src/aws/aws.s3';
import { AwsModule } from 'src/aws/aws.module';

@Module({
controllers: [EventsController],
providers: [EventsService, AwsS3Service],
imports: [PrismaModule, MulterModule.registerAsync({
useClass: MulterConfigService
})],
imports: [PrismaModule, AwsModule],
})
export class EventsModule {}
Loading

0 comments on commit cf2294e

Please sign in to comment.