Skip to content

Commit

Permalink
Feat: Conference page 수정 API (#99)
Browse files Browse the repository at this point in the history
* Feat: Add Controller for member search only top, and page.

* Feat: Add ResearchSearchEntity, and entry for conference, research, lab entity.

* Feat: For research create/update, lab create, add updating researchsearch.

* Feat: Add empty repository and service for ResearchSearch

* Feat: Add update method for labentity.

* Feat: Add update lab service.

* Feat: Add update lab controller.

* Test: Add ResearchServiceTest.

* Feat: Add Conference Repository.

* Feat: add conferenc eentity method for create, update entity.

* Feat: Change variables to mutable.

* Feat: Add id in conferencedto.

* Feat: Add to sort the conferenceList.

* Feat: Add deleteAttachment (marking)

* Feat add service to modify conference page (create, modify, delete conferences)

* Feat: Add api for modify conference page.

* Test: Add test for conference service.

---------

Co-authored-by: Junhyeong Kim <indiv0227@snu.ac.kr>
  • Loading branch information
huGgW and leeeryboy authored Sep 12, 2023
1 parent 5225232 commit ba8aace
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.wafflestudio.csereal.core.conference.api

import com.wafflestudio.csereal.common.aop.AuthenticatedStaff
import com.wafflestudio.csereal.core.conference.dto.ConferenceModifyRequest
import com.wafflestudio.csereal.core.conference.dto.ConferencePage
import com.wafflestudio.csereal.core.conference.service.ConferenceService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*

@RequestMapping("/api/v1/conference")
@RestController
Expand All @@ -18,4 +18,15 @@ class ConferenceController(
return ResponseEntity.ok(conferenceService.getConferencePage())
}

@AuthenticatedStaff
@PatchMapping("/page/conferences")
fun modifyConferencePage(
@RequestBody conferenceModifyRequest: ConferenceModifyRequest
): ResponseEntity<ConferencePage> {
return ResponseEntity.ok(
conferenceService.modifyConferences(
conferenceModifyRequest
)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.wafflestudio.csereal.core.conference.database

import com.wafflestudio.csereal.common.config.BaseTimeEntity
import com.wafflestudio.csereal.core.conference.dto.ConferenceCreateDto
import com.wafflestudio.csereal.core.conference.dto.ConferenceDto
import com.wafflestudio.csereal.core.research.database.ResearchSearchEntity
import jakarta.persistence.*

Expand All @@ -18,4 +20,21 @@ class ConferenceEntity(
@OneToOne(mappedBy = "conferenceElement", cascade = [CascadeType.ALL], orphanRemoval = true)
var researchSearch: ResearchSearchEntity? = null,
) : BaseTimeEntity() {
}
companion object {
fun of(
conferenceCreateDto: ConferenceCreateDto,
conferencePage: ConferencePageEntity,
) = ConferenceEntity(
code = conferenceCreateDto.code,
abbreviation = conferenceCreateDto.abbreviation,
name = conferenceCreateDto.name,
conferencePage = conferencePage,
)
}

fun update(conferenceDto: ConferenceDto) {
this.code = conferenceDto.code
this.abbreviation = conferenceDto.abbreviation
this.name = conferenceDto.name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ class ConferencePageEntity(

@OneToOne
@JoinColumn(name = "author_id")
val author: UserEntity,
var author: UserEntity,

@OneToMany(mappedBy = "conferencePage")
@OneToMany(mappedBy = "conferencePage", cascade = [CascadeType.ALL], orphanRemoval = true)
@OrderBy("code ASC")
val conferences: List<ConferenceEntity> = mutableListOf()
val conferences: MutableSet<ConferenceEntity> = mutableSetOf()

) : BaseTimeEntity()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.wafflestudio.csereal.core.conference.database

import org.springframework.data.jpa.repository.JpaRepository

interface ConferenceRepository: JpaRepository<ConferenceEntity, Long>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.wafflestudio.csereal.core.conference.dto

data class ConferenceCreateDto (
val code: String,
val abbreviation: String,
val name: String,
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ package com.wafflestudio.csereal.core.conference.dto
import com.wafflestudio.csereal.core.conference.database.ConferenceEntity

data class ConferenceDto(
val id: Long,
val code: String,
val abbreviation: String,
val name: String
val name: String,
) {
companion object {
fun of(conferenceEntity: ConferenceEntity): ConferenceDto {
return ConferenceDto(
id = conferenceEntity.id,
code = conferenceEntity.code,
abbreviation = conferenceEntity.abbreviation,
name = conferenceEntity.name
name = conferenceEntity.name,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.wafflestudio.csereal.core.conference.dto

data class ConferenceModifyRequest(
val newConferenceList: List<ConferenceCreateDto>,
val modifiedConferenceList: List<ConferenceDto>,
val deleteConfereceIdList: List<Long>
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ data class ConferencePage(
createdAt = conferencePageEntity.createdAt!!,
modifiedAt = conferencePageEntity.modifiedAt!!,
author = conferencePageEntity.author.name,
conferenceList = conferencePageEntity.conferences.map { ConferenceDto.of(it) }
conferenceList = conferencePageEntity.conferences.map {
ConferenceDto.of(it)
}.sortedBy { it.code }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
package com.wafflestudio.csereal.core.conference.service

import com.wafflestudio.csereal.common.CserealException
import com.wafflestudio.csereal.core.conference.database.ConferenceEntity
import com.wafflestudio.csereal.core.conference.database.ConferencePageEntity
import com.wafflestudio.csereal.core.conference.database.ConferencePageRepository
import com.wafflestudio.csereal.core.conference.database.ConferenceRepository
import com.wafflestudio.csereal.core.conference.dto.ConferenceCreateDto
import com.wafflestudio.csereal.core.conference.dto.ConferenceDto
import com.wafflestudio.csereal.core.conference.dto.ConferenceModifyRequest
import com.wafflestudio.csereal.core.conference.dto.ConferencePage
import com.wafflestudio.csereal.core.research.database.ResearchSearchEntity
import com.wafflestudio.csereal.core.research.service.ResearchSearchService
import com.wafflestudio.csereal.core.user.database.UserEntity
import com.wafflestudio.csereal.core.user.database.UserRepository
import org.springframework.data.repository.findByIdOrNull
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.core.oidc.user.OidcUser
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.context.request.RequestAttributes
import org.springframework.web.context.request.RequestContextHolder


interface ConferenceService {
fun getConferencePage(): ConferencePage
fun modifyConferences(conferenceModifyRequest: ConferenceModifyRequest): ConferencePage
}

@Service
@Transactional
class ConferenceServiceImpl(
private val conferencePageRepository: ConferencePageRepository
private val conferencePageRepository: ConferencePageRepository,
private val conferenceRepository: ConferenceRepository,
private val userRepository: UserRepository,
private val researchSearchService: ResearchSearchService,
) : ConferenceService {

@Transactional(readOnly = true)
Expand All @@ -23,4 +42,84 @@ class ConferenceServiceImpl(
return ConferencePage.of(conferencePage)
}

}
@Transactional
override fun modifyConferences(conferenceModifyRequest: ConferenceModifyRequest): ConferencePage {
var user = RequestContextHolder.getRequestAttributes()?.getAttribute(
"loggedInUser",
RequestAttributes.SCOPE_REQUEST
) as UserEntity?

if (user == null) {
val oidcUser = SecurityContextHolder.getContext().authentication.principal as OidcUser
val username = oidcUser.idToken.getClaim<String>("username")

user = userRepository.findByUsername(username) ?: throw CserealException.Csereal404("재로그인이 필요합니다.")
}

val conferencePage = conferencePageRepository.findAll()[0]

val newConferenceList = conferenceModifyRequest.newConferenceList.map {
createConferenceWithoutSave(it, conferencePage)
}

val modifiedConferenceList = conferenceModifyRequest.modifiedConferenceList.map {
modifyConferenceWithoutSave(it)
}

val deleteConferenceList = conferenceModifyRequest.deleteConfereceIdList.map {
deleteConference(it, conferencePage)
}

conferencePage.author = user

return ConferencePage.of(conferencePage)
}

@Transactional
fun createConferenceWithoutSave(
conferenceCreateDto: ConferenceCreateDto,
conferencePage: ConferencePageEntity,
): ConferenceEntity {
val newConference = ConferenceEntity.of(
conferenceCreateDto,
conferencePage
)
conferencePage.conferences.add(newConference)

newConference.researchSearch = ResearchSearchEntity.create(newConference)

return newConference
}

@Transactional
fun modifyConferenceWithoutSave(
conferenceDto: ConferenceDto,
): ConferenceEntity {
val conferenceEntity = conferenceRepository.findByIdOrNull(conferenceDto.id)
?: throw CserealException.Csereal404("Conference id:${conferenceDto.id} 가 존재하지 않습니다.")

conferenceEntity.update(conferenceDto)

conferenceEntity.researchSearch?.update(conferenceEntity)
?: let {
conferenceEntity.researchSearch = ResearchSearchEntity.create(conferenceEntity)
}

return conferenceEntity
}

@Transactional
fun deleteConference(
id: Long,
conferencePage: ConferencePageEntity,
) = conferenceRepository.findByIdOrNull(id)
?. let {
it.isDeleted = true
conferencePage.conferences.remove(it)

it.researchSearch?.let {
researchSearchService.deleteResearchSearch(it)
}
it.researchSearch = null
}
}
Loading

0 comments on commit ba8aace

Please sign in to comment.