generated from Medici-Mansion/basic-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 편지와 답장 통합 / 우체국에 보관된 편지 메일로 분류
- Loading branch information
1 parent
e51e403
commit b77d7e8
Showing
12 changed files
with
314 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { IsUUID } from 'class-validator'; | ||
|
||
export class SaveMailRequestDTO { | ||
@ApiProperty({ description: '저장할 편지 아이디' }) | ||
@IsUUID('all') | ||
letterId: string; | ||
} | ||
|
||
export class ReadMailRequestDTO { | ||
@ApiProperty({ description: '읽음처리할 메일 아이디' }) | ||
@IsUUID('all') | ||
mailId: string; | ||
} | ||
|
||
export class UpdateMailRequetDTO { | ||
@ApiProperty({ description: '메일 아이디' }) | ||
@IsUUID('all') | ||
mailId: string; | ||
|
||
@ApiProperty({ description: '답장으로 저장할 편지 아이디' }) | ||
@IsUUID('all') | ||
replyLetterId: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { Mail } from '../entities/mail.entity'; | ||
import { IsBoolean, IsDate, IsString, IsUUID } from 'class-validator'; | ||
|
||
export class LetterFromMailResponseDTO { | ||
@ApiProperty() | ||
@IsUUID('all') | ||
id: string; | ||
|
||
@ApiProperty() | ||
@IsDate() | ||
createdAt: Date; | ||
|
||
@ApiProperty() | ||
@IsDate() | ||
updatedAt: Date; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
senderId: string; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
senderNickname: string; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
receiverNickname: string; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
content: string; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
catName: string; | ||
|
||
@ApiProperty() | ||
@IsBoolean() | ||
isRespond: boolean; | ||
|
||
constructor(letter: Mail['letter'] & { replyLetterId: string | null }) { | ||
this.id = letter.id; | ||
this.createdAt = letter.createdAt; | ||
this.updatedAt = letter.updatedAt; | ||
this.senderId = letter.senderId; | ||
this.senderNickname = letter.senderNickname; | ||
this.receiverNickname = letter.receiverNickname; | ||
this.content = letter.content; | ||
this.catName = letter.catName; | ||
this.isRespond = !!letter.replyLetterId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { BaseEntity } from 'src/common/entities/base.entity'; | ||
import { Letter } from 'src/entities/letter.entity'; | ||
import { User } from 'src/entities/user.entity'; | ||
import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; | ||
|
||
@Entity({ name: 'mails' }) | ||
export class Mail extends BaseEntity { | ||
@Column({ | ||
type: 'uuid', | ||
comment: '메일을 보유한 사용자 아이디', | ||
name: 'user_id', | ||
}) | ||
userId: string; | ||
|
||
@ManyToOne(() => User, (user) => user.id, { | ||
createForeignKeyConstraints: false, | ||
}) | ||
@JoinColumn({ name: 'user_id', referencedColumnName: 'id' }) | ||
user: User; | ||
|
||
@Column({ type: 'uuid', comment: '메일의 편지 아이디', name: 'letter_id' }) | ||
letterId: string; | ||
|
||
@ManyToOne(() => Letter, (Letter) => Letter.id, { | ||
createForeignKeyConstraints: false, | ||
}) | ||
@JoinColumn({ name: 'letter_id', referencedColumnName: 'id' }) | ||
letter: Letter; | ||
|
||
@Column({ | ||
type: 'uuid', | ||
comment: '답장하기를 통해 보낸 편지 아이디', | ||
name: 'received_letter_id', | ||
nullable: true, | ||
}) | ||
replyLetterId: string; | ||
|
||
@OneToOne(() => Letter, (Letter) => Letter.id, { | ||
createForeignKeyConstraints: false, | ||
nullable: true, | ||
}) | ||
@JoinColumn({ name: 'received_letter_id', referencedColumnName: 'id' }) | ||
replyLetter: Letter; | ||
|
||
@Column({ | ||
name: 'is_read', | ||
comment: '편지 확인 여부', | ||
default: false, | ||
}) | ||
isRead: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { AccessGuard } from 'src/auth/guards/acess.guard'; | ||
import { MailsService } from './mails.service'; | ||
import { Body, Controller, Get, Post, Put, UseGuards } from '@nestjs/common'; | ||
import { AuthUser } from 'src/auth/decorators/auth-user.decorator'; | ||
import { | ||
ApiBearerAuth, | ||
ApiCreatedResponse, | ||
ApiOkResponse, | ||
ApiOperation, | ||
ApiTags, | ||
} from '@nestjs/swagger'; | ||
import { LetterFromMailResponseDTO } from './dtos/mails.response.dto'; | ||
import { | ||
ReadMailRequestDTO, | ||
SaveMailRequestDTO, | ||
} from './dtos/mails.request.dto'; | ||
|
||
@ApiTags('Mails API') | ||
@Controller('mails') | ||
@ApiBearerAuth() | ||
@UseGuards(AccessGuard) | ||
export class MailsController { | ||
constructor(private readonly mailsService: MailsService) {} | ||
|
||
@Get() | ||
@ApiOkResponse({ | ||
type: [LetterFromMailResponseDTO], | ||
}) | ||
async getMyMails(@AuthUser() { id }) { | ||
return await this.mailsService.getMyMails(id); | ||
} | ||
|
||
@ApiOperation({ | ||
summary: '편지 보관하기', | ||
description: | ||
'편지 보관하기 기능 수행 시 호출. 내가 받은 편지(Mail)에 저장된다', | ||
}) | ||
@Put() | ||
async saveMails( | ||
@AuthUser() { id }, | ||
@Body() saveMailRequestDTO: SaveMailRequestDTO, | ||
) { | ||
return await this.mailsService.saveMails(id, saveMailRequestDTO); | ||
} | ||
|
||
@ApiOperation({ | ||
summary: '메일 읽기', | ||
description: '우체국에 저장된 메일을 읽음처리 한다', | ||
}) | ||
@Post('read') | ||
@ApiCreatedResponse({ | ||
type: Boolean, | ||
}) | ||
async readMails( | ||
@AuthUser() { id }, | ||
@Body() readMailRequestDTO: ReadMailRequestDTO, | ||
) { | ||
return await this.mailsService.readMail(id, readMailRequestDTO); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { MailsController } from './mails.controller'; | ||
import { MailsService } from './mails.service'; | ||
|
||
@Module({ | ||
controllers: [MailsController], | ||
providers: [MailsService], | ||
exports: [MailsService], | ||
}) | ||
export class MailsModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { BadRequestException, Injectable } from '@nestjs/common'; | ||
import { InjectDataSource } from '@nestjs/typeorm'; | ||
import { DataSource } from 'typeorm'; | ||
import { Mail } from './entities/mail.entity'; | ||
import { LetterFromMailResponseDTO } from './dtos/mails.response.dto'; | ||
import { | ||
ReadMailRequestDTO, | ||
SaveMailRequestDTO, | ||
UpdateMailRequetDTO, | ||
} from './dtos/mails.request.dto'; | ||
import { Letter } from 'src/entities/letter.entity'; | ||
|
||
@Injectable() | ||
export class MailsService { | ||
constructor(@InjectDataSource() private readonly dataSource: DataSource) {} | ||
|
||
async getMyMails(userId: string) { | ||
const myMails = await this.dataSource.getRepository(Mail).find({ | ||
where: { | ||
userId, | ||
}, | ||
relations: { | ||
letter: true, | ||
}, | ||
}); | ||
return myMails.map( | ||
(mail) => | ||
new LetterFromMailResponseDTO({ | ||
...mail.letter, | ||
replyLetterId: mail.replyLetterId, | ||
}), | ||
); | ||
} | ||
|
||
async saveMails(id: string, saveMailRequestDTO: SaveMailRequestDTO) { | ||
const repository = this.dataSource.getRepository(Mail); | ||
const newMails = repository.create({ | ||
userId: id, | ||
letterId: saveMailRequestDTO.letterId, | ||
}); | ||
|
||
await repository.save(newMails); | ||
|
||
return newMails; | ||
} | ||
|
||
async readMail(id: string, readMailRequestDTO: ReadMailRequestDTO) { | ||
const repository = this.dataSource.getRepository(Mail); | ||
const currentMail = await repository.findOne({ | ||
where: { | ||
userId: id, | ||
id: readMailRequestDTO.mailId, | ||
}, | ||
}); | ||
|
||
if (!currentMail) { | ||
throw new BadRequestException(); | ||
} | ||
|
||
currentMail.isRead = true; | ||
await repository.save(currentMail); | ||
|
||
return true; | ||
} | ||
|
||
async updateReplyMail(updateMailRequetDTO: UpdateMailRequetDTO) { | ||
const repository = this.dataSource.getRepository(Mail); | ||
const currentMail = await repository.findOne({ | ||
where: { | ||
id: updateMailRequetDTO.mailId, | ||
}, | ||
}); | ||
|
||
const existLetter = await this.dataSource | ||
.createQueryBuilder() | ||
.from(Letter, 'lt') | ||
.where('id = :letterId', { | ||
letterId: updateMailRequetDTO.replyLetterId, | ||
}); | ||
if (existLetter) { | ||
currentMail.replyLetterId = updateMailRequetDTO.replyLetterId; | ||
await repository.save(currentMail); | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |