Skip to content

Commit

Permalink
[DEV-18] 자료실 API (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
5uhwann authored Jul 25, 2024
1 parent 0f7f598 commit 70ff3a8
Show file tree
Hide file tree
Showing 25 changed files with 865 additions and 8 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ dependencies {
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}

tasks.named('test') {
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/ddingdong/ddingdongBE/common/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ public abstract class BaseEntity {
@Column(columnDefinition = "TIMESTAMP")
private LocalDateTime updatedAt;

public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}

public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthService authSer
.antMatchers(GET,
API_PREFIX + "/clubs/**",
API_PREFIX + "/notices/**",
API_PREFIX + "/banners/**")
API_PREFIX + "/banners/**",
API_PREFIX + "/documents/**")
.permitAll()
.antMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**").permitAll()
.anyRequest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public enum ErrorMessage {
UNREGISTER_ID("등록되지 않은 ID입니다."),
NO_SUCH_BANNER("해당 배너가 존재하지 않습니다."),
NON_VALIDATED_TOKEN("유효하지 않은 토큰입니다."),
NO_SUCH_FIX("해당 수리 신청서가 존재하지 않습니다.");
NO_SUCH_FIX("해당 수리 신청서가 존재하지 않습니다."),
NO_SUCH_DOCUMENT("해당 자료가 존재하지 않습니다.");

private final String text;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package ddingdong.ddingdongBE.domain.documents.api;


import ddingdong.ddingdongBE.domain.documents.controller.dto.request.GenerateDocumentRequest;
import ddingdong.ddingdongBE.domain.documents.controller.dto.request.ModifyDocumentRequest;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.AdminDetailDocumentResponse;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.AdminDocumentResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "Document - Admin", description = "Document Admin API")
@RequestMapping("/server/admin/documents")
public interface AdminDocumentApi {

@Operation(summary = "어드민 자료실 업로드 API")
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.CREATED)
@SecurityRequirement(name = "AccessToken")
void generateDocument(@ModelAttribute GenerateDocumentRequest generateDocumentRequest,
@RequestPart(name = "uploadFiles") List<MultipartFile> uploadFiles);

@Operation(summary = "어드민 자료실 목록 조회 API")
@GetMapping
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
List<AdminDocumentResponse> getAllDocuments();

@Operation(summary = "어드민 자료실 상세 조회 API")
@GetMapping("/{documentId}")
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
AdminDetailDocumentResponse getDetailDocument(@PathVariable Long documentId);

@Operation(summary = "어드민 자료실 수정 API")
@PatchMapping(value = "/{documentId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
@SecurityRequirement(name = "AccessToken")
void modifyDocument(@PathVariable Long documentId,
@ModelAttribute ModifyDocumentRequest modifyDocumentRequest,
@RequestPart(name = "uploadFiles", required = false) List<MultipartFile> uploadFiles);

@Operation(summary = "어드민 자료실 삭제 API")
@DeleteMapping("/{documentId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
@SecurityRequirement(name = "AccessToken")
void deleteDocument(@PathVariable Long documentId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ddingdong.ddingdongBE.domain.documents.api;


import ddingdong.ddingdongBE.domain.documents.controller.dto.response.DetailDocumentResponse;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.DocumentResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;

@Tag(name = "Document", description = "Document API")
@RequestMapping("/server/documents")
public interface DocumentApi {

@Operation(summary = "자료실 목록 조회 API")
@GetMapping
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
List<DocumentResponse> getAllDocuments();

@Operation(summary = "자료실 상세 조회 API")
@GetMapping("/{documentId}")
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
DetailDocumentResponse getDetailDocument(@PathVariable Long documentId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package ddingdong.ddingdongBE.domain.documents.controller;

import static ddingdong.ddingdongBE.domain.fileinformation.entity.FileDomainCategory.DOCUMENT;
import static ddingdong.ddingdongBE.domain.fileinformation.entity.FileTypeCategory.FILE;

import ddingdong.ddingdongBE.domain.documents.api.AdminDocumentApi;
import ddingdong.ddingdongBE.domain.documents.controller.dto.request.GenerateDocumentRequest;
import ddingdong.ddingdongBE.domain.documents.controller.dto.request.ModifyDocumentRequest;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.AdminDetailDocumentResponse;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.AdminDocumentResponse;
import ddingdong.ddingdongBE.domain.documents.entity.Document;
import ddingdong.ddingdongBE.domain.documents.service.DocumentService;
import ddingdong.ddingdongBE.domain.fileinformation.service.FileInformationService;
import ddingdong.ddingdongBE.file.dto.FileResponse;
import ddingdong.ddingdongBE.file.service.FileService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
public class AdminDocumentController implements AdminDocumentApi {

private final DocumentService documentService;
private final FileService fileService;
private final FileInformationService fileInformationService;

public void generateDocument(@ModelAttribute GenerateDocumentRequest generateDocumentRequest,
@RequestPart(name = "uploadFiles") List<MultipartFile> uploadFiles) {
Long createdDocumentId = documentService.create(generateDocumentRequest.toEntity());
fileService.uploadDownloadableFile(createdDocumentId, uploadFiles, FILE, DOCUMENT);
}

public List<AdminDocumentResponse> getAllDocuments() {
return documentService.getAll().stream()
.map(AdminDocumentResponse::from)
.toList();
}

public AdminDetailDocumentResponse getDetailDocument(@PathVariable Long documentId) {
Document document = documentService.getById(documentId);
List<FileResponse> fileResponse = fileInformationService.getFileUrls(
FILE.getFileType() + DOCUMENT.getFileDomain() + document.getId());
return AdminDetailDocumentResponse.of(document, fileResponse);
}

public void modifyDocument(@PathVariable Long documentId,
@ModelAttribute ModifyDocumentRequest modifyDocumentRequest,
@RequestPart(name = "uploadFiles", required = false) List<MultipartFile> uploadFiles) {
Long updateDocumentId = documentService.update(documentId, modifyDocumentRequest.toEntity());
fileService.deleteFile(updateDocumentId, FILE, DOCUMENT);
fileService.uploadDownloadableFile(updateDocumentId, uploadFiles, FILE, DOCUMENT);
}

public void deleteDocument(@PathVariable Long documentId) {
fileService.deleteFile(documentId, FILE, DOCUMENT);
documentService.delete(documentId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ddingdong.ddingdongBE.domain.documents.controller;

import static ddingdong.ddingdongBE.domain.fileinformation.entity.FileDomainCategory.DOCUMENT;
import static ddingdong.ddingdongBE.domain.fileinformation.entity.FileTypeCategory.FILE;

import ddingdong.ddingdongBE.domain.documents.api.DocumentApi;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.DetailDocumentResponse;
import ddingdong.ddingdongBE.domain.documents.controller.dto.response.DocumentResponse;
import ddingdong.ddingdongBE.domain.documents.entity.Document;
import ddingdong.ddingdongBE.domain.documents.service.DocumentService;
import ddingdong.ddingdongBE.domain.fileinformation.service.FileInformationService;
import ddingdong.ddingdongBE.file.dto.FileResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class DocumentController implements DocumentApi {

private final DocumentService documentService;
private final FileInformationService fileInformationService;

public List<DocumentResponse> getAllDocuments() {
return documentService.getAll().stream()
.map(DocumentResponse::from)
.toList();
}

public DetailDocumentResponse getDetailDocument(@PathVariable Long documentId) {
Document document = documentService.getById(documentId);
List<FileResponse> fileResponse = fileInformationService.getFileUrls(
FILE.getFileType() + DOCUMENT.getFileDomain() + document.getId());
return DetailDocumentResponse.of(document, fileResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ddingdong.ddingdongBE.domain.documents.controller.dto.request;

import ddingdong.ddingdongBE.domain.documents.entity.Document;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Schema(
name = "GenerateDocumentRequest",
description = "자료실 자료 생성 요청"
)
@Builder
public record GenerateDocumentRequest(
@Schema(description = "자료 제목", example = "제목")
String title,

@Schema(description = "자료 내용", example = "내용")
String content
) {
public Document toEntity() {
return Document.builder()
.title(title)
.content(content)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ddingdong.ddingdongBE.domain.documents.controller.dto.request;

import ddingdong.ddingdongBE.domain.documents.entity.Document;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Schema(
name = "ModifyDocumentRequest",
description = "자료실 자료 수정 요청"
)
@Builder
public record ModifyDocumentRequest(
@Schema(description = "자료 제목", example = "제목")
String title,

@Schema(description = "자료 내용", example = "내용") String content
) {

public Document toEntity() {
return Document.builder()
.title(title)
.content(content)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ddingdong.ddingdongBE.domain.documents.controller.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import ddingdong.ddingdongBE.domain.documents.entity.Document;
import ddingdong.ddingdongBE.file.dto.FileResponse;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import java.util.List;
import lombok.Builder;

@Schema(
name = "AdminDetailDocumentResponse",
description = "어드민 자료실 자료 상세 조회 응답"
)
@Builder
public record AdminDetailDocumentResponse(
@Schema(description = "자료 제목", example = "자료 제목")
String title,

@Schema(description = "자료 내용", example = "자료 내용")
String content,

@Schema(description = "작성일", example = "2024-01-01")
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate createdAt,

@ArraySchema(schema = @Schema(description = "첨부파일 목록", implementation = FileResponse.class))
List<FileResponse> fileUrls
) {

public static AdminDetailDocumentResponse of(Document document,
List<FileResponse> fileResponses) {
return AdminDetailDocumentResponse.builder()
.title(document.getTitle())
.content(document.getContent())
.createdAt(document.getCreatedAt().toLocalDate())
.fileUrls(fileResponses)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ddingdong.ddingdongBE.domain.documents.controller.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import ddingdong.ddingdongBE.domain.documents.entity.Document;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import lombok.Builder;

@Schema(
name = "AdminDocumentResponse",
description = "어드민 자료실 자료 목록 조회 응답"
)
@Builder
public record AdminDocumentResponse(
@Schema(description = "자료 식별자", example = "1")
Long id,

@Schema(description = "자료 제목", example = "자료 제목")
String title,

@Schema(description = "작성일", example = "2024-01-01")
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate createdAt
) {

public static AdminDocumentResponse from(Document document) {
return AdminDocumentResponse.builder()
.id(document.getId())
.title(document.getTitle())
.createdAt(document.getCreatedAt().toLocalDate())
.build();
}
}
Loading

0 comments on commit 70ff3a8

Please sign in to comment.