-
Couldn't load subscription status.
- Fork 1
Fix 서버 파일/메인이미지 폴더 분리 #374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
6eb66d1
63dd3ca
60b9bfd
65d9581
0bcea87
7a6ce7f
03c5ced
d0a6f28
0170d7c
a44dfc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package com.wafflestudio.csereal.core.resource.attachment.service | ||
|
|
||
| import com.wafflestudio.csereal.common.CserealException | ||
| import com.wafflestudio.csereal.core.resource.directory.Directory | ||
| import com.wafflestudio.csereal.common.entity.AttachmentAttachable | ||
| import com.wafflestudio.csereal.common.properties.EndpointProperties | ||
| import com.wafflestudio.csereal.core.about.database.AboutEntity | ||
|
|
@@ -21,6 +22,7 @@ import org.springframework.data.repository.findByIdOrNull | |
| import org.springframework.stereotype.Service | ||
| import org.springframework.transaction.annotation.Transactional | ||
| import org.springframework.web.multipart.MultipartFile | ||
| import java.lang.invoke.WrongMethodTypeException | ||
| import java.nio.file.Files | ||
| import java.nio.file.Paths | ||
|
|
||
|
|
@@ -53,22 +55,25 @@ class AttachmentServiceImpl( | |
| private val eventPublisher: ApplicationEventPublisher | ||
| ) : AttachmentService { | ||
| override fun uploadAttachmentInLabEntity(labEntity: LabEntity, requestAttachment: MultipartFile): AttachmentDto { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 흠 얘도 추후에 추상화가 되면 좋겠군요.. |
||
| Files.createDirectories(Paths.get(path)) | ||
| val directory = "attachment/" + Directory.LAB.toString().lowercase() | ||
| val uploadDir = Paths.get(path, directory) | ||
| Files.createDirectories(uploadDir) | ||
|
|
||
| val timeMillis = System.currentTimeMillis() | ||
|
|
||
| val filename = "${timeMillis}_${requestAttachment.originalFilename}" | ||
| val totalFilename = path + filename | ||
| val saveFile = Paths.get(totalFilename) | ||
| val saveFile = Paths.get(path, directory, filename) | ||
| requestAttachment.transferTo(saveFile) | ||
|
|
||
| val attachment = AttachmentEntity( | ||
| filename = filename, | ||
| directory = directory, | ||
| attachmentsOrder = 1, | ||
| size = requestAttachment.size | ||
| ) | ||
|
|
||
| labEntity.pdf = attachment | ||
| attachment.lab = labEntity | ||
| attachmentRepository.save(attachment) | ||
|
|
||
| return AttachmentDto( | ||
|
|
@@ -83,20 +88,22 @@ class AttachmentServiceImpl( | |
| contentEntityType: AttachmentAttachable, | ||
| requestAttachments: List<MultipartFile> | ||
| ): List<AttachmentDto> { | ||
| Files.createDirectories(Paths.get(path)) | ||
| val directory = attachmentDirectoryOf(contentEntityType) | ||
| val uploadDir = Paths.get(path, directory) | ||
| Files.createDirectories(uploadDir) | ||
|
|
||
| val attachmentsList = mutableListOf<AttachmentDto>() | ||
|
|
||
| for ((index, requestAttachment) in requestAttachments.withIndex()) { | ||
| val timeMillis = System.currentTimeMillis() | ||
|
|
||
| val filename = "${timeMillis}_${requestAttachment.originalFilename}" | ||
| val totalFilename = path + filename | ||
| val saveFile = Paths.get(totalFilename) | ||
| val saveFile = uploadDir.resolve(filename) | ||
| requestAttachment.transferTo(saveFile) | ||
|
|
||
| val attachment = AttachmentEntity( | ||
| filename = filename, | ||
| directory = directory, | ||
| attachmentsOrder = index + 1, | ||
| size = requestAttachment.size | ||
| ) | ||
|
|
@@ -124,7 +131,7 @@ class AttachmentServiceImpl( | |
| attachmentDto = AttachmentResponse( | ||
| id = attachment.id, | ||
| name = attachment.filename.substringAfter("_"), | ||
| url = "${endpointProperties.backend}/v1/file/${attachment.filename}", | ||
| url = "${endpointProperties.backend}/v1/file/${attachment.filePath()}", | ||
| bytes = attachment.size | ||
| ) | ||
| } | ||
|
|
@@ -142,7 +149,7 @@ class AttachmentServiceImpl( | |
| val attachmentDto = AttachmentResponse( | ||
| id = attachment.id, | ||
| name = attachment.filename.substringAfter("_"), | ||
| url = "${endpointProperties.backend}/v1/file/${attachment.filename}", | ||
| url = "${endpointProperties.backend}/v1/file/${attachment.filePath()}", | ||
| bytes = attachment.size | ||
| ) | ||
| list.add(attachmentDto) | ||
|
|
@@ -170,7 +177,7 @@ class AttachmentServiceImpl( | |
|
|
||
| @Transactional | ||
| override fun deleteAttachment(attachment: AttachmentEntity) { | ||
| val fileDirectory = path + attachment.filename | ||
| val fileDirectory = path + attachment.filePath() | ||
| attachmentRepository.delete(attachment) | ||
| eventPublisher.publishEvent(FileDeleteEvent(fileDirectory)) | ||
| } | ||
|
|
@@ -217,6 +224,22 @@ class AttachmentServiceImpl( | |
| contentEntity.attachments.add(attachment) | ||
| attachment.councilFile = contentEntity | ||
| } | ||
|
|
||
| else -> { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 메서드도 main image처럼 추후 간단하게 할 수 있다면 좋겠네용... |
||
| throw WrongMethodTypeException("파일을 엔티티에 연결할 수 없습니다") | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private fun attachmentDirectoryOf(contentEntityType: AttachmentAttachable): String { | ||
| return "attachment/" + when (contentEntityType) { | ||
| is NewsEntity -> Directory.NEWS.toString().lowercase() | ||
| is NoticeEntity -> Directory.NOTICE.toString().lowercase() | ||
| is SeminarEntity -> Directory.SEMINAR.toString().lowercase() | ||
| is AboutEntity -> Directory.ABOUT.toString().lowercase() | ||
| is AcademicsEntity -> Directory.ACADEMICS.toString().lowercase() | ||
| is CouncilFileEntity -> Directory.COUNCIL.toString().lowercase() | ||
| else -> "" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.wafflestudio.csereal.core.resource.directory | ||
|
|
||
| enum class Directory { | ||
| LAB, // for attachment | ||
| NEWS, // for attachment, mainImage | ||
| NOTICE, // for attachment | ||
| SEMINAR, // for attachment, mainImage | ||
| ABOUT, // for attachment, mainImage | ||
| ACADEMICS, // for attachment | ||
| COUNCIL, // for attachment, mainImage | ||
| PROFESSOR, // for mainImage | ||
| STAFF, // for mainImage | ||
| RESEARCH, // for mainImage | ||
| RECRUIT // for mainImage | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| ALTER TABLE attachment | ||
| ADD COLUMN directory VARCHAR(255) NULL, | ||
| DROP CONSTRAINT UQ_attachment_filename, | ||
| ADD CONSTRAINT UQ_attachment_directory_filename UNIQUE (directory, filename); | ||
|
|
||
| ALTER TABLE main_image | ||
| ADD COLUMN directory VARCHAR(255) NULL, | ||
| DROP CONSTRAINT UQ_main_image_filename, | ||
| ADD CONSTRAINT UQ_main_image_directory_filename UNIQUE (directory, filename); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 수정해주세요보다는 방향성을 고민해보면 좋을 거 같아서 코멘트 남깁니다.
현재 각 entity에서 구현한 attachable 인터페이스는 결국 패턴이 "{attachment,mainImage}/{domain}"의 형태로 고정되는거 같고,
각 도메인의 entity가 '어떤 경로에 저장되어야 한다'라는 정보까지 들고 있을 필요가 있을지는 고민되요.
위에 문제를 벗어나기 위해서 각 entity에 method를 정의한다기보다는
(fileType, attachable) -> String 의 식으로 resource/common 패키지 하위에 method를 추가하는 것도 한가지 방법일 거 같아요.
다만 어떻게 하든 장단점은 있어보이네요..!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
원래 attachable -> String 형식으로 메소드를 AttachmentService에 만들었는데, 저장 위치는 attachable이라면 가져야 할 속성이라 생각해 이렇게 수정했습니다.
다시 생각해보니 저장 위치를 하나의 함수에서 관리해줘야 한눈에 보기 편할 것 같기도 합니다.
수정해보겠습니다.