Skip to content

Commit

Permalink
Merge pull request #12 from gutanbug/feat/trade
Browse files Browse the repository at this point in the history
feat: 단국 거래 서비스 단일 조회, 판매 완료 기능 추가
  • Loading branch information
gutanbug authored Dec 25, 2023
2 parents f570379 + da4b203 commit 295d499
Show file tree
Hide file tree
Showing 18 changed files with 435 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

public enum LikeTarget {
POST,
COMMENT
COMMENT,
WITH_DANKOOK
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.dku.council.domain.with_dankook.controller;

import com.dku.council.domain.like.model.LikeTarget;
import com.dku.council.domain.like.service.LikeService;
import com.dku.council.domain.post.model.dto.response.ResponsePage;
import com.dku.council.domain.with_dankook.model.WithDankookStatus;
import com.dku.council.domain.with_dankook.model.dto.list.SummarizedTradeDto;
import com.dku.council.domain.with_dankook.model.dto.request.RequestCreateTradeDto;
import com.dku.council.domain.with_dankook.model.dto.response.ResponseSingleTradeDto;
import com.dku.council.domain.with_dankook.model.entity.type.Trade;
import com.dku.council.domain.with_dankook.service.TradeService;
import com.dku.council.domain.with_dankook.service.WithDankookService;
import com.dku.council.global.auth.jwt.AppAuthentication;
import com.dku.council.global.auth.role.UserAuth;
import com.dku.council.global.model.dto.ResponseIdDto;
Expand All @@ -16,6 +22,7 @@
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

@Tag(name = "단국 거래 게시판", description = "단국 거래 게시판 API")
@RestController
Expand All @@ -24,6 +31,7 @@
public class TradeController {

private final TradeService tradeService;
private final LikeService likeService;

/**
* 단국 거래 게시글 목록 조회
Expand All @@ -41,6 +49,19 @@ public ResponsePage<SummarizedTradeDto> list(@RequestParam(required = false) Str
return new ResponsePage<>(list);
}

/**
* 단국 거래 게시글 상세 조회
*
* @param id 게시글 id
* @return 단국 거래 게시글 상세 정보
*/
@GetMapping("/{id}")
@UserAuth
public ResponseSingleTradeDto findOne(AppAuthentication auth,
@PathVariable Long id) {
return tradeService.findOne(id, auth.getUserId(), auth.getUserRole());
}

/**
* 단국 거래 게시글 등록
*/
Expand All @@ -55,12 +76,61 @@ public ResponseIdDto create(AppAuthentication auth,
/**
* 단국 거래 게시글 삭제
*
* @param auth 사용자 인증정보
* @param id 삭제할 게시글 id
* @param id 게시글 id
*/
@DeleteMapping("/{id}")
@UserAuth
public void delete(AppAuthentication auth, @PathVariable Long id) {
tradeService.delete(id, auth.getUserId(), auth.isAdmin());
}

/**
* 단국 거래 게시글 판매 완료 처리
* 유저가 처리하거나 관리자가 강제로 처리할 수 있습니다.
*
* @param id 게시글 id
*/
@PatchMapping("/{id}")
@UserAuth
public void close(AppAuthentication auth, @PathVariable Long id) {
tradeService.close(id, auth.getUserId());
}

/**
* 단국 거래 게시글 좋아요 표시
* 중복으로 좋아요 처리해도 1개만 적용됩니다.
*
* @param id 게시글 id
*/
@PostMapping("/{id}/like")
@UserAuth
public void like(AppAuthentication auth, @PathVariable Long id) {
likeService.like(id, auth.getUserId(), LikeTarget.WITH_DANKOOK);
}

/**
* 단국 거래 게시글 좋아요 취소
* 중복으로 좋아요 취소해도 최초 1번만 적용됩니다.
*
* @param id 게시글 id
*/
@DeleteMapping("/{id}/like")
@UserAuth
public void cancelLike(AppAuthentication auth, @PathVariable Long id) {
likeService.cancelLike(id, auth.getUserId(), LikeTarget.WITH_DANKOOK);
}

/**
* 내가 작성한 단국 거래 게시글 목록 조회
*
* @param pageable 페이징 size, sort, page
* @return 페이징된 내가 쓴 단국 거래 게시판 목록
*/
@GetMapping("/my")
@UserAuth
public ResponsePage<SummarizedTradeDto> listMyPosts(AppAuthentication auth,
@ParameterObject Pageable pageable) {
Page<SummarizedTradeDto> list = tradeService.listMyPosts(auth.getUserId(), pageable);
return new ResponsePage<>(list);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dku.council.domain.with_dankook.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class ImageSizeExceededException extends LocalizedMessageException {

public ImageSizeExceededException() {
super(HttpStatus.BAD_REQUEST, "invalid.imagesize");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.dku.council.domain.with_dankook.exception;

import com.dku.council.global.error.exception.LocalizedMessageException;
import org.springframework.http.HttpStatus;

public class WithDankookNotFoundException extends LocalizedMessageException {

public WithDankookNotFoundException() {
super(HttpStatus.NOT_FOUND, "notfound.withdankook");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.dku.council.domain.with_dankook.model.entity.TradeImage;
import com.dku.council.infra.nhn.s3.service.ObjectUploadContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import org.springframework.http.MediaType;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Getter
public class TradeImageDto {

@Schema(description = "이미지 아이디", example = "1")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.dku.council.domain.with_dankook.model.dto.list;

import com.dku.council.domain.with_dankook.model.WithDankookStatus;
import com.dku.council.domain.with_dankook.model.dto.TradeImageDto;
import com.dku.council.domain.with_dankook.model.entity.type.Trade;
import com.dku.council.infra.nhn.s3.service.ObjectUploadContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;

import java.util.List;

Expand All @@ -26,12 +29,16 @@ public class SummarizedTradeDto extends SummarizedWithDankookDto{
@Schema(description = "이미지 목록")
private final List<TradeImageDto> images;

public SummarizedTradeDto(SummarizedWithDankookDto dto, Trade trade, ObjectUploadContext context){
@Schema(description = "거래 상태", example = "거래중")
private final String status;

public SummarizedTradeDto(SummarizedWithDankookDto dto, Trade trade, ObjectUploadContext context, MessageSource messageSource){
super(dto);
this.title = trade.getTitle();
this.price = trade.getPrice();
this.content = trade.getContent();
this.tradePlace = trade.getTradePlace();
this.images = TradeImageDto.listOf(context, trade.getImages());
this.status = messageSource.getMessage("withdankook.trade." + trade.getWithDankookStatus().name().toLowerCase(), null, LocaleContextHolder.getLocale());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@ public class SummarizedWithDankookDto {
@Schema(description = "채팅 링크", example = "https://open.kakao.com/o/ghjgjgjg")
private final String chatLink;

@Schema(description = "게시글 타입", example = "TRADE")
private final String type;

public SummarizedWithDankookDto(int bodySize, WithDankook withDankook) {
this.id = withDankook.getId();
this.author = withDankook.getDisplayingUsername();
this.createdAt = withDankook.getCreatedAt();
this.chatLink = withDankook.getChatLink();
this.type = withDankook.getClass().getSimpleName().toUpperCase();
}

public SummarizedWithDankookDto(SummarizedWithDankookDto copy) {
this.id = copy.getId();
this.author = copy.getAuthor();
this.createdAt = copy.getCreatedAt();
this.chatLink = copy.getChatLink();
this.type = copy.getType();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.dku.council.domain.with_dankook.model.dto.response;

import com.dku.council.domain.with_dankook.model.dto.TradeImageDto;
import com.dku.council.domain.with_dankook.model.entity.type.Trade;
import com.dku.council.infra.nhn.s3.service.ObjectUploadContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;

import java.util.List;

@Getter
public class ResponseSingleTradeDto extends ResponseSingleWithDankookDto {

@Schema(description = "제목", example = "물물교환")
private final String title;

@Schema(description = "가격", example = "10000")
private final int price;

@Schema(description = "내용", example = "게시글 본문")
private final String content;

@Schema(description = "거래 장소", example = "단국대학교 정문")
private final String tradePlace;

@Schema(description = "이미지 목록")
private final List<TradeImageDto> images;

@Schema(description = "거래 상태", example = "거래중")
private final String status;

public ResponseSingleTradeDto(ResponseSingleWithDankookDto dto, Trade trade, ObjectUploadContext context, MessageSource messageSource) {
super(dto);
this.title = trade.getTitle();
this.price = trade.getPrice();
this.content = trade.getContent();
this.tradePlace = trade.getTradePlace();
this.images = TradeImageDto.listOf(context, trade.getImages());
this.status = messageSource.getMessage("withdankook.trade." + trade.getWithDankookStatus().name().toLowerCase(), null, LocaleContextHolder.getLocale());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.dku.council.domain.with_dankook.model.dto.response;

import com.dku.council.domain.with_dankook.model.entity.WithDankook;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class ResponseSingleWithDankookDto {

@Schema(description = "게시글 아이디", example = "1")
private final Long id;

@Schema(description = "작성자", example = "익명")
private final String author;

@Schema(description = "생성 날짜")
private final LocalDateTime createdAt;

@Schema(description = "채팅 링크", example = "https://open.kakao.com/o/ghjgjgjg")
private final String chatLink;

@Schema(description = "좋아요 수", example = "26")
private final int likes;

@Schema(description = "내가 쓴 게시물인지?", example = "true")
private final boolean isMine;

@Schema(description = "내가 좋아요를 눌렀는지?", example = "false")
private final boolean isLiked;

@Schema(description = "닫힘 여부", example = "false")
private final boolean isClosed;

public ResponseSingleWithDankookDto(int likes, boolean isMine, boolean isLiked, WithDankook withDankook) {
this.id = withDankook.getId();
this.author = withDankook.getDisplayingUsername();
this.createdAt = withDankook.getCreatedAt();
this.chatLink = withDankook.getChatLink();
this.likes = likes;
this.isMine = isMine;
this.isLiked = isLiked;
this.isClosed = withDankook.isClosed();
}

public ResponseSingleWithDankookDto(ResponseSingleWithDankookDto copy) {
this.id = copy.id;
this.author = copy.author;
this.createdAt = copy.createdAt;
this.chatLink = copy.chatLink;
this.likes = copy.likes;
this.isMine = copy.isMine;
this.isLiked = copy.isLiked;
this.isClosed = copy.isClosed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,12 @@ protected WithDankook(User user, String chatLink) {
public void markAsDeleted(boolean byAdmin) {
this.withDankookStatus = byAdmin ? WithDankookStatus.DELETED_BY_ADMIN : WithDankookStatus.DELETED;
}

public boolean isClosed() {
return withDankookStatus == WithDankookStatus.CLOSED;
}

public void close() {
this.withDankookStatus = WithDankookStatus.CLOSED;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.dku.council.domain.with_dankook.repository;

import com.dku.council.domain.with_dankook.model.dto.list.SummarizedTradeDto;
import com.dku.council.domain.with_dankook.model.entity.WithDankook;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -16,4 +19,14 @@ public interface WithDankookRepository<T extends WithDankook> extends JpaReposit
"join fetch u.major " +
"where w.id=:id and w.withDankookStatus ='ACTIVE' ")
Optional<T> findById(@Param("id") Long id);

@Query("select w from WithDankook w " +
"join fetch w.masterUser u " +
"join fetch u.major " +
"where w.id=:withDankookId and (w.withDankookStatus='CLOSED' or w.withDankookStatus='ACTIVE')")
Optional<T> findWithClosedById(@Param("withDankookId") Long withDankookId);

@Query("select w from WithDankook w " +
"where w.masterUser.id=:userId and (w.withDankookStatus='ACTIVE' or w.withDankookStatus='CLOSED')")
Page<T> findAllByUserId(@Param("userId") Long userId, Pageable pageable);
}
Loading

0 comments on commit 295d499

Please sign in to comment.