Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 13 additions & 38 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,29 @@
version: '3'
services:
redis:
container_name: redis
container_name: redis_test
image: redis:latest
ports:
- "6379:6379"
- "6375:6379"
networks:
- db_network

## deploy - 무중단
nginx:
image: nginx:1.15-alpine
container_name: nginx-container
restart: always
ports:
- "80:80"
volumes:
- ./nginx:/etc/nginx/conf.d
mysql:
container_name: mysql_test
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: root_pw
MYSQL_DATABASE: test_db
MYSQL_USER: test
MYSQL_PASSWORD: test_pw
command:
"/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
networks:
- backbone

green:
build: .
image: green
container_name: green
restart: always
- --default-authentication-plugin=mysql_native_password
ports:
- "8081:8080"
volumes:
- ./:/home/ubuntu
- /etc/localtime:/etc/localtime
- "3302:3306"
networks:
- backbone
- db_network

blue:
build: .
container_name: blue
restart: always
ports:
- "8082:8080"
volumes:
- ./:/home/ubuntu
- /etc/localtime:/etc/localtime
networks:
- backbone

networks:
db_network:
driver: bridge
backbone:
driver: bridge
25 changes: 4 additions & 21 deletions src/docs/asciidoc/board.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ include::{snippets}/intro-board-create/http-request.adoc[]
include::{snippets}/intro-board-create/http-response.adoc[]

==== 4. 게시글 리스트 조회 ( 페이징 처리 )

==== prefix : 필수값
==== category, search, order(default : RECENT) : 선택값

===== Request
include::{snippets}/get-board/http-request.adoc[]
===== Response
Expand Down Expand Up @@ -48,25 +52,4 @@ include::{snippets}/board-category/http-request.adoc[]
===== Response
include::{snippets}/board-category/http-response.adoc[]

==== 9. 게시글 검색 - 게시판 ( 자유 | 홍보 | 소개 )

본 API는 게시판별 게시글 목록 조회 기능을 수행합니다. name 값에 `DEFAULT`, `INTRO`, `ADVERTISEMENT` 값 중 하나를 입력해야 합니다.

keyword는 필수값은 아니며, 검색어를 통해 게시글의 작성자, 제목, 내용에 대해 검색합니다.

===== Request
include::{snippets}/board-prefix-search/http-request.adoc[]
===== Response
include::{snippets}/board-prefix-search/http-response.adoc[]

===== 10.게시글 검색 - 말머리

본 API는 말머리별 게시글 목록 조회 기능을 수행합니다. name 값에 말머리 조회를 통해 얻은 code 데이터 중 하나를 입력해야 합니다.

keyword는 필수값은 아니며, 검색어를 통해 게시글의 작성자, 제목, 내용에 대해 검색합니다.

===== Request
include::{snippets}/board-category-search/http-request.adoc[]

===== Response
include::{snippets}/board-category-search/http-response.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.example.jhouse_server.domain.board.service.BoardService
import com.example.jhouse_server.domain.user.entity.User
import com.example.jhouse_server.global.annotation.Auth
import com.example.jhouse_server.global.annotation.AuthUser
import com.example.jhouse_server.global.aop.log.logger
import com.example.jhouse_server.global.response.ApplicationResponse
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
Expand Down Expand Up @@ -36,12 +37,13 @@ class BoardController(
return ApplicationResponse.ok(boardService.updateBoard(boardId, req, user))
}


@GetMapping
fun getBoardAll(
@RequestParam category: String,
@PageableDefault(size=8) pageable: Pageable
) : ApplicationResponse<Page<BoardResDto>> {
return ApplicationResponse.ok(boardService.getBoardAll(category, pageable))
@ModelAttribute boardListDto: BoardListDto,
@PageableDefault(size=8, page=0) pageable: Pageable
): ApplicationResponse<Page<BoardResDto>> {
return ApplicationResponse.ok(boardService.getBoardAll(boardListDto, pageable))
}

