diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/build.gradle b/server/build.gradle index a3bc9a2..3a6e75b 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -28,6 +28,10 @@ dependencies { // Swagger implementation 'io.springfox:springfox-boot-starter:3.0.0' + + //validation + implementation 'org.springframework.boot:spring-boot-starter-validation' + } tasks.named('test') { diff --git a/server/src/main/java/com/yogit/server/board/controller/BoardController.java b/server/src/main/java/com/yogit/server/board/controller/BoardController.java new file mode 100644 index 0000000..f6a99cf --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/controller/BoardController.java @@ -0,0 +1,41 @@ +package com.yogit.server.board.controller; + + +import com.yogit.server.board.dto.request.CreateBoardReq; +import com.yogit.server.board.dto.response.BoardRes; +import com.yogit.server.board.service.BoardServiceImpl; +import com.yogit.server.global.dto.ApplicationResponse; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor // private final DI의존주입 +@RequestMapping("/boards") +public class BoardController { + + private final BoardServiceImpl boardServiceImpl; + + /** + * 게시글 등록 + * @author 토마스 + */ + @ApiOperation(value = "게시글 등록", notes = "그룹 게시글에 필요한 정보를 입력받아 게시글 생성.") + @ApiResponses({ + @ApiResponse(code= 1000, message = "요청에 성공하였습니다."), + @ApiResponse(code = 4000 , message = "서버 오류입니다.") + }) + @PostMapping("") + public ApplicationResponse registerBoard(@RequestBody @Validated CreateBoardReq createBoardReq){ + return boardServiceImpl.createBoard(createBoardReq); + } + +} diff --git a/server/src/main/java/com/yogit/server/board/dto/request/CreateBoardReq.java b/server/src/main/java/com/yogit/server/board/dto/request/CreateBoardReq.java new file mode 100644 index 0000000..e316cf0 --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/dto/request/CreateBoardReq.java @@ -0,0 +1,94 @@ +package com.yogit.server.board.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.yogit.server.board.entity.Board; +import com.yogit.server.user.entity.City; +import com.yogit.server.user.entity.User; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiParam; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +public class CreateBoardReq { + + @ApiModelProperty(example = "1") + @ApiParam(value = "도시 ID", required = true) + private Long cityId; + + @ApiModelProperty(example = "1") + @ApiParam(value = "호스트 ID", required = true) + private Long hostId; + + @ApiModelProperty(example = "경복궁 탐사입니다.") + @ApiParam(value = "게시글 제목", required = true) + @Size(min = 1, max=51) + @NotBlank + private String title; + + @ApiModelProperty(example = "서울특별시 종로구 사직로 130") + @ApiParam(value = "모임 주소", required = true) + @NotBlank + private String address; + + @ApiModelProperty(example = "37.1") + @ApiParam(value = "위도", required = true) + private float longitute; + + @ApiModelProperty(example = "37") + @ApiParam(value = "경도", required = true) + private float latitude; + + @ApiModelProperty(example = "2022-07-13 16:29:30") + @ApiParam(value = "사용자 ID", required = true) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") + @NotBlank + private LocalDateTime date; // 모임 시각 + + @ApiModelProperty(example = "시간에 맞춰오시기 바랍니다.") + @ApiParam(value = "모임 공지사항", required = false) + @Size(max = 1000) + private String notice; + + @ApiModelProperty(example = "3시에 모여서 경복궁역에서 경복궁으로 출발합니다.") + @ApiParam(value = "모임 상세설명", required = false) + @Size(max = 1000) + private String introduction; // 게시글 내용 상세설명 + + @ApiModelProperty(example = "활발한 사람이 오면 좋습니다.") + @ApiParam(value = "원하는 사람 설명", required = false) + @Size(max = 1000) + private String kindOfPerson; // 이런 사람을 원합니다 설명 글. + + @ApiModelProperty(example = "5") + @ApiParam(value = "총 인원수", required = true) + private int totalMember; + + //TODO: boardCategory 필드값 + @ApiModelProperty(example = "1") + @ApiParam(value = "그룹 카테고리 ID", required = true) + private Long boardCategoryId; + + + public Board toEntity(CreateBoardReq dto){ + return Board.builder() + .title(dto.getTitle()) + .address(dto.getAddress()) + .longitute(dto.getLongitute()) + .latitude(dto.getLatitude()) + .date(dto.getDate()) + .notice(dto.getNotice()) + .introduction(dto.getIntroduction()) + .kindOfPerson(dto.getKindOfPerson()) + .totalMember(dto.getTotalMember()) + .build(); + } + +} diff --git a/server/src/main/java/com/yogit/server/board/dto/response/BoardRes.java b/server/src/main/java/com/yogit/server/board/dto/response/BoardRes.java new file mode 100644 index 0000000..652fdcf --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/dto/response/BoardRes.java @@ -0,0 +1,104 @@ +package com.yogit.server.board.dto.response; + +import com.yogit.server.board.entity.Board; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiParam; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +public class BoardRes { + + @ApiModelProperty(example = "1") + @ApiParam(value = "도시 ID") + private Long cityId; + + @ApiModelProperty(example = "1") + @ApiParam(value = "호스트 ID") + private Long hostId; + + @ApiModelProperty(example = "경복궁 탐사입니다.") + @ApiParam(value = "게시글 제목") + private String title; + + @ApiModelProperty(example = "서울특별시 종로구 사직로 130") + @ApiParam(value = "모임 주소") + private String address; + + @ApiModelProperty(example = "37.1") + @ApiParam(value = "위도") + private float longitute; + + @ApiModelProperty(example = "37") + @ApiParam(value = "경도") + private float latitude; + + @ApiModelProperty(example = "2022-07-13 16:29:30") + @ApiParam(value = "사용자 ID") + private LocalDateTime date; // 모임 시각 + + @ApiModelProperty(example = "시간에 맞춰오시기 바랍니다.") + @ApiParam(value = "모임 공지사항") + private String notice; + + @ApiModelProperty(example = "3시에 모여서 경복궁역에서 경복궁으로 출발합니다.") + @ApiParam(value = "모임 상세설명") + private String introduction; // 게시글 내용 상세설명 + + @ApiModelProperty(example = "활발한 사람이 오면 좋습니다.") + @ApiParam(value = "원하는 사람 설명") + private String kindOfPerson; // 이런 사람을 원합니다 설명 글. + + @ApiModelProperty(example = "2") + @ApiParam(value = "현재 참여 인원수") + private int currentMember; + + @ApiModelProperty(example = "5") + @ApiParam(value = "총 인원수") + private int totalMember; + + @ApiModelProperty(example = "2") + @ApiParam(value = "모임 카테고리 ID") + private Long boardCategoryId; + + //TODO: boardImages 리스트 필드값 + + + public static BoardRes toDto(Board board){ + return BoardRes.builder() + .cityId(board.getCity().getId()) + .hostId(board.getHost().getId()) + .title(board.getTitle()) + .address(board.getAddress()) + .longitute(board.getLongitute()) + .latitude(board.getLatitude()) + .date(board.getDate()) + .notice(board.getNotice()) + .introduction(board.getIntroduction()) + .kindOfPerson(board.getKindOfPerson()) + .build(); + //.boardCategoryId(board.get) + } + + @Builder + public BoardRes(Long cityId, Long hostId, String title, String address, float longitute, float latitude, LocalDateTime date, String notice, String introduction, String kindOfPerson, int currentMember, int totalMember, Long boardCategoryId) { + this.cityId = cityId; + this.hostId = hostId; + this.title = title; + this.address = address; + this.longitute = longitute; + this.latitude = latitude; + this.date = date; + this.notice = notice; + this.introduction = introduction; + this.kindOfPerson = kindOfPerson; + this.currentMember = currentMember; + this.totalMember = totalMember; + this.boardCategoryId = boardCategoryId; + } +} diff --git a/server/src/main/java/com/yogit/server/board/entity/Board.java b/server/src/main/java/com/yogit/server/board/entity/Board.java index f90ebf6..721ee0e 100644 --- a/server/src/main/java/com/yogit/server/board/entity/Board.java +++ b/server/src/main/java/com/yogit/server/board/entity/Board.java @@ -3,10 +3,12 @@ import com.yogit.server.user.entity.City; import com.yogit.server.user.entity.User; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import javax.persistence.*; +import java.time.LocalDateTime; import java.util.List; @Entity @@ -26,18 +28,70 @@ public class Board { @JoinColumn(name = "user_id") private User host; + private String title; + + private String address; + + private float longitute; + + private float latitude; + + private LocalDateTime date; // 모임 시각 + + private String notice; + + private String introduction; // 게시글 내용 상세설명 + + private String kindOfPerson; // 이런 사람을 원합니다 설명 글. + + private int currentMember; + + private int totalMember; + @OneToMany(mappedBy = "board") private List boardUsers; @OneToMany(mappedBy = "board") private List boardImages; - @OneToMany(mappedBy = "board") - private List boardCategories; + @OneToOne(mappedBy = "board") + private BoardCategory boardCategory; @OneToMany(mappedBy = "board") private List bookMarks; @OneToMany(mappedBy = "board") private List clipBoards; + + + // 생성자 + @Builder + public Board(Long id, City city, User host, String title, String address, float longitute, float latitude, LocalDateTime date, String notice, String introduction, String kindOfPerson, int currentMember, int totalMember, List boardUsers, List boardImages, BoardCategory boardCategory, List bookMarks, List clipBoards) { + this.id = id; + this.city = city; + this.host = host; + this.title = title; + this.address = address; + this.longitute = longitute; + this.latitude = latitude; + this.date = date; + this.notice = notice; + this.introduction = introduction; + this.kindOfPerson = kindOfPerson; + this.currentMember = currentMember; + this.totalMember = totalMember; + this.boardUsers = boardUsers; + this.boardImages = boardImages; + this.boardCategory = boardCategory; + this.bookMarks = bookMarks; + this.clipBoards = clipBoards; + } + + /* + 연관관계 편의 메서드 + */ + + public void changeBoardCurrentMember(int currentMember){ + this.currentMember = currentMember; + } } diff --git a/server/src/main/java/com/yogit/server/board/entity/BoardCategory.java b/server/src/main/java/com/yogit/server/board/entity/BoardCategory.java index 5c9452d..7baecdd 100644 --- a/server/src/main/java/com/yogit/server/board/entity/BoardCategory.java +++ b/server/src/main/java/com/yogit/server/board/entity/BoardCategory.java @@ -16,7 +16,7 @@ public class BoardCategory { @Column(name = "boardCategory_id") private Long id; - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "board_id") private Board board; diff --git a/server/src/main/java/com/yogit/server/board/repository/BoardRepository.java b/server/src/main/java/com/yogit/server/board/repository/BoardRepository.java new file mode 100644 index 0000000..beb863a --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/repository/BoardRepository.java @@ -0,0 +1,7 @@ +package com.yogit.server.board.repository; + +import com.yogit.server.board.entity.Board; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BoardRepository extends JpaRepository { +} diff --git a/server/src/main/java/com/yogit/server/board/service/BoardService.java b/server/src/main/java/com/yogit/server/board/service/BoardService.java new file mode 100644 index 0000000..0e62a9d --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/service/BoardService.java @@ -0,0 +1,10 @@ +package com.yogit.server.board.service; + +import com.yogit.server.board.dto.request.CreateBoardReq; +import com.yogit.server.board.dto.response.BoardRes; +import com.yogit.server.global.dto.ApplicationResponse; + +public interface BoardService { + + ApplicationResponse createBoard(CreateBoardReq createBoardReq); +} diff --git a/server/src/main/java/com/yogit/server/board/service/BoardServiceImpl.java b/server/src/main/java/com/yogit/server/board/service/BoardServiceImpl.java new file mode 100644 index 0000000..316c60a --- /dev/null +++ b/server/src/main/java/com/yogit/server/board/service/BoardServiceImpl.java @@ -0,0 +1,44 @@ +package com.yogit.server.board.service; + +import com.yogit.server.board.dto.request.CreateBoardReq; +import com.yogit.server.board.dto.response.BoardRes; +import com.yogit.server.board.entity.Board; +import com.yogit.server.board.repository.BoardRepository; +import com.yogit.server.global.dto.ApplicationResponse; +import com.yogit.server.user.entity.City; +import com.yogit.server.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class BoardServiceImpl implements BoardService{ + + private final BoardRepository boardRepository; + + @Transactional(readOnly = false) + @Override + public ApplicationResponse createBoard(CreateBoardReq dto){ + + // host 조회 + // city조회 + // boardUsers 조회 + // boardImages 조회 + // boardCategories 조회 + + // board 생성 + Board board = dto.toEntity(dto); + // currentMember 디폴트=0 + board.changeBoardCurrentMember(0); + + // board 생성 요청 + Board savedBoard = boardRepository.save(board); + // resDto 벼환 + BoardRes boardRes = BoardRes.toDto(savedBoard); + // 반환 + return ApplicationResponse.create("created", boardRes); + } + +}