1
0

fix: 优化代码的组织

This commit is contained in:
2024-12-22 10:48:52 +08:00
parent 9fd28264dd
commit 5ac0f35976
7 changed files with 337 additions and 273 deletions

View File

@@ -1,271 +0,0 @@
package com.lanyuanxiaoyao.bookstore
import cn.hutool.core.util.IdUtil
import jakarta.annotation.Resource
import jakarta.transaction.Transactional
import org.slf4j.LoggerFactory
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import org.springframework.web.bind.annotation.*
data class PageResponse<E>(
val items: List<E>,
val total: Long,
)
data class SingleResponse<E>(
val data: Map<String, E>,
) {
constructor(e: E): this(mapOf("item" to e))
}
@RestController
@RequestMapping("book")
class BookController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var bookRepository: BookRepository
@GetMapping("list")
fun list(
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = bookRepository.findAll(PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save")
fun save(@RequestBody item: ViewItem) {
bookRepository.save(
Book(
bookId = item.bookId ?: IdUtil.fastSimpleUUID(),
name = item.name,
author = item.author,
description = item.description,
source = item.source,
tags = item.tags?.toMutableSet() ?: mutableSetOf()
)
)
}
@GetMapping("detail/{bookId}")
fun detail(@PathVariable("bookId") bookId: String): ViewItem {
return bookRepository.findById(bookId).orElseThrow().let { ViewItem(it) }
}
@Transactional
@GetMapping("remove/{bookId}")
fun remove(@PathVariable("bookId") bookId: String) {
bookRepository.deleteById(bookId)
}
@GetMapping("tags")
fun tags(): List<String> {
return bookRepository.findAllTag()
}
data class ViewItem(
val bookId: String?,
val name: String,
val author: String?,
val description: String,
val source: String?,
val tags: Set<String>?,
) {
constructor(book: Book) : this(
book.bookId,
book.name,
book.author,
book.description,
book.source,
book.tags,
)
}
}
@RestController
@RequestMapping("chapter")
class ChapterController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var bookRepository: BookRepository
@Resource
private lateinit var chapterRepository: ChapterRepository
@Resource
private lateinit var lineRepository: LineRepository
@GetMapping("list/{bookId}")
fun list(
@PathVariable("bookId") bookId: String,
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = chapterRepository.findAll({ root, _, builder ->
builder.equal(root.get<Book>("book").get<String>("bookId"), bookId)
}, PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save/{bookId}")
fun save(@PathVariable("bookId") bookId: String, @RequestBody item: ViewItem) {
val book = bookRepository.findById(bookId).orElseThrow()
chapterRepository.save(
Chapter(
chapterId = item.chapterId ?: IdUtil.fastSimpleUUID(),
name = item.name,
sequence = item.sequence,
description = item.description,
book = book,
)
)
}
@Transactional
@PostMapping("import/{chapterId}")
fun import(@PathVariable("chapterId") chapterId: String, @RequestBody item: ImportItem) {
val chapter = chapterRepository.findById(chapterId).orElseThrow()
var startIndex = chapter.content.size.toLong()
if (item.override) {
lineRepository.deleteAllInBatch(chapter.content)
startIndex = 0
}
chapter.content = item.text
.split("\n")
.mapIndexed { index, line ->
Line(
lineId = IdUtil.fastSimpleUUID(),
sequence = startIndex + index,
text = line.trim(),
chapter = chapter,
)
}
.toMutableSet()
chapterRepository.save(chapter)
}
@GetMapping("detail/{chapterId}")
fun detail(@PathVariable("chapterId") chapterId: String): ViewItem {
return chapterRepository.findById(chapterId).orElseThrow().let { ViewItem(it) }
}
@GetMapping("show/{chapterId}")
fun show(@PathVariable("chapterId") chapterId: String): SingleResponse<String> {
return SingleResponse(
lineRepository
.findAll({ root, _, builder ->
builder.equal(root.get<Chapter>("chapter").get<String>("chapterId"), chapterId)
}, Sort.by(Sort.Direction.DESC, "sequence"))
.joinToString("\n") { "<p>${it.text}</p>" }
)
}
@Transactional
@GetMapping("remove/{chapterId}")
fun remove(@PathVariable("chapterId") chapterId: String) {
chapterRepository.deleteById(chapterId)
}
data class ViewItem(
val chapterId: String?,
val name: String?,
val sequence: Int,
val description: String?,
) {
constructor(chapter: Chapter) : this(
chapter.chapterId,
chapter.name,
chapter.sequence,
chapter.description,
)
}
data class ImportItem(
val override: Boolean = false,
val text: String
)
}
@RestController
@RequestMapping("line")
class LineController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var chapterRepository: ChapterRepository
@Resource
private lateinit var lineRepository: LineRepository
@GetMapping("list/{chapterId}")
fun list(
@PathVariable("chapterId") chapterId: String,
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = lineRepository.findAll({ root, _, builder ->
builder.equal(root.get<Chapter>("chapter").get<String>("chapterId"), chapterId)
}, PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save/{lineId}")
fun save(@PathVariable("lineId") lineId: String, @RequestBody item: ViewItem) {
val chapter = chapterRepository.findById(lineId).orElseThrow()
lineRepository.save(
Line(
lineId = item.lineId ?: IdUtil.fastSimpleUUID(),
sequence = item.sequence,
text = item.text,
chapter = chapter,
)
)
}
@Transactional
@PostMapping("update/{lineId}")
fun update(@PathVariable("lineId") lineId: String, @RequestBody item: ViewItem) {
val line = lineRepository.findById(lineId).orElseThrow()
line.text = item.text
lineRepository.save(line)
}
@GetMapping("detail/{lineId}")
fun detail(@PathVariable("lineId") lineId: String): ViewItem {
return lineRepository.findById(lineId).orElseThrow().let { ViewItem(it) }
}
@Transactional
@GetMapping("remove/{lineId}")
fun remove(@PathVariable("lineId") lineId: String) {
lineRepository.deleteById(lineId)
}
data class ViewItem(
val lineId: String?,
val sequence: Long,
val text: String,
) {
constructor(line: Line) : this(
line.lineId,
line.sequence,
line.text,
)
}
}

View File

@@ -2,7 +2,20 @@
package com.lanyuanxiaoyao.bookstore
import jakarta.persistence.*
import jakarta.persistence.CascadeType
import jakarta.persistence.Column
import jakarta.persistence.ConstraintMode
import jakarta.persistence.ElementCollection
import jakarta.persistence.Entity
import jakarta.persistence.FetchType
import jakarta.persistence.ForeignKey
import jakarta.persistence.Id
import jakarta.persistence.JoinColumn
import jakarta.persistence.Lob
import jakarta.persistence.ManyToOne
import jakarta.persistence.NamedAttributeNode
import jakarta.persistence.NamedEntityGraph
import jakarta.persistence.OneToMany
import org.hibernate.annotations.DynamicUpdate
import org.springframework.data.jpa.repository.EntityGraph
import org.springframework.data.jpa.repository.JpaRepository

View File

@@ -0,0 +1,12 @@
package com.lanyuanxiaoyao.bookstore
data class PageResponse<E>(
val items: List<E>,
val total: Long,
)
data class SingleResponse<E>(
val data: Map<String, E>,
) {
constructor(e: E) : this(mapOf("item" to e))
}

View File

@@ -0,0 +1,87 @@
package com.lanyuanxiaoyao.bookstore.controller
import cn.hutool.core.util.IdUtil
import com.lanyuanxiaoyao.bookstore.Book
import com.lanyuanxiaoyao.bookstore.BookRepository
import com.lanyuanxiaoyao.bookstore.PageResponse
import jakarta.annotation.Resource
import jakarta.transaction.Transactional
import org.slf4j.LoggerFactory
import org.springframework.data.domain.PageRequest
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.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("book")
class BookController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var bookRepository: BookRepository
@GetMapping("list")
fun list(
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = bookRepository.findAll(PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save")
fun save(@RequestBody item: ViewItem) {
bookRepository.save(
Book(
bookId = item.bookId ?: IdUtil.fastSimpleUUID(),
name = item.name,
author = item.author,
description = item.description,
source = item.source,
tags = item.tags?.toMutableSet() ?: mutableSetOf()
)
)
}
@GetMapping("detail/{bookId}")
fun detail(@PathVariable("bookId") bookId: String): ViewItem {
return bookRepository.findById(bookId).orElseThrow().let { ViewItem(it) }
}
@Transactional
@GetMapping("remove/{bookId}")
fun remove(@PathVariable("bookId") bookId: String) {
bookRepository.deleteById(bookId)
}
@GetMapping("tags")
fun tags(): List<String> {
return bookRepository.findAllTag()
}
data class ViewItem(
val bookId: String?,
val name: String,
val author: String?,
val description: String,
val source: String?,
val tags: Set<String>?,
) {
constructor(book: Book) : this(
book.bookId,
book.name,
book.author,
book.description,
book.source,
book.tags,
)
}
}

View File

@@ -0,0 +1,132 @@
package com.lanyuanxiaoyao.bookstore.controller
import cn.hutool.core.util.IdUtil
import com.lanyuanxiaoyao.bookstore.Book
import com.lanyuanxiaoyao.bookstore.BookRepository
import com.lanyuanxiaoyao.bookstore.Chapter
import com.lanyuanxiaoyao.bookstore.ChapterRepository
import com.lanyuanxiaoyao.bookstore.Line
import com.lanyuanxiaoyao.bookstore.LineRepository
import com.lanyuanxiaoyao.bookstore.PageResponse
import com.lanyuanxiaoyao.bookstore.SingleResponse
import jakarta.annotation.Resource
import jakarta.transaction.Transactional
import org.slf4j.LoggerFactory
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
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.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("chapter")
class ChapterController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var bookRepository: BookRepository
@Resource
private lateinit var chapterRepository: ChapterRepository
@Resource
private lateinit var lineRepository: LineRepository
@GetMapping("list/{bookId}")
fun list(
@PathVariable("bookId") bookId: String,
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = chapterRepository.findAll({ root, _, builder ->
builder.equal(root.get<Book>("book").get<String>("bookId"), bookId)
}, PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save/{bookId}")
fun save(@PathVariable("bookId") bookId: String, @RequestBody item: ViewItem) {
val book = bookRepository.findById(bookId).orElseThrow()
chapterRepository.save(
Chapter(
chapterId = item.chapterId ?: IdUtil.fastSimpleUUID(),
name = item.name,
sequence = item.sequence,
description = item.description,
book = book,
)
)
}
@Transactional
@PostMapping("import/{chapterId}")
fun import(@PathVariable("chapterId") chapterId: String, @RequestBody item: ImportItem) {
val chapter = chapterRepository.findById(chapterId).orElseThrow()
var startIndex = chapter.content.size.toLong()
if (item.override) {
lineRepository.deleteAllInBatch(chapter.content)
startIndex = 0
}
chapter.content = item.text
.split("\n")
.mapIndexed { index, line ->
Line(
lineId = IdUtil.fastSimpleUUID(),
sequence = startIndex + index,
text = line.trim(),
chapter = chapter,
)
}
.toMutableSet()
chapterRepository.save(chapter)
}
@GetMapping("detail/{chapterId}")
fun detail(@PathVariable("chapterId") chapterId: String): ViewItem {
return chapterRepository.findById(chapterId).orElseThrow().let { ViewItem(it) }
}
@GetMapping("show/{chapterId}")
fun show(@PathVariable("chapterId") chapterId: String): SingleResponse<String> {
return SingleResponse(
lineRepository
.findAll({ root, _, builder ->
builder.equal(root.get<Chapter>("chapter").get<String>("chapterId"), chapterId)
}, Sort.by(Sort.Direction.DESC, "sequence"))
.joinToString("\n") { "<p>${it.text}</p>" }
)
}
@Transactional
@GetMapping("remove/{chapterId}")
fun remove(@PathVariable("chapterId") chapterId: String) {
chapterRepository.deleteById(chapterId)
}
data class ViewItem(
val chapterId: String?,
val name: String?,
val sequence: Int,
val description: String?,
) {
constructor(chapter: Chapter) : this(
chapter.chapterId,
chapter.name,
chapter.sequence,
chapter.description,
)
}
data class ImportItem(
val override: Boolean = false,
val text: String
)
}

View File

@@ -0,0 +1,91 @@
package com.lanyuanxiaoyao.bookstore.controller
import cn.hutool.core.util.IdUtil
import com.lanyuanxiaoyao.bookstore.Chapter
import com.lanyuanxiaoyao.bookstore.ChapterRepository
import com.lanyuanxiaoyao.bookstore.Line
import com.lanyuanxiaoyao.bookstore.LineRepository
import com.lanyuanxiaoyao.bookstore.PageResponse
import jakarta.annotation.Resource
import jakarta.transaction.Transactional
import org.slf4j.LoggerFactory
import org.springframework.data.domain.PageRequest
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.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("line")
class LineController {
private val log = LoggerFactory.getLogger(javaClass)
@Resource
private lateinit var chapterRepository: ChapterRepository
@Resource
private lateinit var lineRepository: LineRepository
@GetMapping("list/{chapterId}")
fun list(
@PathVariable("chapterId") chapterId: String,
@RequestParam("page", defaultValue = "1") page: Int,
@RequestParam("size", defaultValue = "10") size: Int
): PageResponse<ViewItem> {
val pageable = lineRepository.findAll({ root, _, builder ->
builder.equal(root.get<Chapter>("chapter").get<String>("chapterId"), chapterId)
}, PageRequest.of(0.coerceAtLeast(page - 1), size))
return PageResponse(
pageable.content.map { ViewItem(it) },
pageable.totalElements,
)
}
@Transactional
@PostMapping("save/{lineId}")
fun save(@PathVariable("lineId") lineId: String, @RequestBody item: ViewItem) {
val chapter = chapterRepository.findById(lineId).orElseThrow()
lineRepository.save(
Line(
lineId = item.lineId ?: IdUtil.fastSimpleUUID(),
sequence = item.sequence,
text = item.text,
chapter = chapter,
)
)
}
@Transactional
@PostMapping("update/{lineId}")
fun update(@PathVariable("lineId") lineId: String, @RequestBody item: ViewItem) {
val line = lineRepository.findById(lineId).orElseThrow()
line.text = item.text
lineRepository.save(line)
}
@GetMapping("detail/{lineId}")
fun detail(@PathVariable("lineId") lineId: String): ViewItem {
return lineRepository.findById(lineId).orElseThrow().let { ViewItem(it) }
}
@Transactional
@GetMapping("remove/{lineId}")
fun remove(@PathVariable("lineId") lineId: String) {
lineRepository.deleteById(lineId)
}
data class ViewItem(
val lineId: String?,
val sequence: Long,
val text: String,
) {
constructor(line: Line) : this(
line.lineId,
line.sequence,
line.text,
)
}
}

View File

@@ -32,7 +32,7 @@
<script src="components/chapter.js"></script>
<script>
(function () {
let debug = true
let debug = false
let amis = amisRequire('amis/embed')
let amisJSON = {
type: 'page',