@GetMapping("/{boardId}")
Expand Down Expand Up @@ -69,23 +71,5 @@ class BoardController(
return ApplicationResponse.ok(boardService.getCategory(name))
}

// name : prefix category
@GetMapping("/category/search")
fun getBoardAllWithPrefixCategory(
@RequestParam name : String,
@RequestParam keyword : String,
@PageableDefault pageable: Pageable
) : ApplicationResponse<Page<BoardResDto>> {
return ApplicationResponse.ok(boardService.getBoardAllWithPrefixCategory(name, keyword, pageable));
}

// name : category
@GetMapping("/board-category/search")
fun getBoardAllWithBoardCategory(
@RequestParam name : String,
@RequestParam keyword : String,
@PageableDefault pageable: Pageable
) : ApplicationResponse<Page<BoardResDto>> {
return ApplicationResponse.ok(boardService.getBoardAllWithBoardCategory(name, keyword, pageable));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import com.example.jhouse_server.domain.board.entity.BoardCategory
import com.example.jhouse_server.domain.comment.dto.CommentResDto
import org.slf4j.LoggerFactory
import java.sql.Timestamp
import java.text.Normalizer
import java.util.*
import java.util.regex.Matcher
import java.util.regex.Pattern
import javax.validation.constraints.NotNull
import kotlin.streams.toList

Expand All @@ -32,7 +35,8 @@ data class BoardResDto(
val imageUrl: String?,
val commentCount: Int,
val category: String,
val prefixCategory: String
val prefixCategory: String,
val fixed: Boolean
)

data class BoardUpdateReqDto(
Expand Down Expand Up @@ -61,23 +65,32 @@ data class BoardResOneDto(
val commentCount : Int,
val comments : List<CommentResDto>
)

data class BoardListDto(
val prefix: String,
val category: String?,
val search: String?,
val order: String?
)
fun toListDto(board : Board) : BoardResDto {
val oneLineContent = sliceContentWithRegex(board.content)
if (board.imageUrls.isEmpty()) {
return BoardResDto(board.id, board.title, board.boardCode.code, oneLineContent, board.user.nickName, Timestamp.valueOf(board.createdAt), null, board.comment.size, board.category.name, board.prefixCategory.name)
return BoardResDto(board.id, board.title, board.boardCode.code, oneLineContent, board.user.nickName, Timestamp.valueOf(board.createdAt), null, board.comment.size, board.category.name, board.prefixCategory.name, board.fixed)
}
return BoardResDto(board.id, board.title, board.boardCode.code, oneLineContent, board.user.nickName, Timestamp.valueOf(board.createdAt), board.imageUrls[0], board.comment.size, board.category.name, board.prefixCategory.name)
return BoardResDto(board.id, board.title, board.boardCode.code, oneLineContent, board.user.nickName, Timestamp.valueOf(board.createdAt), board.imageUrls[0], board.comment.size, board.category.name, board.prefixCategory.name, board.fixed)
}

fun toDto(board: Board) : BoardResOneDto {
return BoardResOneDto(board.id, board.title, board.boardCode.code, board.user.nickName, Timestamp.valueOf(board.createdAt), board.imageUrls, board.love.size, board.category.name, board.prefixCategory.name, board.comment.size, board.comment.stream().map { com.example.jhouse_server.domain.comment.dto.toDto(it) }.toList())
}
fun sliceContentWithRegex(content : String) : String {
val pattern = Regex("^[a-zA-Z가-힣].*[.!?]$")
val validatedString = pattern.find(content)?.value ?: ""
if (validatedString.length >= 200)
return validatedString.take(200)
return validatedString
// val pattern = Regex("^[a-zA-Z가-힣].*[.!?]$")
// val validatedString = pattern.find(content)?.value ?: ""
return if (content.length >= 200) {
content.take(200)
} else {
content
}
}

data class CodeResDto(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.jhouse_server.domain.board.repository

import com.example.jhouse_server.admin.board.dto.AdminBoardSearch
import com.example.jhouse_server.domain.board.BoardListDto
import com.example.jhouse_server.domain.board.PrefixCategory
import com.example.jhouse_server.domain.board.entity.Board
import com.example.jhouse_server.domain.board.entity.BoardCategory
Expand All @@ -10,7 +11,7 @@ import org.springframework.data.domain.Pageable
interface BoardRepositoryCustom {
fun getFixableBoardListWithPaging(adminBoardSearch: AdminBoardSearch, pageable: Pageable): Page<Board>
fun getDeletableBoardListWithPaging(adminBoardSearch: AdminBoardSearch, pageable: Pageable): Page<Board>
fun getBoardAllWithPrefixCategory(name: PrefixCategory, keyword: String, pageable: Pageable): Page<Board>
abstract fun getBoardAllWithBoardCategory(name: BoardCategory, keyword: String, pageable: Pageable): Page<Board>

fun getBoardAll(boardListDto: BoardListDto, pageable: Pageable): Page<Board>

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ package com.example.jhouse_server.domain.board.repository

import com.example.jhouse_server.admin.board.dto.AdminBoardSearch
import com.example.jhouse_server.admin.board.dto.SearchFilter
import com.example.jhouse_server.domain.board.BoardListDto
import com.example.jhouse_server.domain.board.PrefixCategory
import com.example.jhouse_server.domain.board.entity.Board
import com.example.jhouse_server.domain.board.entity.BoardCategory
import com.example.jhouse_server.domain.board.entity.QBoard.board
import com.example.jhouse_server.domain.board.entity.QBoardCode.boardCode
import com.example.jhouse_server.domain.comment.entity.QComment
import com.example.jhouse_server.domain.comment.entity.QComment.*
import com.example.jhouse_server.domain.love.entity.QLove.*
import com.example.jhouse_server.domain.user.entity.QUser.user
import com.querydsl.core.types.OrderSpecifier
import com.querydsl.core.types.dsl.BooleanExpression
import com.querydsl.jpa.impl.JPAQueryFactory
import org.hibernate.sql.ordering.antlr.OrderingSpecification
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageImpl
import org.springframework.data.domain.Pageable
Expand Down Expand Up @@ -50,38 +57,45 @@ class BoardRepositoryImpl(
return PageableExecutionUtils.getPage(result, pageable) {countQuery.fetch().size.toLong()}
}

override fun getBoardAllWithPrefixCategory(name: PrefixCategory, keyword: String, pageable: Pageable): Page<Board> {

override fun getBoardAll(boardListDto: BoardListDto, pageable: Pageable): Page<Board> {
val result = jpaQueryFactory
.select(board)
.from(board)
.where(searchWithPrefixCategory(name), searchWithKeyword(keyword), board.useYn.eq(true))
.selectFrom(board)
.join(board.boardCode, boardCode).fetchJoin()
.join(board.user, user).fetchJoin()
.where(board.useYn.eq(true), board.prefixCategory.eq(PrefixCategory.valueOf(boardListDto.prefix)),searchWithBoardCategory(boardListDto.category),searchWithKeyword(boardListDto.search))
.orderBy(board.fixed.desc(), searchWithOrder(boardListDto.order))
.limit(pageable.pageSize.toLong())
.offset(pageable.offset)
.fetch()
return PageImpl(result, pageable, result.size.toLong())
}
val countQuery = jpaQueryFactory
.selectFrom(board)
.where(board.useYn.eq(true), board.prefixCategory.eq(PrefixCategory.valueOf(boardListDto.prefix)),searchWithBoardCategory(boardListDto.category),searchWithKeyword(boardListDto.search))

override fun getBoardAllWithBoardCategory(
name: BoardCategory,
keyword: String,
pageable: Pageable
): Page<Board> {
val result = jpaQueryFactory
.select(board)
.from(board)
.where(searchWithBoardCategory(name), searchWithKeyword(keyword), board.useYn.eq(true))
.fetch()
return PageImpl(result, pageable, result.size.toLong())
return PageableExecutionUtils.getPage(result, pageable) {countQuery.fetch().size.toLong()}
}

private fun searchWithBoardCategory(name: BoardCategory): BooleanExpression? {
return board.category.eq(name)

private fun searchWithBoardCategory(category: String?): BooleanExpression? {
return if(category == null) null else board.category.eq(BoardCategory.valueOf(category))
}


private fun searchWithKeyword(keyword: String): BooleanExpression? {
return board.content.contains(keyword)
private fun searchWithKeyword(keyword: String?): BooleanExpression? {
return if(keyword == null) null else board.content.contains(keyword)
.or(board.title.contains(keyword))
.or(board.user.nickName.eq(keyword))
}

private fun searchWithOrder(order: String?): OrderSpecifier<*>?{
return when(order){
null -> board.updatedAt.desc()
"RECENT" -> board.updatedAt.desc()
"POPULAR" -> board.love.size().desc()
else -> null
}
}


private fun searchFilter(adminBoardSearch: AdminBoardSearch) : BooleanExpression? {
return when (adminBoardSearch.filter) {
SearchFilter.TITLE -> board.title.contains(adminBoardSearch.keyword)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import org.springframework.data.domain.Pageable
interface BoardService {
fun createBoard(req: BoardReqDto, user: User): Long
fun updateBoard(boardId: Long, req: BoardUpdateReqDto, user: User): Long
fun getBoardAll(category: String, pageable: Pageable): Page<BoardResDto>
// fun getBoardAll(category: String, pageable: Pageable): Page<BoardResDto>
fun getBoardAll(boardListDto: BoardListDto, pageable: Pageable): Page<BoardResDto>
fun getBoardOne(boardId: Long): BoardResOneDto
fun deleteBoard(boardId: Long, user: User)
fun getCategory(name: String): List<CodeResDto>
fun getBoardAllWithPrefixCategory(name: String, keyword: String, pageable: Pageable): Page<BoardResDto>
abstract fun getBoardAllWithBoardCategory(name: String, keyword: String, pageable: Pageable): Page<BoardResDto>

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,10 @@ class BoardServiceImpl(
).id
}

override fun getBoardAll(category: String, pageable: Pageable): Page<BoardResDto> {
return boardRepository.findAllByPrefixCategoryAndUseYn(
PrefixCategory.valueOf(category),
useYn = true,
pageable = pageable
).map{ toListDto(it) }

override fun getBoardAll(boardListDto: BoardListDto, pageable: Pageable): Page<BoardResDto> {
return boardRepository.getBoardAll(boardListDto, pageable)
.map { toListDto(it) }
}

override fun getBoardOne(boardId: Long): BoardResOneDto {
Expand All @@ -79,19 +77,6 @@ class BoardServiceImpl(
return BoardCategory.values().filter { it.superCategory.name == name }.map { CodeResDto(it.value, it.name) }
}

override fun getBoardAllWithPrefixCategory(name: String, keyword: String, pageable: Pageable): Page<BoardResDto> {
val prefixCategoryName = PrefixCategory.valueOf(name)
return boardRepository.getBoardAllWithPrefixCategory(prefixCategoryName, keyword, pageable).map { toListDto(it) }
}

override fun getBoardAllWithBoardCategory(
name: String,
keyword: String,
pageable: Pageable
): Page<BoardResDto> {
val boardCategoryName = BoardCategory.valueOf(name)
return boardRepository.getBoardAllWithBoardCategory(boardCategoryName, keyword, pageable).map{ toListDto(it) }
}

fun getContent(code: String): String {
var str = code
Expand Down
Loading