Skip to content

Commit

Permalink
Merge pull request #111 from Kusitms-29th-ASAP/feature/tranlate/menu
Browse files Browse the repository at this point in the history
feat: 메뉴 번역 기능 추가
  • Loading branch information
tlarbals824 authored Aug 15, 2024
2 parents 16a9291 + 5943112 commit 1d80cb7
Show file tree
Hide file tree
Showing 20 changed files with 321 additions and 32 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ repositories {

val kotestVersion = "5.8.1"
val mockkVersion = "1.13.10"
extra["springModulithVersion"] = "1.2.0"
extra["springModulithVersion"] = "1.2.1"


val asciidoctorExt = "asciidoctorExt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class IncompleteEventRepublicationHandler(
private val applicationEventMulticaster: IncompleteEventPublications
) {

//분마다 실행
//시간마다 실행
@Scheduled(cron = "0 0 * * * ?")
fun resubmitIncompletePublications() {
applicationEventMulticaster.resubmitIncompletePublications { true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class MenuScheduler (
pageNumber++

TransactionUtils.writable {
menuAppender.addMenu(menuDataContainer.menuInfo)
menuAppender.addMenus(menuDataContainer.menuInfo)
}
}while (menuDataContainer.hasNext)
val endTime = System.currentTimeMillis()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ class MenuOpenApiClient (
val pageable = PageRequest.of(pageNumber, batchSize)
val schools = schoolRepository.findAll(pageable)
val hasNext = schools.hasNext()
val menuFluxex = schools.content.map { school ->
val menuFluxes = schools.content.map { school ->
getMenuResponse(school)
}
val menuInfoList = mutableListOf<Menu>()
Flux.merge(menuFluxex)
Flux.merge(menuFluxes)
.buffer(1000)
.doOnNext(menuInfoList::addAll)
.blockLast()
Expand All @@ -38,6 +38,7 @@ class MenuOpenApiClient (
hasNext = hasNext
)
}

private fun getMenuResponse(school: School): Flux<Menu> {
val formatter = DateTimeFormatter.ofPattern("yyyyMM")
val date = LocalDate.now().format(formatter)
Expand All @@ -57,8 +58,8 @@ class MenuOpenApiClient (
.bodyToMono(String::class.java)
.map {
val menuOpenApiResponse = objectMapper.readValue(it, MenuOpenApiResponse::class.java)
menuOpenApiResponse?.mealServiceDietInfo?.flatMap { menlInfo ->
menlInfo.row?.map {
menuOpenApiResponse?.mealServiceDietInfo?.flatMap { menuInfo ->
menuInfo.row?.map {
it.toMenu(school)
} ?: emptyList()
} ?: emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ data class Row(
) {
fun toMenu(school: School): Menu {
return Menu(
school = school,

schoolId = school.id,
foods = convertToFoods(DDISH_NM),
day = LocalDate.parse(MLSV_YMD, DateTimeFormatter.BASIC_ISO_DATE)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package com.asap.asapbackend.domain.menu.domain.model

import com.asap.asapbackend.domain.school.domain.model.School
import com.asap.asapbackend.global.domain.BaseDateEntity
import jakarta.persistence.Entity
import jakarta.persistence.FetchType
import jakarta.persistence.ManyToOne
import org.hibernate.annotations.JdbcTypeCode
import org.hibernate.type.SqlTypes
import java.time.LocalDate
import java.time.LocalDateTime

@Entity
class Menu(
school: School,
id: Long = 0L,
schoolId: Long,
day: LocalDate,
foods: List<Food>
) : BaseDateEntity() {
@ManyToOne(fetch = FetchType.LAZY)
val school: School = school
foods: List<Food>,
createdAt: LocalDateTime = LocalDateTime.now(),
updatedAt: LocalDateTime = LocalDateTime.now()
){
val id: Long = id

val schoolId: Long = schoolId

val day: LocalDate = day

@JdbcTypeCode(SqlTypes.JSON)
val foods: List<Food> = foods

val createdAt: LocalDateTime = createdAt
val updatedAt: LocalDateTime = updatedAt
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.asap.asapbackend.domain.menu.domain.repository

import com.asap.asapbackend.domain.menu.domain.model.Menu
import org.springframework.data.jpa.repository.JpaRepository
import java.time.LocalDate

interface MenuRepository : JpaRepository<Menu, Long> {
interface MenuRepository{
fun findBySchoolIdAndDay(schoolId: Long, day: LocalDate): Menu?

fun findBySchoolIdAndDayInOrderByDayAsc(schoolId: Long, day: List<LocalDate>): List<Menu>

fun saveAll(menus: List<Menu>): List<Menu>
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package com.asap.asapbackend.domain.menu.domain.service

import com.asap.asapbackend.batch.menu.MenuInfoProvider
import com.asap.asapbackend.domain.menu.domain.model.Allergy
import com.asap.asapbackend.domain.menu.domain.model.Food
import com.asap.asapbackend.domain.menu.domain.model.Menu
import com.asap.asapbackend.domain.menu.domain.repository.MenuRepository
import com.asap.asapbackend.domain.menu.event.MultiMenuCreateEvent
import com.fasterxml.jackson.databind.ObjectMapper
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Service

private val logger = KotlinLogging.logger {}

@Service
class MenuAppender(
private val menuRepository: MenuRepository
private val menuRepository: MenuRepository,
private val applicationEventPublisher: ApplicationEventPublisher,
private val objectMapper: ObjectMapper
) {
fun addMenu(menus: List<Menu>) {
menuRepository.saveAll(menus)
fun addMenus(menus: List<Menu>) {
val savedMenu = menuRepository.saveAll(menus)
val event = MultiMenuCreateEvent(savedMenu.toSet())
applicationEventPublisher.publishEvent(event)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.asap.asapbackend.domain.menu.event

import com.asap.asapbackend.domain.menu.domain.model.Menu

data class MultiMenuCreateEvent(
val menus: Set<Menu>
) {
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.asap.asapbackend.infrastructure.jpa

import jakarta.persistence.PreUpdate
import jakarta.persistence.MappedSuperclass
import java.time.LocalDateTime

@MappedSuperclass
open class BaseEntity(
val createdAt: LocalDateTime = LocalDateTime.now(),
var updatedAt: LocalDateTime = LocalDateTime.now()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,25 @@ class MultiLanguageId(
columnDefinition = "varchar(50)"
)
val language: Language = language


override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as MultiLanguageId

if (id != other.id) return false
if (language != other.language) return false

return true
}

override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + language.hashCode()
return result
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.asap.asapbackend.infrastructure.jpa.menu

import com.asap.asapbackend.domain.menu.domain.model.Food
import com.asap.asapbackend.domain.menu.domain.model.Menu
import com.asap.asapbackend.infrastructure.jpa.menu.entity.FoodEntity
import com.asap.asapbackend.infrastructure.jpa.menu.entity.MenuEntity


object MenuMapper {
fun toModel(menuEntity: MenuEntity): Menu {
return Menu(
id = menuEntity.id,
schoolId = menuEntity.schoolId,
day = menuEntity.day,
foods = toFoodModel(menuEntity.foods),
createdAt = menuEntity.createdAt,
updatedAt = menuEntity.updatedAt
)
}

private fun toFoodModel(foodEntities: List<FoodEntity>): List<Food>{
return foodEntities.map {
Food(
name = it.name,
allergies = it.allergies
)
}
}

fun toEntity(menu: Menu): MenuEntity {
return MenuEntity(
id = menu.id,
schoolId = menu.schoolId,
day = menu.day,
foods = toFoodEntity(menu.foods),
createdAt = menu.createdAt,
updatedAt = menu.updatedAt
)
}

private fun toFoodEntity(foods: List<Food>): List<FoodEntity>{
return foods.map {
FoodEntity(
name = it.name,
allergies = it.allergies
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.asap.asapbackend.infrastructure.jpa.menu

import com.asap.asapbackend.domain.menu.domain.model.Menu
import com.asap.asapbackend.domain.menu.domain.repository.MenuRepository
import com.asap.asapbackend.global.util.LanguageExtractor
import com.asap.asapbackend.infrastructure.jpa.MultiLanguageId
import com.asap.asapbackend.infrastructure.jpa.menu.entity.MenuEntity
import com.asap.asapbackend.infrastructure.jpa.menu.repository.MenuJpaRepository
import com.asap.asapbackend.infrastructure.jpa.menu.repository.TranslatedMenuJpaRepository
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Repository
import java.time.LocalDate

@Repository
class MenuRepositoryImpl(
private val menuJpaRepository: MenuJpaRepository,
private val translatedMenuJpaRepository: TranslatedMenuJpaRepository,
private val languageExtractor: LanguageExtractor
) : MenuRepository {
override fun findBySchoolIdAndDay(schoolId: Long, day: LocalDate): Menu? {
val menu = menuJpaRepository.findBySchoolIdAndDay(schoolId, day) ?: return null
val targetLanguageMenuId = getMenusMultiLanguageId(menu)
translatedMenuJpaRepository.findByIdOrNull(targetLanguageMenuId)?.let {
menu.changeFoods(it.foods)
}
return MenuMapper.toModel(menu)
}



override fun findBySchoolIdAndDayInOrderByDayAsc(schoolId: Long, day: List<LocalDate>): List<Menu> {
val menus = menuJpaRepository.findBySchoolIdAndDayInOrderByDayAsc(schoolId, day)
val menuFoods =
translatedMenuJpaRepository.findAllByIdIn(getMenusMultiLanguageIds(menus))
.associate { it.id.id to it.foods }
return menus.map {
it.changeFoods(menuFoods[it.id])
MenuMapper.toModel(it)
}
}

override fun saveAll(menus: List<Menu>) : List<Menu>{
val savedMenus = menuJpaRepository.saveAll(menus.map { MenuMapper.toEntity(it) })
return savedMenus.map {
MenuMapper.toModel(it)
}
}

private fun getMenusMultiLanguageId(menu: MenuEntity): MultiLanguageId {
val targetLanguageMenuId = MultiLanguageId(menu.id, languageExtractor.getRequestLanguage())
return targetLanguageMenuId
}

private fun getMenusMultiLanguageIds(menus: List<MenuEntity>): List<MultiLanguageId> {
return menus.map {
MultiLanguageId(it.id, languageExtractor.getRequestLanguage())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.asap.asapbackend.infrastructure.jpa.menu.entity

import com.asap.asapbackend.domain.menu.domain.model.Allergy


data class FoodEntity(
val name: String,
val allergies: List<Allergy>
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.asap.asapbackend.infrastructure.jpa.menu.entity

import com.asap.asapbackend.infrastructure.jpa.BaseEntity
import jakarta.persistence.*
import org.hibernate.annotations.JdbcTypeCode
import org.hibernate.type.SqlTypes
import java.time.LocalDate
import java.time.LocalDateTime

@Entity
@Table(
name = "menu",
indexes = [
Index(name = "idx_menu_school_id", columnList = "school_id"),
Index(name = "idx_menu_school_and_day", columnList = "school_id, day", unique = true)
]
)
class MenuEntity(
id: Long,
schoolId: Long,
day: LocalDate,
foods: List<FoodEntity>,
createdAt: LocalDateTime,
updatedAt: LocalDateTime
) : BaseEntity(createdAt, updatedAt) {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = id

@Column(
nullable = false,
name = "school_id"

)
val schoolId: Long = schoolId

val day: LocalDate = day

@JdbcTypeCode(value = SqlTypes.JSON)
var foods: List<FoodEntity> = foods



fun changeFoods(foods: List<FoodEntity>?){
foods?.let {
this.foods = foods
}
}
}
Loading

0 comments on commit 1d80cb7

Please sign in to comment.