diff --git a/client/src/index.tsx b/client/src/index.tsx
index 9aaf20a..590a8ad 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -2,7 +2,6 @@ import {createRoot} from 'react-dom/client'
import {createHashRouter, Navigate, type RouteObject, RouterProvider} from 'react-router'
import './index.scss'
import './components/amis/Registry.ts'
-import Overview from './pages/Overview.tsx'
import Root from './pages/Root.tsx'
import Test from './pages/Test.tsx'
import Bookshelf from './pages/book/Bookshelf.tsx'
@@ -16,11 +15,7 @@ const routes: RouteObject[] = [
children: [
{
index: true,
- element: ,
- },
- {
- path: 'overview',
- Component: Overview,
+ element: ,
},
{
path: 'bookshelf',
diff --git a/client/src/pages/Overview.tsx b/client/src/pages/Overview.tsx
deleted file mode 100644
index 2d40eea..0000000
--- a/client/src/pages/Overview.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from 'react'
-
-function Overview() {
- return (
-
- )
-}
-
-export default React.memo(Overview)
\ No newline at end of file
diff --git a/client/src/pages/Root.tsx b/client/src/pages/Root.tsx
index 8cc3c39..8ccf863 100644
--- a/client/src/pages/Root.tsx
+++ b/client/src/pages/Root.tsx
@@ -25,11 +25,6 @@ const menus = {
name: '概览',
icon: ,
routes: [
- {
- path: '/overview',
- name: '概览',
- icon: ,
- },
{
path: '/bookshelf',
name: '书架',
diff --git a/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java b/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
index 9383c59..048d1ae 100644
--- a/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
+++ b/src/main/java/com/lanyuanxiaoyao/bookstore/BookStoreApplication.java
@@ -1,9 +1,22 @@
package com.lanyuanxiaoyao.bookstore;
+import cn.hutool.core.io.FileUtil;
import com.blinkfox.fenix.EnableFenix;
+import com.lanyuanxiaoyao.bookstore.entity.Chapter;
+import com.lanyuanxiaoyao.bookstore.service.BookService;
+import com.lanyuanxiaoyao.bookstore.service.ChapterService;
+import com.lanyuanxiaoyao.bookstore.service.LineService;
+import jakarta.annotation.Resource;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Comparator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.event.EventListener;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
/**
@@ -17,7 +30,43 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@EnableFenix
@EnableConfigurationProperties
public class BookStoreApplication {
+ @Resource
+ private BookService bookService;
+ @Resource
+ private ChapterService chapterService;
+ @Resource
+ private LineService lineService;
+
public static void main(String[] args) {
SpringApplication.run(BookStoreApplication.class, args);
}
+
+ @EventListener(ApplicationReadyEvent.class)
+ public void importIntoDatabase() throws IOException {
+ var items = new ArrayList- ();
+ Files.list(Path.of("out"))
+ .sorted(Comparator.comparing(path -> FileUtil.lastModifiedTime(path.toFile())))
+ .forEach(path -> {
+ try {
+ items.add(new Item(
+ path.getFileName().toString(),
+ Files.readString(path)
+ ));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ for (var item : items) {
+ var chapter = new Chapter();
+ chapter.setSequence(chapterService.latestSequence(3608359126886400L) + 1);
+ chapter.setName(null);
+ chapter.setDescription(null);
+ chapter.setBook(bookService.detailOrThrow(3608359126886400L));
+ var chapterId = chapterService.save(chapter);
+ lineService.load(chapterId, item.content());
+ }
+ }
+
+ private record Item(String title, String content) {
+ }
}
diff --git a/src/test/java/com/lanyuanxiaoyao/bookstore/BookCrawlerTest.java b/src/test/java/com/lanyuanxiaoyao/bookstore/BookCrawlerTest.java
index 4c6399b..2bff83f 100644
--- a/src/test/java/com/lanyuanxiaoyao/bookstore/BookCrawlerTest.java
+++ b/src/test/java/com/lanyuanxiaoyao/bookstore/BookCrawlerTest.java
@@ -23,10 +23,10 @@ public class BookCrawlerTest {
try {
driver = new ChromeDriver(
new ChromeDriverService.Builder()
- .usingDriverExecutable(new File("/Users/lanyuanxiaoyao/Downloads/chromium/134/macOS-1345775/chromedriver"))
+ .usingDriverExecutable(new File("/Users/lanyuanxiaoyao/SynologyDrive/tools/chromium/134/macOS-1345775/chromedriver"))
.build(),
new ChromeOptions()
- .setBinary(new File("/Users/lanyuanxiaoyao/Downloads/chromium/134/macOS-1345775/Chromium.app/Contents/MacOS/Chromium"))
+ .setBinary(new File("/Users/lanyuanxiaoyao/SynologyDrive/tools/chromium/134/macOS-1345775/Chromium.app/Contents/MacOS/Chromium"))
.addArguments(
// 允许不安全的域名
"--allow-insecure-localhost",
@@ -58,7 +58,7 @@ public class BookCrawlerTest {
"blink-settings=imagesEnabled=false"
)
);
- var articleUrl = "https://www.alicesw.com/novel/33927.html";
+ var articleUrl = "https://www.alicesw.com/novel/32007.html";
driver.get(articleUrl);
var contextUrl = driver.findElement(By.xpath("//div[@class='book_newchap']//a[contains(text(),'查看所有章节')]")).getDomProperty("href");
if (StrUtil.isBlank(contextUrl)) {
@@ -83,12 +83,12 @@ public class BookCrawlerTest {
title = String.valueOf(index);
}
var filename = StrUtil.format("{}.txt", title.replaceAll("\\s", "_"));
- var targetFile = Path.of("out", filename);
+ var targetFile = Path.of("out2", filename);
Files.deleteIfExists(targetFile);
Files.createFile(targetFile);
Files.writeString(targetFile, text);
- ThreadUtil.safeSleep(5000);
+ ThreadUtil.safeSleep(2000);
}
} finally {
if (driver != null) {
diff --git a/src/test/java/com/lanyuanxiaoyao/bookstore/UpdateIntoDatabase.java b/src/test/java/com/lanyuanxiaoyao/bookstore/UpdateIntoDatabase.java
index 94dc38e..f8a29bc 100644
--- a/src/test/java/com/lanyuanxiaoyao/bookstore/UpdateIntoDatabase.java
+++ b/src/test/java/com/lanyuanxiaoyao/bookstore/UpdateIntoDatabase.java
@@ -1,9 +1,18 @@
package com.lanyuanxiaoyao.bookstore;
-import cn.hutool.ai.AIUtil;
-import cn.hutool.ai.ModelName;
-import cn.hutool.ai.core.AIConfigBuilder;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.db.dialect.impl.MysqlDialect;
+import com.lanyuanxiaoyao.service.template.helper.SnowflakeIdGenerator;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Comparator;
import lombok.extern.slf4j.Slf4j;
/**
@@ -14,8 +23,8 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
public class UpdateIntoDatabase {
- public static void main(String[] args) throws IOException {
- /*var chapters = new ArrayList();
+ public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
+ var chapters = new ArrayList();
Files.list(Path.of("out"))
.sorted(Comparator.comparing(path -> FileUtil.lastModifiedTime(path.toFile())))
.forEach(path -> {
@@ -28,10 +37,69 @@ public class UpdateIntoDatabase {
throw new RuntimeException(e);
}
});
- for (var chapter : chapters) {
- log.info("name: {}", chapter.title());
- }*/
- var response = AIUtil.chat(
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ try (
+ var connection = DriverManager.getConnection(
+ "jdbc:mysql://mysql.lanyuanxiaoyao.com:43780/bookstore?useUnicode=true&characterEncoding=utf8&useSSL=false",
+ "bookstore",
+ "EzSn+RZ*x2&fHFh9kC+H"
+ )
+ /*var ds = new SimpleDataSource(
+ "jdbc:mysql://mysql.lanyuanxiaoyao.com:43780/bookstore?useUnicode=true&characterEncoding=utf8&useSSL=false",
+ "bookstore",
+ "EzSn+RZ*x2&fHFh9kC+H",
+ "com.mysql.cj.jdbc.Driver"
+ )*/
+ ) {
+ var dialect = new MysqlDialect();
+ for (int index = 0; index < chapters.size(); index++) {
+ var chapter = chapters.get(index);
+ log.info("Chapter: {}", chapter.title());
+ var now = LocalDateTime.now();
+ var chapterId = SnowflakeIdGenerator.Snowflake.next();
+ /*Db.use(ds, dialect).insert(
+ Entity.create("bookstore_chapter")
+ .set("id", chapterId)
+ .set("created_time", now)
+ .set("modified_time", now)
+ .set("sequence", index)
+ .set("book_id", 3608359126886400L)
+ );*/
+ try (var statement = connection.prepareStatement("insert into bookstore_chapter(id,created_time,modified_time,sequence,book_id) values(?,current_timestamp(),current_timestamp(),?,?)")) {
+ statement.setLong(1, chapterId);
+ statement.setDouble(2, index);
+ statement.setLong(3, 3608359126886400L);
+ statement.execute();
+ }
+ var lines = StrUtil.split(chapter.content, "\n")
+ .stream()
+ .map(StrUtil::trimToNull)
+ .filter(ObjectUtil::isNotNull)
+ .toList();
+ // var entities = new ArrayList();
+ for (int lineIndex = 0; lineIndex < lines.size(); lineIndex++) {
+ /*entities.add(
+ Entity.create("bookstore_line")
+ .set("id", SnowflakeIdGenerator.Snowflake.next())
+ .set("created_time", now)
+ .set("modified_time", now)
+ .set("sequence", lineIndex)
+ .set("text", lines.get(lineIndex))
+ .set("chapter_id", chapterId)
+ );*/
+ try (var statement = connection.prepareStatement("insert into bookstore_line(id,created_time,modified_time,sequence,text,chapter_id) values(?,current_timestamp(),current_timestamp(),?,?,?)")) {
+ statement.setLong(1, SnowflakeIdGenerator.Snowflake.next());
+ statement.setDouble(2, lineIndex);
+ statement.setString(3, lines.get(lineIndex));
+ statement.setLong(4, chapterId);
+ statement.execute();
+ }
+ }
+ // Db.use(ds, dialect).insert(entities);
+ }
+ }
+
+ /*var response = AIUtil.chat(
new AIConfigBuilder(ModelName.OPENAI.getValue())
.setApiUrl("http://127.0.0.1:30000")
.setApiKey("*XMySqV%>hR&v>>g*NwCs3tpQ5FVMFEF2VHVTj