Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
deveunhwa committed Nov 4, 2024
2 parents 12fbcae + 9bc878a commit cc1716d
Show file tree
Hide file tree
Showing 42 changed files with 780 additions and 202 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tenten.bittakotlin.chat.controller

import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.http.ResponseEntity
import org.springframework.messaging.handler.annotation.MessageMapping
import org.springframework.messaging.simp.SimpMessagingTemplate
Expand All @@ -9,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.tenten.bittakotlin.chat.dto.ChatRequestDto
import org.tenten.bittakotlin.chat.dto.ChatResponseDto
Expand All @@ -28,17 +31,20 @@ class ChatController(
private val chatRoomService: ChatRoomService
) {
@MessageMapping("/send")
fun send(@RequestBody requestDto: ChatRequestDto.Send): Unit {
fun send(requestDto: ChatRequestDto.Send): Unit {
val responseDto: ChatResponseDto.Send = chatService.save(requestDto)

simpMessagingTemplate.convertAndSend("/room/${responseDto.chatRoomId}", responseDto)
}

@GetMapping("/room")
fun read(@RequestBody requestDto: ChatRequestDto.Read): ResponseEntity<Map<String, Any>> {
fun read(@RequestParam(defaultValue = "0") page: Int, @RequestParam(defaultValue = "20") size: Int
, @RequestBody requestDto: ChatRequestDto.Read): ResponseEntity<Map<String, Any>> {
val pageable: Pageable = PageRequest.of(page, size)

return ResponseEntity.ok(mapOf(
"message" to "파일 조회 링크를 성공적으로 생성했습니다.",
"result" to chatService.get(requestDto)
"message" to "채팅 목록을 성공적으로 생성했습니다.",
"result" to chatService.get(pageable, requestDto)
))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.tenten.bittakotlin.chat.repository

import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
Expand All @@ -8,6 +10,6 @@ import org.tenten.bittakotlin.chat.entity.Chat

@Repository
interface ChatRepository : JpaRepository<Chat, Long> {
@Query("SELECT c FROM Chat c WHERE c.chatRoom.id = :chatRoomId")
fun findAllByChatRoomId(@Param("chatRoomId") chatRoomId: Long): List<Chat>
@Query("SELECT c FROM Chat c WHERE c.chatRoom.id = :chatRoomId ORDER BY c.id DESC")
fun findAllByChatRoomIdOrderByIdDesc(@Param("chatRoomId") chatRoomId: Long, pageable: Pageable): Slice<Chat>
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package org.tenten.bittakotlin.chat.service

import org.springframework.data.domain.Pageable
import org.tenten.bittakotlin.chat.dto.ChatRequestDto
import org.tenten.bittakotlin.chat.dto.ChatResponseDto

interface ChatService {
fun get(requestDto: ChatRequestDto.Read): List<ChatResponseDto.Read>
fun get(pageable: Pageable, requestDto: ChatRequestDto.Read): List<ChatResponseDto.Read>

fun save(requestDto: ChatRequestDto.Send): ChatResponseDto.Send

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.tenten.bittakotlin.chat.service

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Slice
import org.springframework.stereotype.Service
import org.tenten.bittakotlin.chat.constant.ChatError
import org.tenten.bittakotlin.chat.dto.ChatRequestDto
Expand All @@ -25,20 +27,20 @@ class ChatServiceImpl(
private val logger: Logger = LoggerFactory.getLogger(ChatServiceImpl::class.java)
}

override fun get(requestDto: ChatRequestDto.Read): List<ChatResponseDto.Read> {
override fun get(pageable: Pageable, requestDto: ChatRequestDto.Read): List<ChatResponseDto.Read> {
var result: MutableList<ChatResponseDto.Read> = mutableListOf()

try {
val chatRoom: ChatRoom = chatRoomService.getChatRoomByNicknames(requestDto.sender, requestDto.receiver)
val chats: List<Chat> = chatRepository.findAllByChatRoomId(chatRoom.id!!)
val chats: Slice<Chat> = chatRepository.findAllByChatRoomIdOrderByIdDesc(chatRoom.id!!, pageable)

chats.forEach { c -> result.add(
chats.forEach { chat -> result.add(
ChatResponseDto.Read(
chatId = c.id!!,
sender = c.profile.nickname,
message = c.message,
deleted = c.deleted,
chatAt = c.createdAt!!
chatId = chat.id!!,
sender = chat.profile.nickname,
message = chat.message,
deleted = chat.deleted,
chatAt = chat.createdAt!!
))
}
} catch (e: NoSuchElementException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.tenten.bittakotlin.feed.constant

enum class FeedError(val code: Int, val message: String) {
NOT_FOUND(404, "피드가 존재하지 않습니다."),
CANNOT_FOUND(404, "피드가 존재하지 않습니다."),
CANNOT_MODIFY_BAD_AUTHORITY(403, "피드를 수정할 권한이 없습니다."),
CANNOT_DELETE_BAD_AUTHORITY(403, "피드를 삭제할 권한이 없습니다."),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.tenten.bittakotlin.feed.controller

import org.tenten.bittakotlin.feed.service.FeedService
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.tenten.bittakotlin.feed.dto.FeedRequestDto
import org.tenten.bittakotlin.security.service.PrincipalProvider

@RestController
@RequestMapping("/api/v1/feed")
class FeedController (
private val feedService: FeedService
) {
@GetMapping
fun readAll(
@RequestParam(required = false, defaultValue = "0", value = "page") page: Int,
@RequestParam(required = false, defaultValue = "10", value = "size") size: Int,
@RequestParam(required = false, value = "nickname") nickname: String?,
@RequestParam(required = false, value = "title") title: String?
): ResponseEntity<Map<String, Any>> {
val pageable: Pageable = PageRequest.of(page, size)

return ResponseEntity.ok(mapOf(
"message" to "피드 목록을 성공적으로 조회했습니다.",
"result" to feedService.getAll(pageable, nickname, title)
))
}

@GetMapping("/random")
fun readRandom(@RequestParam(required = false, defaultValue = "0", value = "page") size: Int
): ResponseEntity<Map<String, Any>> {
return ResponseEntity.ok(mapOf(
"message" to "피드 목록을 무작위로 조회했습니다.",
"result" to feedService.getRandom(size)
))
}

@GetMapping("/{id}")
fun read(@PathVariable("id") id: Long): ResponseEntity<Map<String, Any>> {
return ResponseEntity.ok(mapOf(
"message" to "피드를 성공적으로 조회했습니다.",
"result" to feedService.get(id)
))
}

@PostMapping
fun create(requestDto: FeedRequestDto.Create): ResponseEntity<Map<String, Any>> {
return ResponseEntity.ok(mapOf(
"message" to "피드를 성공적으로 등록했습니다.",
"result" to feedService.save(requestDto)
))
}

@PutMapping
fun modifyFeed(
@PathVariable("id") id: Long, @RequestBody requestDto: FeedRequestDto.Modify):
ResponseEntity<Map<String, Any>> {
return ResponseEntity.ok(mapOf(
"message" to "피드를 성공적으로 수정했습니다.",
"result" to feedService.update(id, requestDto)
))
}

@DeleteMapping("/{id}")
fun deleteFeed(@PathVariable id: Long): ResponseEntity<Map<String, Any>> {
feedService.delete(id)

return ResponseEntity.ok(mapOf(
"message" to "피드를 성공적으로 삭제했습니다."
))
}
}
23 changes: 23 additions & 0 deletions src/main/kotlin/org/tenten/bittakotlin/feed/dto/FeedRequestDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.tenten.bittakotlin.feed.dto

import org.tenten.bittakotlin.media.dto.MediaRequestDto

class FeedRequestDto {
data class Create (
val title: String,

val content: String,

val medias: List<MediaRequestDto.Upload>?
)

data class Modify (
val title: String,

val content: String,

val uploads: List<MediaRequestDto.Upload>?,

val deletes: List<MediaRequestDto.Delete>?
)
}
28 changes: 28 additions & 0 deletions src/main/kotlin/org/tenten/bittakotlin/feed/dto/FeedResponseDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.tenten.bittakotlin.feed.dto

import org.tenten.bittakotlin.media.dto.MediaResponseDto
import java.time.LocalDateTime

class FeedResponseDto {
data class Read (
val id: Long,

val title: String,

val content: String,

val author: String,

val createdAt: LocalDateTime,

val medias: List<MediaResponseDto.Read>
)

data class Create (
val medias: List<MediaResponseDto.Read>
)

data class Modify (
val medias: List<MediaResponseDto.Read>
)
}
38 changes: 38 additions & 0 deletions src/main/kotlin/org/tenten/bittakotlin/feed/entity/Feed.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.tenten.bittakotlin.feed.entity

import jakarta.persistence.*
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import org.tenten.bittakotlin.profile.entity.Profile
import java.time.LocalDateTime
import java.util.*

@Entity
@EntityListeners(AuditingEntityListener::class)
data class Feed(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,

@Column(nullable = false, length = 50)
var title: String,

@Column(nullable = false, length = 1000)
var content: String,

@ManyToOne
@JoinColumn(name = "profile_id", nullable = false)
val profile: Profile,

@OneToMany(mappedBy = "feed", cascade = [CascadeType.ALL])
val feedMedias: List<FeedMedia> = mutableListOf(),

@CreatedDate
@Column(updatable = false, nullable = false)
val createdAt: LocalDateTime? = null,

@LastModifiedDate
@Column(updatable = true, nullable = false)
var updatedAt: LocalDateTime? = null
)
22 changes: 22 additions & 0 deletions src/main/kotlin/org/tenten/bittakotlin/feed/entity/FeedMedia.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.tenten.bittakotlin.feed.entity

import jakarta.persistence.EmbeddedId
import jakarta.persistence.Entity
import jakarta.persistence.ManyToOne
import jakarta.persistence.MapsId
import org.tenten.bittakotlin.feed.entity.key.FeedMediaId
import org.tenten.bittakotlin.media.entity.Media

@Entity
data class FeedMedia (
@EmbeddedId
val id: FeedMediaId? = null,

@ManyToOne
@MapsId("feedId")
val feed: Feed,

@ManyToOne
@MapsId("mediaId")
val media: Media
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.tenten.bittakotlin.feed.entity.key

import jakarta.persistence.Embeddable
import java.io.Serializable

@Embeddable
data class FeedMediaId(
val feedId: Long,

val mediaId: Long
) : Serializable
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.prgrms2.java.bitta.feed.exception

import org.tenten.bittakotlin.feed.constant.FeedError

class FeedException(
val code: Int,

override val message: String
) : RuntimeException(message) {
constructor(feedError: FeedError): this(
code = feedError.code,
message = feedError.message
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.tenten.bittakotlin.feed.repository

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import org.tenten.bittakotlin.feed.entity.FeedMedia

@Repository
interface FeedMediaRepository : JpaRepository<FeedMedia, Long> {
@Query("SELECT fm.media.filename FROM FeedMedia fm WHERE fm.feed.id = :feedId")
fun findFilenamesByFeedId(@Param("feedId") feedId: Long): List<String>

@Query("DELETE FROM FeedMedia fm WHERE fm.media.id = :mediaId")
fun deleteByMediaId(@Param("mediaId") mediaId: Long)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.tenten.bittakotlin.feed.repository

import org.tenten.bittakotlin.feed.entity.Feed
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository

@Repository
interface FeedRepository : JpaRepository<Feed, Long> {

@Query("SELECT f FROM Feed f WHERE f.profile.nickname LIKE %:nickname% ORDER BY f.id DESC")
fun findAllLikeNicknameOrderByIdDesc(@Param("nickname") nickname: String, pageable: Pageable): Page<Feed>

@Query("SELECT f FROM Feed f WHERE f.title LIKE %:title% ORDER BY f.id DESC")
fun findAllLikeTitleOrderByIdDesc(@Param("title") title: String, pageable: Pageable): Page<Feed>

@Query("SELECT f FROM Feed f WHERE f.profile.nickname LIKE %:nickname% AND f.title LIKE %:title% ORDER BY f.id DESC")
fun findAllLikeNicknameAndTitleOrderByIdDesc(@Param("nickname") nickname: String, @Param("title") title: String,
pageable: Pageable): Page<Feed>

fun findAllByOrderByIdDesc(pageable: Pageable): Page<Feed>
}
Loading

0 comments on commit cc1716d

Please sign in to comment.