Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class Archive extends BaseEntity {
private ArchiveType archiveType;

//아카이브 삭제(아마도 계정 탈퇴) 시 폴더 일괄 삭제
@OneToMany(mappedBy = "archive", cascade = CascadeType.REMOVE, orphanRemoval = true)
@OneToMany(mappedBy = "archive", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Folder> folders = new ArrayList<>();

public Archive(ArchiveType archiveType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.tuna.zoopzoop.backend.domain.archive.archive.entity.PersonalArchive;

import java.util.Optional;
Expand All @@ -14,10 +15,10 @@ public interface PersonalArchiveRepository extends JpaRepository<PersonalArchive
* @return PersonalArchive 엔티티
*/
@Query("""
select pa
from PersonalArchive pa
join fetch pa.archive a
where pa.member.id = :memberId
""")
Optional<PersonalArchive> findByMemberId(Integer memberId);
select pa
from PersonalArchive pa
join fetch pa.archive a
where pa.member.id = :memberId
""")
Optional<PersonalArchive> findByMemberId(@Param("memberId") Integer memberId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tuna.zoopzoop.backend.domain.archive.folder.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -14,13 +16,13 @@
import org.tuna.zoopzoop.backend.global.rsData.RsData;
import org.tuna.zoopzoop.backend.global.security.jwt.CustomUserDetails;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/archive/folder")
@RequiredArgsConstructor
@Tag(name = "ApiV1Folder", description = "개인 아카이브의 폴더 CRUD")
public class FolderController {

private final FolderService folderService;
Expand All @@ -30,6 +32,7 @@ public class FolderController {
* @param rq reqBodyForCreateFolder
* @return resBodyForCreateFolder
*/
@Operation(summary = "폴더 생성", description = "내 PersonalArchive 안에 새 폴더를 생성합니다.")
@PostMapping
public RsData<resBodyForCreateFolder> createFolder(
@Valid @RequestBody reqBodyForCreateFolder rq,
Expand All @@ -55,14 +58,21 @@ public ResponseEntity<Map<String, Object>> deleteFolder(
@PathVariable Integer folderId,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
if (folderId == 0) {
var body = new java.util.HashMap<String, Object>();
body.put("status", 400);
body.put("msg", "default 폴더는 삭제할 수 없습니다.");
body.put("data", null); // HashMap은 null 허용
return ResponseEntity.badRequest().body(body);
}

Member member = userDetails.getMember();
String deletedFolderName = folderService.deleteFolder(member.getId(), folderId);

Map<String, Object> body = new HashMap<>();
var body = new java.util.HashMap<String, Object>();
body.put("status", 200);
body.put("msg", deletedFolderName + " 폴더가 삭제됐습니다.");
body.put("data", null);

body.put("data", null); // <- 여기도 Map.of 쓰면 NPE 납니다
return ResponseEntity.ok(body);
}

Expand All @@ -77,22 +87,30 @@ public ResponseEntity<Map<String, Object>> updateFolderName(
@RequestBody Map<String, String> body,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
if (folderId == 0) {
var res = new java.util.HashMap<String, Object>();
res.put("status", 400);
res.put("msg", "default 폴더는 이름을 변경할 수 없습니다.");
res.put("data", null);
return ResponseEntity.badRequest().body(res);
}

Member member = userDetails.getMember();
String newName = body.get("folderName");
String updatedName = folderService.updateFolderName(member.getId(), folderId, newName);

Map<String, Object> response = new HashMap<>();
response.put("status", 200);
response.put("msg", "폴더 이름이 " + updatedName + " 으로 변경됐습니다.");
response.put("data", Map.of("folderName", updatedName));

return ResponseEntity.ok(response);
return ResponseEntity.ok(java.util.Map.of(
"status", 200,
"msg", "폴더 이름이 " + updatedName + " 으로 변경됐습니다.",
"data", java.util.Map.of("folderName", updatedName)
));
}

/**
* 개인 아카이브의 폴더 이름 전부 조회
* "default", "폴더1", "폴더2"
*/
@Operation(summary = "폴더 이름 조회", description = "내 PersonalArchive 안에 이름을 전부 조회합니다.")
@GetMapping
public ResponseEntity<?> getFolders(
@AuthenticationPrincipal CustomUserDetails userDetails
Expand All @@ -110,29 +128,32 @@ public ResponseEntity<?> getFolders(
}

/**
* 폴더(내 PersonalArchive 소속) 안의 파일 목록 조회
* 폴더 안의 파일 목록 조회
*/
@GetMapping("/{folderId}/files")
public ResponseEntity<?> getFilesInFolder(
@PathVariable Integer folderId,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
Member member = userDetails.getMember();
FolderFilesDto rs = folderService.getFilesInFolderForPersonal(member.getId(), folderId);

return ResponseEntity.ok(
Map.of(
"status", 200,
"msg", "해당 폴더의 파일 목록을 불러왔습니다.",
"data", Map.of(
"folder", Map.of(
"folderId", rs.folderId(),
"folderName", rs.folderName()
),
"files", rs.files()
)
int memberId = userDetails.getMember().getId();

Integer targetFolderId = (folderId == 0)
? folderService.getDefaultFolderId(memberId)
: folderId;

FolderFilesDto rs = folderService.getFilesInFolderForPersonal(memberId, targetFolderId);

return ResponseEntity.ok(Map.of(
"status", 200,
"msg", folderId == 0 ? "기본 폴더의 파일 목록을 불러왔습니다." : "해당 폴더의 파일 목록을 불러왔습니다.",
"data", Map.of(
"folder", Map.of(
"folderId", rs.folderId(),
"folderName", rs.folderName()
),
"files", rs.files()
)
);
));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ public interface FolderRepository extends JpaRepository<Folder, Integer>{
* @param filenameEnd "파일명 + \ufffff"
*/
@Query("""
select f.name
from Folder f
where f.archive.id = :archiveId
and f.name >= :filename
and f.name < :filenameEnd
""")
List<String> findNamesForConflictCheck(Integer archiveId, String filename, String filenameEnd);
select f.name
from Folder f
where f.archive.id = :archiveId
and f.name >= :filename
and f.name < :filenameEnd
""")
List<String> findNamesForConflictCheck(@Param("archiveId") Integer archiveId,
@Param("filename") String filename,
@Param("filenameEnd") String filenameEnd);
// 개인 아카이브의 폴더 조회
List<Folder> findByArchive(Archive archive);

Expand All @@ -38,24 +40,24 @@ public interface FolderRepository extends JpaRepository<Folder, Integer>{
* @param memberId 조회할 회원 Id
*/
@Query("""
select f
from Folder f
join f.archive a
join PersonalArchive pa on pa.archive = a
where pa.member.id = :memberId
and f.isDefault = true
""")
Optional<Folder> findDefaultFolderByMemberId(Integer memberId);
select f
from Folder f
join f.archive a
join PersonalArchive pa on pa.archive = a
where pa.member.id = :memberId
and f.isDefault = true
""")
Optional<Folder> findDefaultFolderByMemberId(@Param("memberId") Integer memberId);

// 한 번의 조인으로 존재 + 소유권(memberId) 검증
@Query("""
select f
from Folder f
join f.archive a
join PersonalArchive pa on pa.archive = a
where f.id = :folderId
and pa.member.id = :memberId
""")
select f
from Folder f
join f.archive a
join PersonalArchive pa on pa.archive = a
where f.id = :folderId
and pa.member.id = :memberId
""")
Optional<Folder> findByIdAndMemberId(@Param("folderId") Integer folderId,
@Param("memberId") Integer memberId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public FolderResponse createFolderForPersonal(Integer currentMemberId, String fo
throw new IllegalArgumentException("폴더 이름은 비어 있을 수 없습니다.");

Member member = memberRepository.findById(currentMemberId)
.orElseThrow(() -> new IllegalArgumentException("멤버를 찾을 수 없습니다."));
.orElseThrow(() -> new NoResultException("멤버를 찾을 수 없습니다."));

Archive archive = personalArchiveRepository.findByMemberId(member.getId())
.map(PersonalArchive::getArchive)
.orElseThrow(() -> new IllegalStateException("개인 아카이브가 없습니다."));
.orElseThrow(() -> new NoResultException("개인 아카이브가 없습니다."));

final String requested = folderName.trim();

Expand Down Expand Up @@ -192,6 +192,14 @@ public FolderFilesDto getFilesInFolderForPersonal(Integer memberId, Integer fold
return new FolderFilesDto(folder.getId(), folder.getName(), files);
}


public Integer getDefaultFolderId(int memberId) {
Folder folder = folderRepository.findDefaultFolderByMemberId(memberId)
.orElseThrow(() -> new NoResultException("default 폴더를 찾을 수 없습니다."));
return folder.getId();

}

/**
* 입력된 폴더명을 (폴더명, 숫자)로 분리하는 유틸 클래스
* “폴더명” → (”폴더명”, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class DevController {

@GetMapping("/token")
public Map<String, String> issueToken(
@RequestParam Provider provider,
@RequestParam String key
@RequestParam(name = "provider") Provider provider,
@RequestParam(name = "key") String key
) {
Member m = memberRepository.findByProviderAndProviderKey(provider, key)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "member not found"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.NoResultException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tuna.zoopzoop.backend.domain.dashboard.dto.BodyForReactFlow;
Expand All @@ -16,11 +14,7 @@
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
import org.tuna.zoopzoop.backend.domain.space.membership.service.MembershipService;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.nio.file.AccessDeniedException;
import java.security.MessageDigest;
import java.util.List;

@Service
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tuna.zoopzoop.backend.domain.datasource.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -21,6 +23,7 @@
@RestController
@RequestMapping("/api/v1/archive")
@RequiredArgsConstructor
@Tag(name = "ApiV1DataSource", description = "개인 아카이브의 파일 CRUD")
public class DatasourceController {

private final DataSourceService dataSourceService;
Expand All @@ -30,6 +33,7 @@ public class DatasourceController {
* sourceUrl 등록할 자료 url
* folderId 등록될 폴더 위치(null 이면 default)
*/
@Operation(summary = "자료 등록", description = "내 PersonalArchive 안에 자료를 등록합니다.")
@PostMapping("")
public ResponseEntity<?> createDataSource(
@Valid @RequestBody reqBodyForCreateDataSource rq,
Expand All @@ -49,6 +53,7 @@ public ResponseEntity<?> createDataSource(
/**
* 자료 단건 삭제
*/
@Operation(summary = "자료 단건 삭제", description = "내 PersonalArchive 안에 자료를 단건 삭제합니다.")
@DeleteMapping("/{dataSourceId}")
public ResponseEntity<Map<String, Object>> delete(
@PathVariable Integer dataSourceId,
Expand All @@ -68,6 +73,7 @@ public ResponseEntity<Map<String, Object>> delete(
/**
* 자료 다건 삭제
*/
@Operation(summary = "자료 다건 삭제", description = "내 PersonalArchive 안에 자료를 다건 삭제합니다.")
@PostMapping("/delete")
public ResponseEntity<Map<String, Object>> deleteMany(
@Valid @RequestBody reqBodyForDeleteMany body,
Expand All @@ -88,6 +94,7 @@ public ResponseEntity<Map<String, Object>> deleteMany(
* 자료 단건 이동
* folderId=null 이면 default 폴더
*/
@Operation(summary = "자료 단건 이동", description = "내 PersonalArchive 안에 자료를 단건 이동합니다.")
@PatchMapping("/{dataSourceId}/move")
public ResponseEntity<?> moveDataSource(
@PathVariable Integer dataSourceId,
Expand Down Expand Up @@ -118,6 +125,7 @@ public ResponseEntity<?> moveDataSource(
/**
* 자료 다건 이동
*/
@Operation(summary = "자료 다건 이동", description = "내 PersonalArchive 안에 자료들를 다건 이동합니다..")
@PatchMapping("/move")
public ResponseEntity<?> moveMany(
@Valid @RequestBody reqBodyForMoveMany rq,
Expand All @@ -141,6 +149,7 @@ public ResponseEntity<?> moveMany(
* @param dataSourceId 수정할 파일 Id
* @param body 수정할 내용
*/
@Operation(summary = "자료 수정", description = "내 PersonalArchive 안에 자료를 수정합니다.")
@PatchMapping("/{dataSourceId}")
public ResponseEntity<?> updateDataSource(
@PathVariable Integer dataSourceId,
Expand All @@ -162,6 +171,10 @@ public ResponseEntity<?> updateDataSource(
);
}

/**
* 자료 검색
*/
@Operation(summary = "자료 검색", description = "내 PersonalArchive 안에 자료들을 검색합니다.")
@GetMapping("")
public ResponseEntity<?> search(
@RequestParam(required = false) String title,
Expand Down
Loading