From ae015c8e3f493b4f6d44579de26a1982fe64587c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A3=BC=EC=98=81?= <103026521+jyk1029@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:50:29 +0900 Subject: [PATCH] merge :: extra api (#26) * add :: buy emoji api * modify :: create emoji api * add :: upload Emoji Image api * add :: query my emojis api * chore :: resolve bug * modify :: refactoring --- .../emoji/controller/emoji.controller.ts | 18 +++- src/application/domain/emoji/dto/emoji.dto.ts | 4 + .../domain/emoji/service/emoji.service.ts | 85 ++++++++++++++++++- .../emoji/persistence/buy-emoji.entity.ts | 17 ++++ .../global/module/emoji.module.ts | 6 +- 5 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 src/infrastructure/domain/emoji/persistence/buy-emoji.entity.ts diff --git a/src/application/domain/emoji/controller/emoji.controller.ts b/src/application/domain/emoji/controller/emoji.controller.ts index 7f9e43f..0557629 100644 --- a/src/application/domain/emoji/controller/emoji.controller.ts +++ b/src/application/domain/emoji/controller/emoji.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Post, Query, UseFilters, UseGuards } from "@nestjs/common"; +import { Body, Controller, Get, Param, Post, Query, UploadedFile, UseFilters, UseGuards } from "@nestjs/common"; import { GlobalExceptionFilter } from "../../../../infrastructure/global/filter/global.exception.filter"; import { EmojiService } from "../service/emoji.service"; import { CurrentUser } from "../../../../infrastructure/global/decorator/current-user"; @@ -29,4 +29,20 @@ export class EmojiController { async queryEmojiFilter(@Query('min') min: number, @Query('max') max: number) { return await this.emojiService.queryEmojiFilter(min, max) } + + @UseGuards(AuthGuard()) + @Post('buy/:id') + async buyEmoji(@CurrentUser() user: UserEntity, @Param() id) { + await this.emojiService.buyEmoji(user, id) + } + + @Post('upload/:id') + async uploadEmojiImage(@Param() id, @UploadedFile('file') file: Express.Multer.File) { + return await this.emojiService.uploadEmojiImage(id, file) + } + + @Get('mine') + async queryMyEmoji(@CurrentUser() user: UserEntity) { + return await this.emojiService.queryMyEmoji(user) + } } \ No newline at end of file diff --git a/src/application/domain/emoji/dto/emoji.dto.ts b/src/application/domain/emoji/dto/emoji.dto.ts index 1131cc4..e87cade 100644 --- a/src/application/domain/emoji/dto/emoji.dto.ts +++ b/src/application/domain/emoji/dto/emoji.dto.ts @@ -26,3 +26,7 @@ export class EmojiElement { image: string price: number } + +export class UploadImageUrlResponse { + imageUrl: string +} diff --git a/src/application/domain/emoji/service/emoji.service.ts b/src/application/domain/emoji/service/emoji.service.ts index 0b5e120..891ebba 100644 --- a/src/application/domain/emoji/service/emoji.service.ts +++ b/src/application/domain/emoji/service/emoji.service.ts @@ -1,20 +1,42 @@ -import { Injectable } from "@nestjs/common"; +import { HttpException, Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { EmojiEntity } from "../../../../infrastructure/domain/emoji/persistence/emoji.entity"; import { Between, Repository } from "typeorm"; -import { CreateEmojiRequest, EmojiElement, QueryEmojiResponse } from "../dto/emoji.dto"; +import { CreateEmojiRequest, EmojiElement, QueryEmojiResponse, UploadImageUrlResponse } from "../dto/emoji.dto"; +import { UserEntity } from "../../../../infrastructure/domain/user/persistence/user.entity"; +import { BuyEmojiEntity } from "../../../../infrastructure/domain/emoji/persistence/buy-emoji.entity"; +import { AwsService } from "../../../../infrastructure/global/utils/s3/aws.service"; +import { randomUUID } from "crypto"; @Injectable() export class EmojiService { constructor( @InjectRepository(EmojiEntity) private emojiRepository: Repository, + @InjectRepository(UserEntity) + private userRepository: Repository, + @InjectRepository(BuyEmojiEntity) + private buyEmojiRepository: Repository, + private awsService: AwsService, ) { } async createEmoji(req, request: CreateEmojiRequest) { let { title, content, imageUrl, price } = request - await this.emojiRepository.save({ title: title, content: content, image: imageUrl, price: price, userId: req }) + let buyEmoji = new BuyEmojiEntity() + + let emoji = await this.emojiRepository.save({ + title: title, + content: content, + image: imageUrl, + price: price, + userId: req + }) + + buyEmoji.userId = req + buyEmoji.emojiId = emoji + + await this.buyEmojiRepository.save(buyEmoji) } async queryEmojiFilter(min, max) { @@ -27,6 +49,63 @@ export class EmojiService { return this.queryEmoji(emojis) } + async buyEmoji(req, id) { + let emoji = await this.emojiRepository.findOne({ where: id }) + let buyEmoji = new BuyEmojiEntity(); + + buyEmoji.userId = req + buyEmoji.emojiId = emoji + + await this.validateBuyEmoji(req, emoji) + + req.point -= emoji.price + await this.userRepository.save(req) + await this.buyEmojiRepository.save(buyEmoji) + } + + async uploadEmojiImage(id, file) { + let emoji = await this.emojiRepository.findOne({ where: id }) + let response = new UploadImageUrlResponse() + if (!emoji) { + throw new HttpException('Emoji Not Found', 404) + } + + response.imageUrl = await this.awsService.upload(randomUUID(), file) + + return response + } + + async queryMyEmoji(req) { + let buyEmojis = await this.buyEmojiRepository.findBy({ userId: req }) + let response = new QueryEmojiResponse() + + response.emojis = await Promise.all(buyEmojis.map(async (buyEmoji) => { + let element = new EmojiElement() + let emoji = await buyEmoji.emojiId + console.log(emoji) + + element.id = emoji.id + element.title = emoji.title + element.content = emoji.content + element.image = emoji.image + element.price = emoji.price + + return element + })) + + return response + } + + private async validateBuyEmoji(user, emoji) { + if (!emoji) { + throw new HttpException('Emoji Not Found', 404) + } + + if (user.point < emoji.price) { + throw new HttpException('Point Not Enough', 400) + } + } + private async queryEmoji(emojis) { let response = new QueryEmojiResponse() diff --git a/src/infrastructure/domain/emoji/persistence/buy-emoji.entity.ts b/src/infrastructure/domain/emoji/persistence/buy-emoji.entity.ts new file mode 100644 index 0000000..c9c487d --- /dev/null +++ b/src/infrastructure/domain/emoji/persistence/buy-emoji.entity.ts @@ -0,0 +1,17 @@ +import { Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { UserEntity } from "../../user/persistence/user.entity"; +import { EmojiEntity } from "./emoji.entity"; + +@Entity('tbl_buy_emoji') +export class BuyEmojiEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @ManyToOne(() => EmojiEntity, { lazy: true }) + @JoinColumn({ name: 'emoji_id' }) + emojiId: EmojiEntity; + + @ManyToOne(() => UserEntity, { lazy: true }) + @JoinColumn({ name: 'user_id' }) + userId: UserEntity; +} \ No newline at end of file diff --git a/src/infrastructure/global/module/emoji.module.ts b/src/infrastructure/global/module/emoji.module.ts index 6391e99..a0de301 100644 --- a/src/infrastructure/global/module/emoji.module.ts +++ b/src/infrastructure/global/module/emoji.module.ts @@ -3,14 +3,16 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { EmojiEntity } from "../../domain/emoji/persistence/emoji.entity"; import { EmojiService } from "../../../application/domain/emoji/service/emoji.service"; import { EmojiController } from "../../../application/domain/emoji/controller/emoji.controller"; +import { BuyEmojiEntity } from "../../domain/emoji/persistence/buy-emoji.entity"; +import { AwsService } from "../utils/s3/aws.service"; -const EMOJI_REPOSITORY = TypeOrmModule.forFeature([ EmojiEntity ]); +const EMOJI_REPOSITORY = TypeOrmModule.forFeature([ EmojiEntity, BuyEmojiEntity ]); @Global() @Module({ imports: [ EMOJI_REPOSITORY ], controllers: [ EmojiController ], - providers: [ EmojiService ], + providers: [ EmojiService, AwsService ], exports: [ EMOJI_REPOSITORY ] }) export class EmojiModule {