.
This commit is contained in:
@@ -17,22 +17,28 @@ class PostController(
|
||||
private val postService: PostService
|
||||
) {
|
||||
|
||||
// 목록 조회 (기본값: 최신순, 10개씩)
|
||||
@GetMapping
|
||||
fun getPosts(
|
||||
@RequestParam(required = false) keyword: String?,
|
||||
@RequestParam(required = false) category: String?,
|
||||
@RequestParam(required = false) tag: String?, // 👈 파라미터 추가
|
||||
@PageableDefault(size = 10, sort = ["id"], direction = Sort.Direction.DESC) pageable: Pageable
|
||||
@RequestParam(required = false) category: String?, // 👈 프론트는 'category'로 보냄
|
||||
@RequestParam(required = false) tag: String?,
|
||||
@PageableDefault(size = 10, sort = ["createdAt"], direction = Sort.Direction.DESC) pageable: Pageable
|
||||
): ResponseEntity<ApiResponse<Page<PostSummaryResponse>>> {
|
||||
|
||||
val result = postService.searchPosts(keyword, category, tag, pageable)
|
||||
return ResponseEntity.ok(ApiResponse.success(result))
|
||||
// 검색 조건이 하나라도 있으면 searchPosts 호출 (검색 + 카테고리 필터링)
|
||||
return if (keyword != null || category != null || tag != null) {
|
||||
val posts = postService.searchPosts(keyword, category, tag, pageable)
|
||||
ResponseEntity.ok(ApiResponse.success(posts))
|
||||
} else {
|
||||
// 조건이 없으면 전체 목록 조회
|
||||
val posts = postService.getPosts(pageable)
|
||||
ResponseEntity.ok(ApiResponse.success(posts))
|
||||
}
|
||||
}
|
||||
|
||||
// 상세 조회 (Slug)
|
||||
@GetMapping("/{slug}")
|
||||
fun getPost(@PathVariable slug: String): ResponseEntity<ApiResponse<PostResponse>> {
|
||||
return ResponseEntity.ok(ApiResponse.success(postService.getPostBySlug(slug)))
|
||||
val post = postService.getPostBySlug(slug)
|
||||
return ResponseEntity.ok(ApiResponse.success(post))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.wypark.blogbackend.api.controller
|
||||
|
||||
import me.wypark.blogbackend.api.common.ApiResponse
|
||||
import me.wypark.blogbackend.api.dto.ProfileResponse
|
||||
import me.wypark.blogbackend.domain.profile.BlogProfileService
|
||||
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
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/profile")
|
||||
class ProfileController(
|
||||
private val blogProfileService: BlogProfileService
|
||||
) {
|
||||
|
||||
@GetMapping
|
||||
fun getProfile(): ResponseEntity<ApiResponse<ProfileResponse>> {
|
||||
return ResponseEntity.ok(ApiResponse.success(blogProfileService.getProfile()))
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package me.wypark.blogbackend.api.controller.admin
|
||||
|
||||
import me.wypark.blogbackend.api.common.ApiResponse
|
||||
import me.wypark.blogbackend.api.dto.CategoryCreateRequest
|
||||
import me.wypark.blogbackend.api.dto.CategoryUpdateRequest
|
||||
import me.wypark.blogbackend.domain.category.CategoryService
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.*
|
||||
@@ -18,6 +19,16 @@ class AdminCategoryController(
|
||||
return ResponseEntity.ok(ApiResponse.success(id, "카테고리가 생성되었습니다."))
|
||||
}
|
||||
|
||||
// 👈 [추가] 카테고리 수정 (이름, 위치 이동)
|
||||
@PutMapping("/{id}")
|
||||
fun updateCategory(
|
||||
@PathVariable id: Long,
|
||||
@RequestBody request: CategoryUpdateRequest
|
||||
): ResponseEntity<ApiResponse<Nothing>> {
|
||||
categoryService.updateCategory(id, request)
|
||||
return ResponseEntity.ok(ApiResponse.success(message = "카테고리가 수정되었습니다."))
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
fun deleteCategory(@PathVariable id: Long): ResponseEntity<ApiResponse<Nothing>> {
|
||||
categoryService.deleteCategory(id)
|
||||
|
||||
@@ -7,10 +7,7 @@ import me.wypark.blogbackend.domain.post.PostService
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.security.core.userdetails.User
|
||||
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.RestController
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/posts")
|
||||
@@ -23,8 +20,23 @@ class AdminPostController(
|
||||
@RequestBody @Valid request: PostSaveRequest,
|
||||
@AuthenticationPrincipal user: User
|
||||
): ResponseEntity<ApiResponse<Long>> {
|
||||
// user.username은 email입니다.
|
||||
val postId = postService.createPost(request, user.username)
|
||||
return ResponseEntity.ok(ApiResponse.success(postId, "게시글이 작성되었습니다."))
|
||||
}
|
||||
|
||||
// 👈 [추가] 게시글 수정 엔드포인트
|
||||
@PutMapping("/{id}")
|
||||
fun updatePost(
|
||||
@PathVariable id: Long,
|
||||
@RequestBody @Valid request: PostSaveRequest
|
||||
): ResponseEntity<ApiResponse<Long>> {
|
||||
val postId = postService.updatePost(id, request)
|
||||
return ResponseEntity.ok(ApiResponse.success(postId, "게시글이 수정되었습니다."))
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
fun deletePost(@PathVariable id: Long): ResponseEntity<ApiResponse<Nothing>> {
|
||||
postService.deletePost(id)
|
||||
return ResponseEntity.ok(ApiResponse.success(message = "게시글과 포함된 이미지가 삭제되었습니다."))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package me.wypark.blogbackend.api.controller.admin
|
||||
|
||||
import me.wypark.blogbackend.api.common.ApiResponse
|
||||
import me.wypark.blogbackend.api.dto.ProfileUpdateRequest
|
||||
import me.wypark.blogbackend.domain.profile.BlogProfileService
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/profile")
|
||||
class AdminProfileController(
|
||||
private val blogProfileService: BlogProfileService
|
||||
) {
|
||||
|
||||
@PutMapping
|
||||
fun updateProfile(@RequestBody request: ProfileUpdateRequest): ResponseEntity<ApiResponse<Nothing>> {
|
||||
blogProfileService.updateProfile(request)
|
||||
return ResponseEntity.ok(ApiResponse.success(message = "프로필이 수정되었습니다."))
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,12 @@ data class CategoryCreateRequest(
|
||||
val parentId: Long? = null // null이면 최상위(Root) 카테고리
|
||||
)
|
||||
|
||||
// [요청] 카테고리 수정 (이름 + 부모 이동)
|
||||
data class CategoryUpdateRequest(
|
||||
val name: String,
|
||||
val parentId: Long? // null이면 최상위(Root)로 이동
|
||||
)
|
||||
|
||||
// [응답] 카테고리 트리 구조 (재귀)
|
||||
data class CategoryResponse(
|
||||
val id: Long,
|
||||
|
||||
@@ -8,7 +8,8 @@ data class CommentResponse(
|
||||
val id: Long,
|
||||
val content: String,
|
||||
val author: String,
|
||||
val isPostAuthor: Boolean, // 👈 [추가] 게시글 작성자 여부
|
||||
val isPostAuthor: Boolean,
|
||||
val memberId: Long?,
|
||||
val createdAt: LocalDateTime,
|
||||
val children: List<CommentResponse>
|
||||
) {
|
||||
@@ -22,7 +23,8 @@ data class CommentResponse(
|
||||
id = comment.id!!,
|
||||
content = comment.content,
|
||||
author = comment.getAuthorName(),
|
||||
isPostAuthor = isAuthor, // 👈 계산된 값 주입
|
||||
isPostAuthor = isAuthor,
|
||||
memberId = comment.member?.id,
|
||||
createdAt = comment.createdAt,
|
||||
children = comment.children.map { from(it) }
|
||||
)
|
||||
|
||||
@@ -36,7 +36,8 @@ data class PostSummaryResponse(
|
||||
val slug: String,
|
||||
val categoryName: String?,
|
||||
val viewCount: Long,
|
||||
val createdAt: LocalDateTime
|
||||
val createdAt: LocalDateTime,
|
||||
val content: String?
|
||||
) {
|
||||
companion object {
|
||||
fun from(post: Post): PostSummaryResponse {
|
||||
@@ -46,7 +47,8 @@ data class PostSummaryResponse(
|
||||
slug = post.slug,
|
||||
categoryName = post.category?.name,
|
||||
viewCount = post.viewCount,
|
||||
createdAt = post.createdAt
|
||||
createdAt = post.createdAt,
|
||||
content = post.content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
31
src/main/kotlin/me/wypark/blogbackend/api/dto/ProfileDtos.kt
Normal file
31
src/main/kotlin/me/wypark/blogbackend/api/dto/ProfileDtos.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package me.wypark.blogbackend.api.dto
|
||||
|
||||
import me.wypark.blogbackend.domain.profile.BlogProfile
|
||||
|
||||
data class ProfileResponse(
|
||||
val name: String,
|
||||
val bio: String,
|
||||
val imageUrl: String?,
|
||||
val githubUrl: String?,
|
||||
val email: String?
|
||||
) {
|
||||
companion object {
|
||||
fun from(profile: BlogProfile): ProfileResponse {
|
||||
return ProfileResponse(
|
||||
name = profile.name,
|
||||
bio = profile.bio,
|
||||
imageUrl = profile.imageUrl,
|
||||
githubUrl = profile.githubUrl,
|
||||
email = profile.email
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class ProfileUpdateRequest(
|
||||
val name: String,
|
||||
val bio: String,
|
||||
val imageUrl: String?,
|
||||
val githubUrl: String?,
|
||||
val email: String?
|
||||
)
|
||||
Reference in New Issue
Block a user