diff --git a/.idea/GitCommitMessageStorage.xml b/.idea/GitCommitMessageStorage.xml
new file mode 100644
index 0000000..e4fd56a
--- /dev/null
+++ b/.idea/GitCommitMessageStorage.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/csv-editor.xml b/.idea/csv-editor.xml
new file mode 100644
index 0000000..af8e228
--- /dev/null
+++ b/.idea/csv-editor.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/pages/book/Book.tsx b/client/src/pages/book/Book.tsx
index 94451e5..55d88a3 100644
--- a/client/src/pages/book/Book.tsx
+++ b/client/src/pages/book/Book.tsx
@@ -9,6 +9,48 @@ import {
time,
} from '../../util/amis.tsx'
+const detailDialog = (bookId: string | undefined) => {
+ return {
+ title: '添加书架',
+ size: 'md',
+ body: {
+ debug: commonInfo.debug,
+ type: 'form',
+ api: `${commonInfo.baseUrl}/chapter/save`,
+ initApi: `${commonInfo.baseUrl}/chapter/detail/\${id}`,
+ initFetchOn: '${id}',
+ ...horizontalFormOptions(),
+ canAccessSuperData: false,
+ body: [
+ {
+ type: 'hidden',
+ name: 'bookId',
+ value: bookId,
+ },
+ {
+ type: 'input-number',
+ name: 'sequence',
+ label: '序号',
+ required: true,
+ },
+ {
+ type: 'input-text',
+ name: 'name',
+ label: '名称',
+ required: true,
+ clearable: true,
+ },
+ {
+ type: 'textarea',
+ name: 'description',
+ label: '描述',
+ clearable: true,
+ },
+ ],
+ },
+ }
+}
+
function Book() {
const navigate = useNavigate()
const {id} = useParams()
@@ -49,11 +91,11 @@ function Book() {
sort: [
{
column: 'sequence',
- direction: 'ASC',
+ direction: 'DESC',
},
{
column: 'modifiedTime',
- direction: 'DESC',
+ direction: 'ASC',
},
],
},
@@ -70,7 +112,9 @@ function Book() {
actionType: 'ajax',
tooltip: '序号重排',
tooltipPlacement: 'top',
- api: `get:${commonInfo.baseUrl}/chapter/generate_sequence`
+ api: `get:${commonInfo.baseUrl}/chapter/generate_sequence`,
+ confirmText: '确认重排序号?',
+ confirmTitle: '序号重拍',
},
{
type: 'action',
@@ -142,7 +186,7 @@ function Book() {
actionType: 'dialog',
dialog: detailDialog(),
},*/
- ]
+ ],
),
columns: [
{
@@ -193,14 +237,14 @@ function Book() {
},
},
},
- /*{
+ {
type: 'action',
label: '修改',
level: 'link',
size: 'sm',
actionType: 'dialog',
- dialog: detailDialog(),
- },*/
+ dialog: detailDialog(id),
+ },
{
className: 'text-danger btn-deleted',
type: 'action',
diff --git a/client/src/pages/book/Bookshelf.tsx b/client/src/pages/book/Bookshelf.tsx
index 41b6714..a39947b 100644
--- a/client/src/pages/book/Bookshelf.tsx
+++ b/client/src/pages/book/Bookshelf.tsx
@@ -96,7 +96,7 @@ function Bookshelf() {
{
name: 'name',
label: '书名',
- width: 150,
+ width: 120,
fixed: 'left',
},
{
@@ -112,7 +112,7 @@ function Bookshelf() {
{
name: 'source',
label: '来源',
- width: 150,
+ width: 200,
},
{
name: 'tags',
diff --git a/client/src/pages/book/Chapter.tsx b/client/src/pages/book/Chapter.tsx
index 60be467..881259b 100644
--- a/client/src/pages/book/Chapter.tsx
+++ b/client/src/pages/book/Chapter.tsx
@@ -1,6 +1,13 @@
import React from 'react'
import {useParams} from 'react-router'
-import {amisRender, commonInfo, crudCommonOptions, horizontalFormOptions, paginationTemplate} from '../../util/amis.tsx'
+import {
+ amisRender,
+ commonInfo,
+ crudCommonOptions,
+ horizontalFormOptions,
+ paginationTemplate,
+ readOnlyDialogOptions,
+} from '../../util/amis.tsx'
function Chapter() {
// const navigate = useNavigate()
@@ -52,19 +59,46 @@ function Chapter() {
},
...crudCommonOptions(),
...paginationTemplate(
- undefined,
+ 50,
undefined,
[
{
type: 'action',
label: '',
- icon: 'fa fa-rotate-right',
+ icon: 'fa fa-book-open-reader',
actionType: 'ajax',
tooltip: '序号重排',
tooltipPlacement: 'top',
- api: `get:${commonInfo.baseUrl}/line/generate_sequence/${id}`
- }
- ]
+ api: `get:${commonInfo.baseUrl}/line/generate_sequence/${id}`,
+ confirmText: '确认重排序号?',
+ confirmTitle: '序号重拍',
+ },
+ {
+ type: 'action',
+ label: '',
+ icon: 'fa fa-glasses',
+ actionType: 'dialog',
+ tooltip: '全文阅读',
+ tooltipPlacement: 'top',
+ dialog: {
+ title: '全文查看',
+ size: 'md',
+ ...readOnlyDialogOptions(),
+ body: {
+ type: 'service',
+ size: 'none',
+ api: `${commonInfo.baseUrl}/chapter/content/${id}`,
+ body: {
+ type: 'markdown',
+ value: '${detail}',
+ options: {
+ breaks: true,
+ },
+ },
+ },
+ },
+ },
+ ],
),
columns: [
{
diff --git a/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java b/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
index df504be..9383c59 100644
--- a/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
+++ b/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
@@ -1,23 +1,10 @@
package com.lanyuanxiaoyao.bookstore;
-import cn.hutool.core.lang.Tuple;
-import cn.hutool.core.text.csv.CsvUtil;
-import cn.hutool.core.util.NumberUtil;
-import cn.hutool.core.util.ObjectUtil;
import com.blinkfox.fenix.EnableFenix;
-import com.lanyuanxiaoyao.bookstore.entity.Chapter;
-import com.lanyuanxiaoyao.bookstore.entity.Line;
-import com.lanyuanxiaoyao.bookstore.service.BookService;
-import com.lanyuanxiaoyao.bookstore.service.ChapterService;
-import jakarta.annotation.Resource;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.util.stream.Collectors;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
-import org.springframework.transaction.annotation.Transactional;
/**
* 启动类
@@ -33,44 +20,4 @@ public class BookStoreApplication {
public static void main(String[] args) {
SpringApplication.run(BookStoreApplication.class, args);
}
-
- @Resource
- private BookService bookService;
- @Resource
- private ChapterService chapterService;
-
- @Transactional(rollbackFor = Throwable.class)
- // @EventListener(ApplicationReadyEvent.class)
- public void loadOldData() throws FileNotFoundException {
- var reader = CsvUtil.getReader(new FileReader("C:\\Users\\lanyuanxiaoyao\\Result_6.csv"));
- var rows = reader.stream()
- .map(row -> new Row(Long.parseLong(row.get(0)), row.get(1), Long.parseLong(row.get(2)), row.get(3)))
- .toList();
- var book = bookService.detailOrThrow(3602572744994816L);
- rows.stream()
- .map(row -> new Tuple(row.chapterSequence(), row.chapterTitle()))
- .distinct()
- .forEach(tuple -> {
- var chapter = new Chapter();
- chapter.setSequence(NumberUtil.toDouble(tuple.get(0)));
- chapter.setName(tuple.get(1));
- chapter.setBook(book);
-
- var lines = rows.stream()
- .filter(row -> ObjectUtil.equals(row.chapterSequence(), tuple.get(0)) && ObjectUtil.equals(row.chapterTitle(), tuple.get(1)))
- .map(row -> {
- var line = new Line();
- line.setSequence(NumberUtil.toDouble(row.lineSequence()));
- line.setText(row.lineText());
- line.setChapter(chapter);
- return line;
- })
- .collect(Collectors.toSet());
- chapter.setContent(lines);
- chapterService.save(chapter);
- });
- }
-
- public record Row(long chapterSequence, String chapterTitle, long lineSequence, String lineText) {
- }
}
diff --git a/src/main/java/com/lanyuanxiaoyao/bookstore/controller/ChapterController.java b/src/main/java/com/lanyuanxiaoyao/bookstore/controller/ChapterController.java
index 25ae242..d33b91c 100644
--- a/src/main/java/com/lanyuanxiaoyao/bookstore/controller/ChapterController.java
+++ b/src/main/java/com/lanyuanxiaoyao/bookstore/controller/ChapterController.java
@@ -1,6 +1,8 @@
package com.lanyuanxiaoyao.bookstore.controller;
+import cn.hutool.core.util.ObjectUtil;
import com.lanyuanxiaoyao.bookstore.entity.Chapter;
+import com.lanyuanxiaoyao.bookstore.entity.Line;
import com.lanyuanxiaoyao.bookstore.entity.vo.Option;
import com.lanyuanxiaoyao.bookstore.service.BookService;
import com.lanyuanxiaoyao.bookstore.service.ChapterService;
@@ -8,11 +10,15 @@ import com.lanyuanxiaoyao.bookstore.service.LineService;
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
import java.time.LocalDateTime;
+import java.util.Comparator;
import java.util.List;
+import java.util.Map;
import java.util.function.Function;
+import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
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;
@@ -43,7 +49,7 @@ public class ChapterController extends SimpleControllerSupport saveWithContent(@RequestBody SaveWithContentItem item) {
if (SaveWithContentItem.Mode.CREATE.equals(item.mode())) {
var chapter = new Chapter();
- chapter.setSequence(chapterService.latestSequence(item.bookId()));
+ chapter.setSequence(chapterService.latestSequence(item.bookId()) + 1);
chapter.setName(item.name());
chapter.setDescription(item.description());
chapter.setBook(bookService.detailOrThrow(item.bookId()));
@@ -62,6 +68,18 @@ public class ChapterController extends SimpleControllerSupport> content(@PathVariable("chapter_id") Long chapterId) {
+ var chapter = chapterService.detailOrThrow(chapterId);
+ return GlobalResponse.responseDetailData(
+ chapter.getContent()
+ .stream()
+ .sorted(Comparator.comparing(Line::getSequence))
+ .map(Line::getText)
+ .collect(Collectors.joining("\n"))
+ );
+ }
+
@GetMapping("generate_sequence")
public GlobalResponse