-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from wafflestudio/feat/auth
Feat/article
- Loading branch information
Showing
13 changed files
with
441 additions
and
78 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
src/main/kotlin/com/toyProject7/karrot/article/ArticleException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.toyProject7.karrot.article | ||
|
||
import com.toyProject7.karrot.DomainException | ||
import org.springframework.http.HttpStatus | ||
import org.springframework.http.HttpStatusCode | ||
|
||
sealed class ArticleException( | ||
errorCode: Int, | ||
httpStatusCode: HttpStatusCode, | ||
msg: String, | ||
cause: Throwable? = null, | ||
) : DomainException(errorCode, httpStatusCode, msg, cause) | ||
|
||
class ArticleNotFoundException : ArticleException( | ||
errorCode = 0, | ||
httpStatusCode = HttpStatus.NOT_FOUND, | ||
msg = "Article not found", | ||
) | ||
|
||
class ArticlePermissionDeniedException : ArticleException( | ||
errorCode = 0, | ||
httpStatusCode = HttpStatus.UNAUTHORIZED, | ||
msg = "Permission denied", | ||
) |
32 changes: 31 additions & 1 deletion
32
src/main/kotlin/com/toyProject7/karrot/article/controller/Article.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,33 @@ | ||
package com.toyProject7.karrot.article.controller | ||
|
||
class Article | ||
import com.toyProject7.karrot.article.persistence.ArticleEntity | ||
import com.toyProject7.karrot.user.controller.User | ||
import java.time.Instant | ||
|
||
data class Article( | ||
val id: Long, | ||
val seller: User, | ||
val title: String, | ||
val content: String, | ||
val price: Int, | ||
val status: String, | ||
val location: String, | ||
val createdAt: Instant, | ||
val likeCount: Int, | ||
) { | ||
companion object { | ||
fun fromEntity(entity: ArticleEntity): Article { | ||
return Article( | ||
id = entity.id!!, | ||
seller = User.fromEntity(entity.seller), | ||
title = entity.title, | ||
content = entity.content, | ||
price = entity.price, | ||
status = entity.status, | ||
location = entity.location, | ||
createdAt = entity.createdAt, | ||
likeCount = entity.articleLikes.size, | ||
) | ||
} | ||
} | ||
} |
99 changes: 98 additions & 1 deletion
99
src/main/kotlin/com/toyProject7/karrot/article/controller/ArticleController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,100 @@ | ||
package com.toyProject7.karrot.article.controller | ||
|
||
class ArticleController | ||
import com.toyProject7.karrot.article.persistence.ArticleEntity | ||
import com.toyProject7.karrot.article.service.ArticleService | ||
import com.toyProject7.karrot.user.AuthUser | ||
import com.toyProject7.karrot.user.controller.User | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.web.bind.annotation.DeleteMapping | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.PostMapping | ||
import org.springframework.web.bind.annotation.PutMapping | ||
import org.springframework.web.bind.annotation.RequestBody | ||
import org.springframework.web.bind.annotation.RequestParam | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RestController | ||
class ArticleController( | ||
private val articleService: ArticleService, | ||
) { | ||
@PostMapping("api/item/post") | ||
fun postArticle( | ||
@RequestBody request: PostArticleRequest, | ||
@AuthUser user: User, | ||
): ResponseEntity<Article> { | ||
val article = articleService.postArticle(request, user.id) | ||
return ResponseEntity.ok(article) | ||
} | ||
|
||
@PutMapping("api/item/edit/{articleId}") | ||
fun editArticle( | ||
@RequestBody request: PostArticleRequest, | ||
@PathVariable articleId: Long, | ||
@AuthUser user: User, | ||
): ResponseEntity<Article> { | ||
val article = articleService.editArticle(articleId, request, user.id) | ||
return ResponseEntity.ok(article) | ||
} | ||
|
||
@DeleteMapping("api/item/delete/{articleId}") | ||
fun deleteArticle( | ||
@PathVariable articleId: Long, | ||
@AuthUser user: User, | ||
): ResponseEntity<String> { | ||
articleService.deleteArticle(articleId, user.id) | ||
return ResponseEntity.ok("Deleted Successfully") | ||
} | ||
|
||
@GetMapping("api/item/get/{articleId}") | ||
fun getArticle( | ||
@PathVariable articleId: Long, | ||
): ResponseEntity<Article> { | ||
return ResponseEntity.ok(articleService.getArticle(articleId)) | ||
} | ||
|
||
@GetMapping("/api/home") | ||
fun getPreviousArticles( | ||
@RequestParam("articleId") articleId: Long, | ||
): ResponseEntity<List<Item>> { | ||
val articles: List<ArticleEntity> = articleService.getPreviousArticles(articleId) | ||
val response: List<Item> = | ||
articles.map { article -> | ||
Item.fromArticle(Article.fromEntity(article)) | ||
} | ||
return ResponseEntity.ok(response) | ||
} | ||
|
||
@GetMapping("/api/mypage/sells") | ||
fun getArticlesBySeller( | ||
@RequestParam("articleId") articleId: Long, | ||
@AuthUser user: User, | ||
): ResponseEntity<List<Item>> { | ||
val articles: List<ArticleEntity> = articleService.getArticlesBySeller(user.id, articleId) | ||
val response: List<Item> = | ||
articles.map { article -> | ||
Item.fromArticle(Article.fromEntity(article)) | ||
} | ||
return ResponseEntity.ok(response) | ||
} | ||
|
||
@GetMapping("/api/mypage/buys") | ||
fun getArticlesByBuyer( | ||
@RequestParam("articleId") articleId: Long, | ||
@AuthUser user: User, | ||
): ResponseEntity<List<Item>> { | ||
val articles = articleService.getArticlesByBuyer(user.id, articleId) | ||
val response: List<Item> = | ||
articles.map { article -> | ||
Item.fromArticle(Article.fromEntity(article)) | ||
} | ||
return ResponseEntity.ok(response) | ||
} | ||
} | ||
|
||
data class PostArticleRequest( | ||
val title: String, | ||
val content: String, | ||
val price: Int, | ||
val location: String, | ||
) |
28 changes: 28 additions & 0 deletions
28
src/main/kotlin/com/toyProject7/karrot/article/controller/Item.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.toyProject7.karrot.article.controller | ||
|
||
import java.time.Instant | ||
|
||
// article's preview information | ||
data class Item( | ||
val id: Long, | ||
val title: String, | ||
val price: Int, | ||
val status: String, | ||
val location: String, | ||
val createdAt: Instant, | ||
val likeCount: Int, | ||
) { | ||
companion object { | ||
fun fromArticle(article: Article): Item { | ||
return Item( | ||
id = article.id, | ||
title = article.title, | ||
price = article.price, | ||
status = article.status, | ||
location = article.location, | ||
createdAt = article.createdAt, | ||
likeCount = article.likeCount, | ||
) | ||
} | ||
} | ||
} |
40 changes: 39 additions & 1 deletion
40
src/main/kotlin/com/toyProject7/karrot/article/persistence/ArticleEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,41 @@ | ||
package com.toyProject7.karrot.article.persistence | ||
|
||
class ArticleEntity | ||
import com.toyProject7.karrot.user.persistence.UserEntity | ||
import jakarta.persistence.Column | ||
import jakarta.persistence.Entity | ||
import jakarta.persistence.GeneratedValue | ||
import jakarta.persistence.GenerationType | ||
import jakarta.persistence.Id | ||
import jakarta.persistence.JoinColumn | ||
import jakarta.persistence.ManyToOne | ||
import jakarta.persistence.OneToMany | ||
import java.time.Instant | ||
|
||
@Entity(name = "article") | ||
class ArticleEntity( | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
val id: Long? = null, | ||
@ManyToOne | ||
@JoinColumn(name = "seller") | ||
var seller: UserEntity, | ||
@ManyToOne | ||
@JoinColumn(name = "buyer") | ||
var buyer: UserEntity?, | ||
@Column(name = "title", nullable = false) | ||
var title: String, | ||
@Column(name = "content", nullable = false) | ||
var content: String, | ||
@Column(name = "price", nullable = false) | ||
var price: Int, | ||
@Column(name = "status", nullable = false) | ||
var status: String, | ||
@Column(name = "location", nullable = false) | ||
var location: String, | ||
@OneToMany(mappedBy = "article") | ||
var articleLikes: MutableList<ArticleLikesEntity> = mutableListOf(), | ||
@Column(name = "created_at", nullable = false) | ||
var createdAt: Instant, | ||
@Column(name = "updated_at", nullable = false) | ||
var updatedAt: Instant, | ||
) |
27 changes: 26 additions & 1 deletion
27
src/main/kotlin/com/toyProject7/karrot/article/persistence/ArticleLikesEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,28 @@ | ||
package com.toyProject7.karrot.article.persistence | ||
|
||
class ArticleLikesEntity | ||
import com.toyProject7.karrot.user.persistence.UserEntity | ||
import jakarta.persistence.Column | ||
import jakarta.persistence.Entity | ||
import jakarta.persistence.GeneratedValue | ||
import jakarta.persistence.GenerationType | ||
import jakarta.persistence.Id | ||
import jakarta.persistence.JoinColumn | ||
import jakarta.persistence.ManyToOne | ||
import java.time.Instant | ||
|
||
@Entity(name = "article_likes") | ||
class ArticleLikesEntity( | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.UUID) | ||
val id: String? = null, | ||
@ManyToOne | ||
@JoinColumn(name = "article_id") | ||
var article: ArticleEntity, | ||
@ManyToOne | ||
@JoinColumn(name = "user") | ||
var user: UserEntity, | ||
@Column(name = "created_at", nullable = false) | ||
var createdAt: Instant, | ||
@Column(name = "updated_at", nullable = false) | ||
var updatedAt: Instant, | ||
) |
4 changes: 3 additions & 1 deletion
4
src/main/kotlin/com/toyProject7/karrot/article/persistence/ArticleLikesRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
package com.toyProject7.karrot.article.persistence | ||
|
||
class ArticleLikesRepository | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
|
||
interface ArticleLikesRepository : JpaRepository<ArticleLikesEntity, String> |
17 changes: 16 additions & 1 deletion
17
src/main/kotlin/com/toyProject7/karrot/article/persistence/ArticleRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,18 @@ | ||
package com.toyProject7.karrot.article.persistence | ||
|
||
class ArticleRepository | ||
import com.toyProject7.karrot.user.persistence.UserEntity | ||
import org.springframework.data.jpa.repository.JpaRepository | ||
|
||
interface ArticleRepository : JpaRepository<ArticleEntity, Long> { | ||
fun findTop10ByIdBeforeOrderByCreatedAtDesc(id: Long): List<ArticleEntity> | ||
|
||
fun findTop10BySellerAndIdLessThanOrderByIdDesc( | ||
seller: UserEntity, | ||
id: Long, | ||
): List<ArticleEntity> | ||
|
||
fun findTop10ByBuyerAndIdLessThanOrderByIdDesc( | ||
buyer: UserEntity, | ||
id: Long, | ||
): List<ArticleEntity> | ||
} |
103 changes: 102 additions & 1 deletion
103
src/main/kotlin/com/toyProject7/karrot/article/service/ArticleService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,104 @@ | ||
package com.toyProject7.karrot.article.service | ||
|
||
class ArticleService | ||
import com.toyProject7.karrot.article.ArticleNotFoundException | ||
import com.toyProject7.karrot.article.ArticlePermissionDeniedException | ||
import com.toyProject7.karrot.article.controller.Article | ||
import com.toyProject7.karrot.article.controller.PostArticleRequest | ||
import com.toyProject7.karrot.article.persistence.ArticleEntity | ||
import com.toyProject7.karrot.article.persistence.ArticleRepository | ||
import com.toyProject7.karrot.user.service.UserService | ||
import org.springframework.data.repository.findByIdOrNull | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
import java.time.Instant | ||
|
||
@Service | ||
class ArticleService( | ||
private val articleRepository: ArticleRepository, | ||
private val userService: UserService, | ||
) { | ||
@Transactional | ||
fun postArticle( | ||
request: PostArticleRequest, | ||
id: String, | ||
): Article { | ||
val user = userService.getUserEntityById(id) | ||
val articleEntity = | ||
ArticleEntity( | ||
seller = user, | ||
buyer = null, | ||
title = request.title, | ||
content = request.content, | ||
price = request.price, | ||
status = "판매 중", | ||
location = request.location, | ||
createdAt = Instant.now(), | ||
updatedAt = Instant.now(), | ||
).let { | ||
articleRepository.save(it) | ||
} | ||
return Article.fromEntity(articleEntity) | ||
} | ||
|
||
@Transactional | ||
fun editArticle( | ||
articleId: Long, | ||
request: PostArticleRequest, | ||
id: String, | ||
): Article { | ||
val user = userService.getUserEntityById(id) | ||
val articleEntity = articleRepository.findByIdOrNull(articleId) ?: throw ArticleNotFoundException() | ||
if (articleEntity.seller.userId != user.userId) { | ||
throw ArticlePermissionDeniedException() | ||
} | ||
request.title.let { articleEntity.title = it } | ||
request.content.let { articleEntity.content = it } | ||
request.price.let { articleEntity.price = it } | ||
request.location.let { articleEntity.location = it } | ||
articleEntity.updatedAt = Instant.now() | ||
articleRepository.save(articleEntity) | ||
return Article.fromEntity(articleEntity) | ||
} | ||
|
||
@Transactional | ||
fun deleteArticle( | ||
articleId: Long, | ||
id: String, | ||
) { | ||
val user = userService.getUserEntityById(id) | ||
val articleEntity = articleRepository.findByIdOrNull(articleId) ?: throw ArticleNotFoundException() | ||
if (articleEntity.seller.userId != user.userId) { | ||
throw ArticlePermissionDeniedException() | ||
} | ||
articleRepository.delete(articleEntity) | ||
} | ||
|
||
@Transactional | ||
fun getArticle(articleId: Long): Article { | ||
val articleEntity = articleRepository.findByIdOrNull(articleId) ?: throw ArticleNotFoundException() | ||
return Article.fromEntity(articleEntity) | ||
} | ||
|
||
@Transactional | ||
fun getPreviousArticles(articleId: Long): List<ArticleEntity> { | ||
return articleRepository.findTop10ByIdBeforeOrderByCreatedAtDesc(articleId) | ||
} | ||
|
||
@Transactional | ||
fun getArticlesBySeller( | ||
id: String, | ||
articleId: Long, | ||
): List<ArticleEntity> { | ||
val seller = userService.getUserEntityById(id) | ||
return articleRepository.findTop10BySellerAndIdLessThanOrderByIdDesc(seller, articleId) | ||
} | ||
|
||
@Transactional | ||
fun getArticlesByBuyer( | ||
id: String, | ||
articleId: Long, | ||
): List<ArticleEntity> { | ||
val buyer = userService.getUserEntityById(id) | ||
return articleRepository.findTop10ByBuyerAndIdLessThanOrderByIdDesc(buyer, articleId) | ||
} | ||
} |
Oops, something went wrong.