diff --git a/src/main/java/com/web/SearchWeb/bookmark/controller/BookmarkApiController.java b/src/main/java/com/web/SearchWeb/bookmark/controller/BookmarkApiController.java index ea30430..094374e 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/controller/BookmarkApiController.java +++ b/src/main/java/com/web/SearchWeb/bookmark/controller/BookmarkApiController.java @@ -83,7 +83,7 @@ public ResponseEntity checkBookmark(@PathVariable final int websiteId){ **/ @GetMapping("/{memberId}/bookmarks") public List selectBookmarkList(@PathVariable final int memberId){ - return bookmarkService.selectBookmarkList(memberId, "Oldest"); //JSON 형태로 객체 리스트 반환 + return bookmarkService.selectBookmarkList(memberId, null, "Oldest", null, null); //JSON 형태로 객체 리스트 반환 } diff --git a/src/main/java/com/web/SearchWeb/bookmark/dao/BookmarkDao.java b/src/main/java/com/web/SearchWeb/bookmark/dao/BookmarkDao.java index c073a1c..435d7cd 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/dao/BookmarkDao.java +++ b/src/main/java/com/web/SearchWeb/bookmark/dao/BookmarkDao.java @@ -5,9 +5,9 @@ import com.web.SearchWeb.bookmark.dto.BookmarkCheckDto; import com.web.SearchWeb.bookmark.dto.BookmarkDto; import com.web.SearchWeb.bookmark.domain.BookmarkWebsite; +import com.web.SearchWeb.bookmark.dto.request.BookmarkSearchRequestDto; import java.util.List; -import java.util.Map; public interface BookmarkDao { //북마크 확인 @@ -16,12 +16,8 @@ public interface BookmarkDao { int checkBoardBookmark(BoardBookmarkCheckDto checkDto); //북마크 단일 조회 Bookmark selectBookmark(int memberId, int bookmarkId); - //북마크 목록 조회 (시간) - List selectBookmarkList(int memberId, String sort); - //북마크 목록 조회 (시간, 태그) - List selectBookmarkListByTag(Map params); - //북마크 목록 조회 (검색어) - List selectBookmarkListByQuery(int memberId, String tag, String sort, String query); + //북마크 목록 조회 + List selectBookmarkList(BookmarkSearchRequestDto searchRequest); //북마크 추가 int insertBookmark(BookmarkDto bookmark); //북마크 추가 (사용자 직접 추가) @@ -39,7 +35,7 @@ public interface BookmarkDao { //북마크-웹사이트 조회 List selectBookmarkWebsite(int memberId); //사용자 태그 목록 조회 - List selectTags(int memberId); + List selectTags(int memberId, Long folderId); //게시글 북마크 여부 확인 int isBookmarked(int boardId, int memberId); } diff --git a/src/main/java/com/web/SearchWeb/bookmark/dao/MybatisBookmarkDao.java b/src/main/java/com/web/SearchWeb/bookmark/dao/MybatisBookmarkDao.java index 12e9b4f..6247e63 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/dao/MybatisBookmarkDao.java +++ b/src/main/java/com/web/SearchWeb/bookmark/dao/MybatisBookmarkDao.java @@ -5,12 +5,12 @@ import com.web.SearchWeb.bookmark.dto.BookmarkCheckDto; import com.web.SearchWeb.bookmark.dto.BookmarkDto; import com.web.SearchWeb.bookmark.domain.BookmarkWebsite; +import com.web.SearchWeb.bookmark.dto.request.BookmarkSearchRequestDto; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Map; @Repository public class MybatisBookmarkDao implements BookmarkDao { @@ -25,29 +25,11 @@ public MybatisBookmarkDao(SqlSession sqlSession) { /** - * 북마크 목록 조회 (시간) + * 북마크 목록 조회 */ @Override - public List selectBookmarkList(int memberId, String sort) { - return mapper.selectBookmarkList(memberId, sort); - } - - - /** - * //북마크 목록 조회 (시간, 태그) - */ - @Override - public List selectBookmarkListByTag(Map params) { - return mapper.selectBookmarkListByTag(params); - } - - - /** - * 북마크 목록 조회 (검색어) - */ - @Override - public List selectBookmarkListByQuery(int memberId, String tag, String sort, String query) { - return mapper.selectBookmarkListByQuery(memberId, tag, sort, query); + public List selectBookmarkList(BookmarkSearchRequestDto searchRequest) { + return mapper.selectBookmarkList(searchRequest); } @@ -153,8 +135,8 @@ public List selectBookmarkWebsite(int memberId) { * 사용자 태그 목록 조회 */ @Override - public List selectTags(int memberId) { - return mapper.selectTags(memberId); + public List selectTags(int memberId, Long folderId) { + return mapper.selectTags(memberId, folderId); } diff --git a/src/main/java/com/web/SearchWeb/bookmark/domain/Bookmark.java b/src/main/java/com/web/SearchWeb/bookmark/domain/Bookmark.java index 48a6b90..7414e93 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/domain/Bookmark.java +++ b/src/main/java/com/web/SearchWeb/bookmark/domain/Bookmark.java @@ -13,6 +13,7 @@ public class Bookmark { private int member_memberId; private int website_websiteId; private int board_boardId; + private int folder_folderId; private String name; private String description; private String url; diff --git a/src/main/java/com/web/SearchWeb/bookmark/dto/BookmarkDto.java b/src/main/java/com/web/SearchWeb/bookmark/dto/BookmarkDto.java index c57f3f1..4cc7404 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/dto/BookmarkDto.java +++ b/src/main/java/com/web/SearchWeb/bookmark/dto/BookmarkDto.java @@ -13,6 +13,7 @@ public class BookmarkDto { private int member_memberId; private int website_websiteId; private int board_boardId; + private Long folder_folderId; private String name; private String description; private String url; diff --git a/src/main/java/com/web/SearchWeb/bookmark/dto/request/BookmarkSearchRequestDto.java b/src/main/java/com/web/SearchWeb/bookmark/dto/request/BookmarkSearchRequestDto.java new file mode 100644 index 0000000..6c3ab77 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/bookmark/dto/request/BookmarkSearchRequestDto.java @@ -0,0 +1,18 @@ +package com.web.SearchWeb.bookmark.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class BookmarkSearchRequestDto { + private int memberId; + private String tag; + private String sort; + private String query; + private Long folderId; +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkService.java b/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkService.java index bb4ad11..c7a98d3 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkService.java +++ b/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkService.java @@ -17,12 +17,8 @@ public interface BookmarkService { int checkBoardBookmark(BoardBookmarkCheckDto checkDto); //북마크 단일 조회 Bookmark selectBookmark(int memberId, int bookmarkId); - //북마크 목록 조회 (시간) - List selectBookmarkList(int memberId, String sort); - //북마크 목록 조회 (시간, 태그) - List selectBookmarkListByTag(int memberId, String tag, String sort); - //북마크 목록 조회 (검색어) - List selectBookmarkListByQuery(int memberId, String tag, String sort, String query); + //북마크 목록 조회 + List selectBookmarkList(int memberId, String tag, String sort, String query, Long folderId); //북마크 추가 (메인리스트에서 추가) int insertBookmark(BookmarkDto bookmark); //북마크 추가 (마이페이지에서 추가) @@ -40,7 +36,7 @@ public interface BookmarkService { //북마크-웹사이트 조회 List selectBookmarkWebsite(int memberId); //사용자 태그 목록 조회 - List selectTags(int memberId); + List selectTags(int memberId, Long folderId); //게시글 북마크 여부 확인 int isBookmarked(int boardId, int memberId); } diff --git a/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkServiceImpl.java b/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkServiceImpl.java index d2b59cc..cb5f360 100644 --- a/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkServiceImpl.java +++ b/src/main/java/com/web/SearchWeb/bookmark/service/BookmarkServiceImpl.java @@ -6,13 +6,11 @@ import com.web.SearchWeb.bookmark.dto.BookmarkCheckDto; import com.web.SearchWeb.bookmark.dto.BookmarkDto; import com.web.SearchWeb.bookmark.domain.BookmarkWebsite; +import com.web.SearchWeb.bookmark.dto.request.BookmarkSearchRequestDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; - -import java.util.HashMap; import java.util.List; -import java.util.Map; @Service public class BookmarkServiceImpl implements BookmarkService { @@ -52,33 +50,18 @@ public Bookmark selectBookmark(int memberId, int bookmarkId) { /** - * 북마크 목록 조회 (시간) - */ - @Override - public List selectBookmarkList(int memberId, String sort) { - return bookmarkDao.selectBookmarkList(memberId, sort); - } - - - /** - * 북마크 목록 조회 (시간, 태그) - */ - @Override - public List selectBookmarkListByTag(int memberId, String tag, String sort) { - Map params = new HashMap<>(); - params.put("member_memberId", memberId); - params.put("tag", tag); - params.put("sort", sort); - return bookmarkDao.selectBookmarkListByTag(params); - } - - - /** - * 북마크 목록 조회 (검색어) + * 북마크 목록 조회 */ @Override - public List selectBookmarkListByQuery(int memberId, String tag, String sort, String query) { - return bookmarkDao.selectBookmarkListByQuery(memberId, tag, sort, query); + public List selectBookmarkList(int memberId, String tag, String sort, String query, Long folderId) { + BookmarkSearchRequestDto searchRequest = BookmarkSearchRequestDto.builder() + .memberId(memberId) + .tag(tag) + .sort(sort) + .query(query) + .folderId(folderId) + .build(); + return bookmarkDao.selectBookmarkList(searchRequest); } @@ -159,8 +142,8 @@ public List selectBookmarkWebsite(int memberId) { * 사용자 태그 목록 조회 */ @Override - public List selectTags(int memberId) { - return bookmarkDao.selectTags(memberId); + public List selectTags(int memberId, Long folderId) { + return bookmarkDao.selectTags(memberId, folderId); } diff --git a/src/main/java/com/web/SearchWeb/folder/controller/FolderController.java b/src/main/java/com/web/SearchWeb/folder/controller/FolderController.java new file mode 100644 index 0000000..d0220cb --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/controller/FolderController.java @@ -0,0 +1,117 @@ +package com.web.SearchWeb.folder.controller; + +import com.web.SearchWeb.aop.OwnerCheck; +import com.web.SearchWeb.folder.dto.request.FolderCreateRequestDto; +import com.web.SearchWeb.folder.dto.request.FolderUpdateRequestDto; +import com.web.SearchWeb.folder.dto.response.FolderResponseDto; +import com.web.SearchWeb.folder.service.FolderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 코드 작성자: + * - 서진영(jin2304) + * + * 코드 설명: + * - 사용자의 폴더 관리 API (CRUD + 태그 조회). + * - 모든 요청은 OwnerCheck AOP를 통해 권한을 검증. + * + * 코드 주요 기능: + * - 폴더 생성 + * - 폴더 단일 조회 + * - 폴더 목록 조회 + * - 폴더 수정 + * - 폴더 삭제 + * - 폴더 태그 목록 조회 + * + * 코드 작성일: + * - 2025.12.31 ~ 2026.01.02 + */ +@Controller +public class FolderController { + + private final FolderService folderService; + + @Autowired + public FolderController(FolderService folderService) { + this.folderService = folderService; + } + + + /** + * 폴더 생성 + */ + @PostMapping("/myPage/{memberId}/folder") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity insertFolder(@PathVariable final int memberId, + @RequestBody FolderCreateRequestDto folderCreateRequestDto) { + FolderResponseDto folder = folderService.insertFolder(memberId, folderCreateRequestDto); + return ResponseEntity.ok(folder); + } + + + /** + * 폴더 단일 조회 + */ + @GetMapping("/myPage/{memberId}/folder/{folderId}") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity getFolder(@PathVariable final int memberId, + @PathVariable final int folderId) { + FolderResponseDto folder = folderService.selectFolder(memberId, folderId); + return ResponseEntity.ok(folder); + } + + + /** + * 폴더 목록 조회 + */ + @GetMapping("/myPage/{memberId}/folders") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity> getFolders(@PathVariable final int memberId, + @RequestParam(required = false, defaultValue = "All") String tag, + @RequestParam(required = false, defaultValue = "Newest") String sort) { + List folders = folderService.selectFolderList(memberId, tag, sort); + return ResponseEntity.ok(folders); + } + + + /** + * 폴더 수정 + */ + @PutMapping("/myPage/{memberId}/folder/{folderId}") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity updateFolder(@PathVariable final int memberId, + @PathVariable final int folderId, + @RequestBody FolderUpdateRequestDto folderUpdateRequestDto) { + int result = folderService.updateFolder(memberId, folderId, folderUpdateRequestDto); + return ResponseEntity.ok(result); + } + + + /** + * 폴더 삭제 + */ + @DeleteMapping("/myPage/{memberId}/folder/{folderId}") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity deleteFolder(@PathVariable final int memberId, + @PathVariable final int folderId) { + int result = folderService.deleteFolder(memberId, folderId); + return ResponseEntity.ok(result); + } + + + /** + * 폴더 태그 목록 조회 + */ + @GetMapping("/myPage/{memberId}/folderTags") + @OwnerCheck(idParam = "memberId", service = "memberService") + public ResponseEntity> getFolderTags(@PathVariable final int memberId) { + List tags = folderService.selectFolderTags(memberId); + return ResponseEntity.ok(tags); + } +} diff --git a/src/main/java/com/web/SearchWeb/folder/dao/FolderDao.java b/src/main/java/com/web/SearchWeb/folder/dao/FolderDao.java new file mode 100644 index 0000000..f0856dd --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dao/FolderDao.java @@ -0,0 +1,21 @@ +package com.web.SearchWeb.folder.dao; + +import com.web.SearchWeb.folder.domain.Folder; +import com.web.SearchWeb.folder.dto.request.FolderSearchRequestDto; + +import java.util.List; + +public interface FolderDao { + // 폴더 생성 + int insertFolder(Folder folder); + // 폴더 단일 조회 + Folder selectFolder(int memberId, int folderId); + // 폴더 목록 조회 + List selectFolderList(FolderSearchRequestDto searchRequest); + // 폴더 수정 + int updateFolder(Folder folder); + // 폴더 삭제 + int deleteFolder(int memberId, int folderId); + // 폴더 태그 목록 조회 + List selectFolderTags(int memberId); +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/folder/dao/MybatisFolderDao.java b/src/main/java/com/web/SearchWeb/folder/dao/MybatisFolderDao.java new file mode 100644 index 0000000..63b109f --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dao/MybatisFolderDao.java @@ -0,0 +1,57 @@ +package com.web.SearchWeb.folder.dao; + +import com.web.SearchWeb.folder.domain.Folder; +import com.web.SearchWeb.folder.dto.request.FolderSearchRequestDto; +import org.apache.ibatis.session.SqlSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class MybatisFolderDao implements FolderDao { + + private final FolderDao mapper; + + @Autowired + public MybatisFolderDao(SqlSession sqlSession) { + mapper = sqlSession.getMapper(FolderDao.class); + } + + + @Override + public int insertFolder(Folder folder) { + return mapper.insertFolder(folder); + } + + + @Override + public Folder selectFolder(int memberId, int folderId) { + return mapper.selectFolder(memberId, folderId); + } + + + @Override + public List selectFolderList(FolderSearchRequestDto searchRequest) { + return mapper.selectFolderList(searchRequest); + } + + + @Override + public int updateFolder(Folder folder) { + return mapper.updateFolder(folder); + } + + + @Override + public int deleteFolder(int memberId, int folderId) { + return mapper.deleteFolder(memberId, folderId); + } + + + @Override + public List selectFolderTags(int memberId) { + return mapper.selectFolderTags(memberId); + } +} + diff --git a/src/main/java/com/web/SearchWeb/folder/domain/Folder.java b/src/main/java/com/web/SearchWeb/folder/domain/Folder.java new file mode 100644 index 0000000..15ec109 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/domain/Folder.java @@ -0,0 +1,23 @@ +package com.web.SearchWeb.folder.domain; + +import java.time.LocalDateTime; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@ToString +public class Folder { + private int folderId; + private int member_memberId; + private String name; + private String tag; + private LocalDateTime created_date; + private LocalDateTime modified_date; +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/folder/dto/request/FolderCreateRequestDto.java b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderCreateRequestDto.java new file mode 100644 index 0000000..69d594b --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderCreateRequestDto.java @@ -0,0 +1,17 @@ +package com.web.SearchWeb.folder.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class FolderCreateRequestDto { + private String name; + private String tag; +} diff --git a/src/main/java/com/web/SearchWeb/folder/dto/request/FolderSearchRequestDto.java b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderSearchRequestDto.java new file mode 100644 index 0000000..30b6575 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderSearchRequestDto.java @@ -0,0 +1,16 @@ +package com.web.SearchWeb.folder.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FolderSearchRequestDto { + private int memberId; + private String tag; + private String sort; +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/folder/dto/request/FolderUpdateRequestDto.java b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderUpdateRequestDto.java new file mode 100644 index 0000000..8e67567 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dto/request/FolderUpdateRequestDto.java @@ -0,0 +1,17 @@ +package com.web.SearchWeb.folder.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class FolderUpdateRequestDto { + private String name; + private String tag; +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/folder/dto/response/FolderResponseDto.java b/src/main/java/com/web/SearchWeb/folder/dto/response/FolderResponseDto.java new file mode 100644 index 0000000..ae3e9b5 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/dto/response/FolderResponseDto.java @@ -0,0 +1,53 @@ +package com.web.SearchWeb.folder.dto.response; + +import com.web.SearchWeb.folder.domain.Folder; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FolderResponseDto { + private int folderId; + private String name; + private String tag; + private LocalDateTime created_date; + private LocalDateTime modified_date; + + /** + * Folder Entity -> FolderResponseDto 변환 메서드 + */ + public static FolderResponseDto from(Folder folder) { + if (folder == null) { + return null; + } + return FolderResponseDto.builder() + .folderId(folder.getFolderId()) + .name(folder.getName()) + .tag(folder.getTag()) + .created_date(folder.getCreated_date()) + .modified_date(folder.getModified_date()) + .build(); + } + + /** + * Folder Entity List -> FolderResponseDto List 변환 메서드 + */ + public static List fromList(List folders) { + if (folders == null) { + return null; + } + return folders.stream() + .map(FolderResponseDto::from) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/web/SearchWeb/folder/service/FolderService.java b/src/main/java/com/web/SearchWeb/folder/service/FolderService.java new file mode 100644 index 0000000..6731961 --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/service/FolderService.java @@ -0,0 +1,22 @@ +package com.web.SearchWeb.folder.service; + +import com.web.SearchWeb.folder.dto.request.FolderCreateRequestDto; +import com.web.SearchWeb.folder.dto.response.FolderResponseDto; +import com.web.SearchWeb.folder.dto.request.FolderUpdateRequestDto; + +import java.util.List; + +public interface FolderService { + // 폴더 생성 + FolderResponseDto insertFolder(int memberId, FolderCreateRequestDto folderCreateRequestDto); + // 폴더 단일 조회 + FolderResponseDto selectFolder(int memberId, int folderId); + // 폴더 목록 조회 + List selectFolderList(int memberId, String tag, String sort); + // 폴더 수정 + int updateFolder(int memberId, int folderId, FolderUpdateRequestDto folderUpdateRequestDto); + // 폴더 삭제 + int deleteFolder(int memberId, int folderId); + // 폴더 태그 목록 조회 + List selectFolderTags(int memberId); +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/folder/service/FolderServiceImpl.java b/src/main/java/com/web/SearchWeb/folder/service/FolderServiceImpl.java new file mode 100644 index 0000000..232ce4e --- /dev/null +++ b/src/main/java/com/web/SearchWeb/folder/service/FolderServiceImpl.java @@ -0,0 +1,77 @@ +package com.web.SearchWeb.folder.service; + +import com.web.SearchWeb.folder.dao.FolderDao; +import com.web.SearchWeb.folder.domain.Folder; +import com.web.SearchWeb.folder.dto.request.FolderCreateRequestDto; +import com.web.SearchWeb.folder.dto.request.FolderSearchRequestDto; +import com.web.SearchWeb.folder.dto.response.FolderResponseDto; +import com.web.SearchWeb.folder.dto.request.FolderUpdateRequestDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +@Service +public class FolderServiceImpl implements FolderService { + + private final FolderDao folderDao; + + @Autowired + public FolderServiceImpl(FolderDao folderDao) { + this.folderDao = folderDao; + } + + @Override + public FolderResponseDto insertFolder(int memberId, FolderCreateRequestDto folderCreateRequestDto) { + LocalDateTime now = LocalDateTime.now(); + Folder folder = Folder.builder() + .member_memberId(memberId) + .name(folderCreateRequestDto.getName()) + .tag(folderCreateRequestDto.getTag()) + .created_date(now) + .modified_date(now) + .build(); + folderDao.insertFolder(folder); + // useGeneratedKeys로 생성된 folderId가 folder 객체에 자동 설정됨 + return FolderResponseDto.from(folder); + } + + @Override + public FolderResponseDto selectFolder(int memberId, int folderId) { + Folder folder = folderDao.selectFolder(memberId, folderId); + return FolderResponseDto.from(folder); + } + + @Override + public List selectFolderList(int memberId, String tag, String sort) { + FolderSearchRequestDto searchRequest = FolderSearchRequestDto.builder() + .memberId(memberId) + .tag(tag) + .sort(sort) + .build(); + List folders = folderDao.selectFolderList(searchRequest); + return FolderResponseDto.fromList(folders); + } + + @Override + public int updateFolder(int memberId, int folderId, FolderUpdateRequestDto folderUpdateRequestDto) { + Folder folder = Folder.builder() + .folderId(folderId) + .member_memberId(memberId) + .name(folderUpdateRequestDto.getName()) + .tag(folderUpdateRequestDto.getTag()) + .build(); + return folderDao.updateFolder(folder); + } + + @Override + public int deleteFolder(int memberId, int folderId) { + return folderDao.deleteFolder(memberId, folderId); + } + + @Override + public List selectFolderTags(int memberId) { + return folderDao.selectFolderTags(memberId); + } +} \ No newline at end of file diff --git a/src/main/java/com/web/SearchWeb/mypage/controller/MyPageController.java b/src/main/java/com/web/SearchWeb/mypage/controller/MyPageController.java index e8e77fd..7e02f39 100644 --- a/src/main/java/com/web/SearchWeb/mypage/controller/MyPageController.java +++ b/src/main/java/com/web/SearchWeb/mypage/controller/MyPageController.java @@ -87,31 +87,21 @@ public ResponseEntity insertBookmark(@PathVariable final int member public ResponseEntity> getBookmarks(@PathVariable final int memberId, @RequestParam(required = false) String query, @RequestParam(defaultValue = "All") String tag, + @RequestParam(required = false) Long folderId, @RequestParam(defaultValue = "Oldest") String sort) { - List bookmarks; - if ((query == null || query.isEmpty()) && ("All".equals(tag) || tag == null)) { - // 1. 전체 북마크 조회 (태그x, 검색어x) - bookmarks = bookmarkService.selectBookmarkList(memberId, sort); - } else if (query != null && !query.isEmpty()) { //검색어가 있는 경우 - // 2. 검색어로 북마크 조회 (태그x, 검색어o), - // 3. 검색어와 특정 태그로 북마크 조회 (태그o, 검색어o) - bookmarks = bookmarkService.selectBookmarkListByQuery(memberId, tag, sort, query); - } else { - // 4. 특정 태그로 북마크 조회 (태그o, 검색어x) - bookmarks = bookmarkService.selectBookmarkListByTag(memberId, tag, sort); - } - + List bookmarks = bookmarkService.selectBookmarkList(memberId, tag, sort, query, folderId); return ResponseEntity.ok(bookmarks); } /** - * 태그 조회 + * 마이페이지 북마크 태그 조회 */ @GetMapping("/myPage/{memberId}/tags") @OwnerCheck(idParam = "memberId", service = "memberService") - public ResponseEntity> getTags(@PathVariable final int memberId) { - List tags = bookmarkService.selectTags(memberId); + public ResponseEntity> getTags(@PathVariable final int memberId, + @RequestParam(required = false) Long folderId) { + List tags = bookmarkService.selectTags(memberId, folderId); return ResponseEntity.ok(tags); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 20d8468..d62382f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,8 @@ spring.application.name=SearchWeb +# Active profile +spring.profiles.active=${SPRING_PROFILES_ACTIVE} + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # mybatis settings mybatis.mapper-locations=classpath:mapper/*.xml diff --git a/src/main/resources/db/init.sql b/src/main/resources/db/init.sql new file mode 100644 index 0000000..1ac5c83 --- /dev/null +++ b/src/main/resources/db/init.sql @@ -0,0 +1,155 @@ +/* 테이블 초기화 */ +-- member 테이블 생성 +DROP TABLE IF EXISTS `member`; + +CREATE TABLE `member` ( + `memberId` int NOT NULL AUTO_INCREMENT, + `username` varchar(100) NOT NULL, + `password` varchar(255) NOT NULL, + `nickname` varchar(45) DEFAULT NULL, + `job` varchar(45) DEFAULT NULL, + `major` varchar(45) DEFAULT NULL, + `summary` varchar(45) DEFAULT NULL, + `role` varchar(45) DEFAULT 'ROLE_USER', + `email` varchar(100) DEFAULT NULL, + PRIMARY KEY (`memberId`), + KEY `idx_nickname` (`nickname`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- website 테이블 생성 +DROP TABLE IF EXISTS `website`; + +CREATE TABLE `website` ( + `websiteId` int NOT NULL, + `name` varchar(255) DEFAULT NULL, + `k_name` varchar(255) DEFAULT NULL, + `description` text, + `url` varchar(255) DEFAULT NULL, + `category` varchar(255) DEFAULT NULL, + `subcategory` varchar(255) DEFAULT NULL, + `rating` int DEFAULT '0', + PRIMARY KEY (`websiteId`), + KEY `idx_category` (`category`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- board 테이블 생성 +DROP TABLE IF EXISTS `board`; + +CREATE TABLE `board` ( + `boardId` int NOT NULL AUTO_INCREMENT, + `member_memberId` int DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `title` varchar(45) NOT NULL, + `summary` varchar(150) DEFAULT NULL, + `description` text, + `hashtags` varchar(255) DEFAULT NULL, + `likes_count` int DEFAULT '0', + `comments_count` int DEFAULT '0', + `bookmarks_count` int DEFAULT '0', + `views_count` int DEFAULT '0', + `created_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`boardId`), + KEY `memberId_idx` (`member_memberId`), + KEY `idx_created_date` (`created_date` DESC), + CONSTRAINT `memberId` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- likes 테이블 생성 +DROP TABLE IF EXISTS `likes`; + +CREATE TABLE `likes` ( + `likes_Id` int NOT NULL AUTO_INCREMENT, + `board_boardId` int NOT NULL, + `member_memberId` int NOT NULL, + `is_Liked` tinyint(1) DEFAULT '0', + PRIMARY KEY (`likes_Id`), + UNIQUE KEY `unique_board_member` (`board_boardId`,`member_memberId`), + KEY `member_memberId_idx` (`member_memberId`) /*!80000 INVISIBLE */, + KEY `board_boardId` (`board_boardId`), + CONSTRAINT `fk_like_board` FOREIGN KEY (`board_boardId`) REFERENCES `board` (`boardId`) ON DELETE CASCADE, + CONSTRAINT `fk_like_member` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- folder 테이블 생성 +DROP TABLE IF EXISTS `folder`; + +CREATE TABLE `folder` ( + `folderId` int NOT NULL AUTO_INCREMENT, + `member_memberId` int NOT NULL, + `name` varchar(255) NOT NULL, + `tag` varchar(45) DEFAULT NULL, + `created_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `modified_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`folderId`), + KEY `fk_folder_member_idx` (`member_memberId`), + CONSTRAINT `fk_folder_member` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- bookmark 테이블 생성 +DROP TABLE IF EXISTS `bookmark`; + +CREATE TABLE `bookmark` ( + `bookmarkId` int NOT NULL AUTO_INCREMENT, + `member_memberId` int NOT NULL, + `nickname` varchar(45) DEFAULT NULL, + `website_websiteId` int DEFAULT NULL, + `board_boardId` int DEFAULT NULL, + `folder_folderId` int DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `description` text, + `url` varchar(255) DEFAULT NULL, + `modified_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `tag` varchar(45) DEFAULT NULL, + PRIMARY KEY (`bookmarkId`), + KEY `fk_bookmark_member_idx` (`member_memberId`), + KEY `fk_bookmark_website1_idx` (`website_websiteId`), + KEY `fk_bookmark_board_idx` (`board_boardId`), + KEY `fk_bookmark_folder_idx` (`folder_folderId`), + CONSTRAINT `fk_bookmark_board` FOREIGN KEY (`board_boardId`) REFERENCES `board` (`boardId`) ON DELETE CASCADE, + CONSTRAINT `fk_bookmark_member` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE CASCADE, + CONSTRAINT `fk_bookmark_website1` FOREIGN KEY (`website_websiteId`) REFERENCES `website` (`websiteId`), + CONSTRAINT `fk_bookmark_folder` FOREIGN KEY (`folder_folderId`) REFERENCES `folder` (`folderId`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- likebookmark 테이블 생성 +DROP TABLE IF EXISTS `likebookmark`; + +CREATE TABLE `likebookmark` ( + `likebookmarkId` int NOT NULL AUTO_INCREMENT, + `board_boardId` int NOT NULL, + `member_memberId` int NOT NULL, + `is_Liked` tinyint(1) DEFAULT '0', + `is_Bookmarked` tinyint(1) DEFAULT '0', + PRIMARY KEY (`likebookmarkId`), + UNIQUE KEY `unique_board_member` (`board_boardId`,`member_memberId`), + KEY `member_memberId_idx` (`member_memberId`) /*!80000 INVISIBLE */, + KEY `board_boardId` (`board_boardId`), + CONSTRAINT `board_boardId` FOREIGN KEY (`board_boardId`) REFERENCES `board` (`boardId`) ON DELETE CASCADE, + CONSTRAINT `member_memberId` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +-- comment 테이블 생성 +DROP TABLE IF EXISTS `comment`; + +CREATE TABLE `comment` ( + `commentId` int NOT NULL AUTO_INCREMENT, + `board_boardId` int NOT NULL, + `member_memberId` int DEFAULT NULL, + `member_nickname` varchar(45) NOT NULL, + `member_job` varchar(45) DEFAULT NULL, + `member_major` varchar(45) DEFAULT NULL, + `content` text, + `created_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`commentId`), + KEY `board_boardId_idx` (`board_boardId`), + KEY `member_memberId_idx` (`member_memberId`), + CONSTRAINT `fk_comment_board` FOREIGN KEY (`board_boardId`) REFERENCES `board` (`boardId`) ON DELETE CASCADE, + CONSTRAINT `fk_comment_member` FOREIGN KEY (`member_memberId`) REFERENCES `member` (`memberId`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/src/main/resources/mapper/bookmark-mapper.xml b/src/main/resources/mapper/bookmark-mapper.xml index a4047d9..ce69228 100644 --- a/src/main/resources/mapper/bookmark-mapper.xml +++ b/src/main/resources/mapper/bookmark-mapper.xml @@ -34,62 +34,31 @@ - - - - - - - select * from bookmark - WHERE member_memberId=#{member_memberId} - + WHERE member_memberId = #{memberId} + + AND folder_folderId = #{folderId} + + AND tag = #{tag} + + AND LOWER(name) LIKE CONCAT('%', LOWER(#{query}), '%') + ORDER BY - - modified_date ASC - modified_date DESC - - - - - - @@ -98,8 +67,8 @@ insert into - bookmark(member_memberId, website_websiteId, name, description, url) - values(#{member_memberId}, #{website_websiteId}, #{name}, #{description}, #{url}); + bookmark(member_memberId, website_websiteId, name, description, url, folder_folderId) + values(#{member_memberId}, #{website_websiteId}, #{name}, #{description}, #{url}, #{folder_folderId}); @@ -107,8 +76,8 @@ insert into - bookmark(member_memberId, name, description, url, tag) - values(#{member_memberId},#{name}, #{description}, #{url}, #{tag}); + bookmark(member_memberId, name, description, url, tag, folder_folderId) + values(#{member_memberId},#{name}, #{description}, #{url}, #{tag}, #{folder_folderId}); @@ -116,8 +85,8 @@ insert into - bookmark(member_memberId, board_boardId, name, description, url, tag) - values(#{member_memberId},#{board_boardId}, #{name}, #{description}, #{url}, #{tag}); + bookmark(member_memberId, board_boardId, name, description, url, tag, folder_folderId) + values(#{member_memberId},#{board_boardId}, #{name}, #{description}, #{url}, #{tag}, #{folder_folderId}); @@ -128,7 +97,8 @@ name = #{bookmarkDto.name}, description = #{bookmarkDto.description}, url = #{bookmarkDto.url}, - tag = #{bookmarkDto.tag} + tag = #{bookmarkDto.tag}, + folder_folderId = #{bookmarkDto.folder_folderId} WHERE bookmarkId = #{bookmarkId} @@ -171,11 +141,14 @@ - - select DISTINCT tag from bookmark - WHERE member_memberId=#{member_memberId} + WHERE member_memberId=#{memberId} + + AND folder_folderId = #{folderId} + AND tag IS NOT NULL And tag != '' diff --git a/src/main/resources/mapper/folder-mapper.xml b/src/main/resources/mapper/folder-mapper.xml new file mode 100644 index 0000000..3f5ab4a --- /dev/null +++ b/src/main/resources/mapper/folder-mapper.xml @@ -0,0 +1,78 @@ + + + + + + + + INSERT INTO folder(member_memberId, name, tag) + VALUES(#{member_memberId}, #{name}, #{tag}) + + + + + + + + + + + + + + UPDATE folder + SET name = #{name}, + tag = #{tag} + WHERE folderId = #{folderId} + AND member_memberId = #{member_memberId} + + + + + + DELETE FROM folder + WHERE folderId = #{folderId} + AND member_memberId = #{memberId} + + + + + + + +