Browse Source

1.图书管理页优化

1 1 day ago
parent
commit
2f23015b3d

+ 5 - 2
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/controller/cms/books/BookViewController.java

@@ -1,7 +1,9 @@
 package top.imwork.window.silos.controller.cms.books;
 
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 /**
@@ -47,8 +49,9 @@ public class BookViewController {
         return "/cms/book/contents/edit";
     }
 
-    @GetMapping("/chapter/chapter.html")
-    public String chapter() {
+    @GetMapping("/chapter/chapter.html/{id}")
+    public String chapter(@PathVariable("id") Long id, Model model) {
+        model.addAttribute("bookId", id);
         return "/cms/book/chapter/chapter";
     }
 }

+ 3 - 0
imwork-windows/imwork-silos/src/main/java/top/imwork/window/silos/service/impl/ContentsServiceImpl.java

@@ -81,6 +81,9 @@ public class ContentsServiceImpl extends ServiceImpl<ContentsDao,Contents> imple
                     .like("book_info_id", contentsListDTO.getContentsName()).or()
                     .like("chapter_number", contentsListDTO.getContentsName());
         }
+        if (!StringUtils.isEmpty(contentsListDTO.getBookInfoId())) {
+            queryWrapper.like("book_info_id", contentsListDTO.getBookInfoId());
+        }
         if (!StringUtils.isEmpty(contentsListDTO.getContentType())) {
             queryWrapper.like("content_type", contentsListDTO.getContentType());
         }

+ 403 - 0
imwork-windows/imwork-silos/src/main/resources/static/business/cms/book/chapter/chapter.js

@@ -0,0 +1,403 @@
+layui.config({
+    base: '/assets/lib/jplus/treeTable/'
+}).use(['form', 'layer', 'table', 'laytpl', 'treeTable'], function () {
+    var form = layui.form,
+        layer = parent.layer === undefined ? layui.layer : top.layer,
+        $ = layui.jquery,
+        laytpl = layui.laytpl,
+        table = layui.table,
+        treeTable = layui.treeTable;
+
+    // 状态管理
+    const state = {
+        currentChapterIndex: 0,
+        fontSize: 'medium',
+        theme: 'light',
+        lineHeight: 'normal',
+        fontFamily: 'system',
+        chapters: [],
+        isChaptersLoaded: false, // 新增:标记章节是否已加载
+        isRendering: false // 新增:防止重复渲染
+    };
+
+    // 配置常量
+    const CONFIG = {
+        table: {
+            elem: '#list',
+            url: '/silos/cms/book/contents/queryPage',
+            method: 'POST',
+            contentType: 'application/json;charset=utf-8',
+            page: true,
+            limits: [10, 15, 20, 25],
+            limit: 15,
+            id: "listTable",
+            request: {
+                pageName: "pageNo",
+                limitName: "pageRows"
+            },
+            response: {
+                statusName: 'code',
+                statusCode: 200,
+                msgName: 'msg',
+                countName: 'totalRows',
+                dataName: 'data'
+            }
+        },
+        grid: {
+            pageNo: 1,
+            pageRows: 100
+        }
+    };
+
+    // DOM 元素缓存
+    const DOM = {
+        chaptersList: document.getElementById('chaptersList'),
+        chapterNumberDisplay: document.getElementById('chapterNumberDisplay'),
+        chapterTitleDisplay: document.getElementById('chapterTitleDisplay'),
+        chapterContent: document.getElementById('chapterContent'),
+        readingArea: document.getElementById('readingArea'),
+        toggleSidebar: document.getElementById('toggleSidebar'),
+        prevChapter: document.getElementById('prevChapter'),
+        nextChapter: document.getElementById('nextChapter'),
+        prevNavBtn: document.getElementById('prevNavBtn'),
+        nextNavBtn: document.getElementById('nextNavBtn'),
+        settingsBtn: document.getElementById('settingsBtn'),
+        closeSettings: document.getElementById('closeSettings'),
+        fontSelect: document.getElementById('fontSelect'),
+        bookmarkBtn: document.getElementById('bookmarkBtn'),
+        searchBtn: document.getElementById('searchBtn'),
+        progressPercent: document.getElementById('progressPercent'),
+        sidebar: document.getElementById('sidebar'),
+        mainContent: document.getElementById('mainContent'),
+        settingsPanel: document.getElementById('settingsPanel')
+    };
+
+    // 工具函数
+    const utils = {
+        showError: function(title, msg) {
+            console.error(title, msg);
+            // 这里可以添加更友好的错误提示,如使用layer
+        },
+
+        getFontFamily: function(font) {
+            const fontMap = {
+                'serif': "'Noto Serif SC', 'Times New Roman', serif",
+                'sans-serif': "'Segoe UI', 'Microsoft YaHei', sans-serif",
+                'monospace': "'Courier New', monospace",
+                'system': "system-ui, -apple-system, sans-serif"
+            };
+            return fontMap[font] || fontMap.system;
+        },
+
+        debounce: function(func, wait) {
+            let timeout;
+            return function executedFunction(...args) {
+                const later = () => {
+                    clearTimeout(timeout);
+                    func(...args);
+                };
+                clearTimeout(timeout);
+                timeout = setTimeout(later, wait);
+            };
+        }
+    };
+
+    // 章节管理
+    const chapterManager = {
+        // 加载章节数据
+        loadChapters: function() {
+            if (state.isChaptersLoaded) {
+                return Promise.resolve(state.chapters);
+            }
+
+            const requestData = $.extend({}, CONFIG.grid, {
+                bookInfoId: $('#bookId').val()
+            });
+
+            return new Promise((resolve, reject) => {
+                $.ajax({
+                    url: "/silos/cms/book/contents/queryPage",
+                    type: "POST",
+                    dataType: "json",
+                    contentType: 'application/json;charset=UTF-8',
+                    data: JSON.stringify(requestData),
+                    success: function (res) {
+                        if (res.code === 200) {
+                            state.chapters = res.data.dataList.map(chapter => ({
+                                id: chapter.id,
+                                number: chapter.chapterNumber,
+                                title: chapter.chapterTitle,
+                                content: chapter.contentHtml
+                            }));
+                            state.isChaptersLoaded = true;
+                            resolve(state.chapters);
+                        } else {
+                            utils.showError("加载失败", res.msg);
+                            reject(res.msg);
+                        }
+                    },
+                    error: function (xhr, status, error) {
+                        console.error("请求失败:", error);
+                        utils.showError("请求失败", "网络错误或服务器异常");
+                        reject(error);
+                    }
+                });
+            });
+        },
+
+        // 渲染章节列表(只渲染一次,后续只更新激活状态)
+        renderChaptersList: function() {
+            if (state.isRendering || !state.isChaptersLoaded) return;
+
+            state.isRendering = true;
+
+            DOM.chaptersList.innerHTML = state.chapters.map((chapter, index) => `
+                <div class="chapter-item ${index === state.currentChapterIndex ? 'active' : ''}" 
+                     data-index="${index}">
+                    <div class="chapter-number">${chapter.number}</div>
+                    <div class="chapter-title">${chapter.title}</div>
+                </div>
+            `).join('');
+
+            state.isRendering = false;
+        },
+
+        // 更新章节激活状态(避免重新渲染整个列表)
+        updateActiveChapter: function() {
+            if (!DOM.chaptersList) return;
+
+            // 移除所有激活状态
+            const items = DOM.chaptersList.querySelectorAll('.chapter-item');
+            items.forEach(item => item.classList.remove('active'));
+
+            // 添加当前激活状态
+            const currentItem = DOM.chaptersList.querySelector(`.chapter-item[data-index="${state.currentChapterIndex}"]`);
+            if (currentItem) {
+                currentItem.classList.add('active');
+
+                // 确保激活的章节在可视区域内
+                currentItem.scrollIntoView({
+                    behavior: 'smooth',
+                    block: 'nearest'
+                });
+            }
+        },
+
+        // 显示指定章节
+        showChapter: function(index) {
+            if (index < 0 || index >= state.chapters.length) return;
+
+            state.currentChapterIndex = index;
+            const chapter = state.chapters[index];
+
+            // 更新显示内容
+            DOM.chapterNumberDisplay.textContent = chapter.number;
+            DOM.chapterTitleDisplay.textContent = chapter.title;
+            DOM.chapterContent.innerHTML = chapter.content;
+
+            // 更新导航按钮状态
+            DOM.prevNavBtn.disabled = index === 0;
+            DOM.nextNavBtn.disabled = index === state.chapters.length - 1;
+
+            // 更新章节列表激活状态(不重新渲染整个列表)
+            chapterManager.updateActiveChapter();
+
+            // 更新阅读进度
+            chapterManager.updateProgress();
+        },
+
+        // 更新阅读进度
+        updateProgress: function() {
+            const progress = ((state.currentChapterIndex + 1) / state.chapters.length * 100).toFixed(0);
+            DOM.progressPercent.textContent = `${progress}%`;
+        }
+    };
+
+    // 阅读设置管理
+    const settingsManager = {
+        // 应用阅读设置
+        applyReadingSettings: function() {
+            // 字体大小
+            DOM.readingArea.className = DOM.readingArea.className.replace(/\bfont-\w+\b/g, '');
+            DOM.readingArea.classList.add(`font-${state.fontSize}`);
+
+            // 主题
+            document.body.className = document.body.className.replace(/\btheme-\w+\b/g, '');
+            document.body.classList.add(`theme-${state.theme}`);
+            if (state.theme === 'dark') {
+                document.body.classList.add('dark-mode');
+            } else {
+                document.body.classList.remove('dark-mode');
+            }
+
+            // 行高
+            DOM.readingArea.className = DOM.readingArea.className.replace(/\bline-\w+\b/g, '');
+            DOM.readingArea.classList.add(`line-${state.lineHeight}`);
+
+            // 字体
+            DOM.chapterContent.style.fontFamily = utils.getFontFamily(state.fontFamily);
+        },
+
+        // 初始化设置面板
+        initSettingsPanel: function() {
+            // 字体大小设置
+            document.querySelectorAll('.font-size-btn').forEach(btn => {
+                btn.addEventListener('click', function() {
+                    document.querySelectorAll('.font-size-btn').forEach(b => b.classList.remove('active'));
+                    this.classList.add('active');
+                    state.fontSize = this.getAttribute('data-size');
+                    settingsManager.applyReadingSettings();
+                });
+            });
+
+            // 主题设置
+            document.querySelectorAll('.theme-btn').forEach(btn => {
+                btn.addEventListener('click', function() {
+                    document.querySelectorAll('.theme-btn').forEach(b => b.classList.remove('active'));
+                    this.classList.add('active');
+                    state.theme = this.getAttribute('data-theme');
+                    settingsManager.applyReadingSettings();
+                });
+            });
+
+            // 行高设置
+            document.querySelectorAll('[data-lineheight]').forEach(btn => {
+                btn.addEventListener('click', function() {
+                    document.querySelectorAll('[data-lineheight]').forEach(b => b.classList.remove('active'));
+                    this.classList.add('active');
+                    state.lineHeight = this.getAttribute('data-lineheight');
+                    settingsManager.applyReadingSettings();
+                });
+            });
+
+            // 字体设置
+            DOM.fontSelect.addEventListener('change', function() {
+                state.fontFamily = this.value;
+                settingsManager.applyReadingSettings();
+            });
+        }
+    };
+
+    // 事件处理
+    const eventHandler = {
+        initEvents: function() {
+            // 切换侧边栏
+            DOM.toggleSidebar.addEventListener('click', function() {
+                DOM.sidebar.classList.toggle('collapsed');
+                DOM.mainContent.classList.toggle('expanded');
+            });
+
+            // 章节导航
+            DOM.prevChapter.addEventListener('click', () => {
+                if (state.currentChapterIndex > 0) {
+                    chapterManager.showChapter(state.currentChapterIndex - 1);
+                }
+            });
+
+            DOM.nextChapter.addEventListener('click', () => {
+                if (state.currentChapterIndex < state.chapters.length - 1) {
+                    chapterManager.showChapter(state.currentChapterIndex + 1);
+                }
+            });
+
+            DOM.prevNavBtn.addEventListener('click', () => {
+                if (state.currentChapterIndex > 0) {
+                    chapterManager.showChapter(state.currentChapterIndex - 1);
+                }
+            });
+
+            DOM.nextNavBtn.addEventListener('click', () => {
+                if (state.currentChapterIndex < state.chapters.length - 1) {
+                    chapterManager.showChapter(state.currentChapterIndex + 1);
+                }
+            });
+
+            // 章节列表点击事件(使用事件委托)
+            DOM.chaptersList.addEventListener('click', utils.debounce(function(e) {
+                const chapterItem = e.target.closest('.chapter-item');
+                if (chapterItem) {
+                    const index = parseInt(chapterItem.getAttribute('data-index'));
+                    chapterManager.showChapter(index);
+
+                    // 在移动端点击章节后自动关闭侧边栏
+                    if (window.innerWidth <= 768) {
+                        DOM.sidebar.classList.remove('open');
+                    }
+                }
+            }, 100));
+
+            // 设置面板
+            DOM.settingsBtn.addEventListener('click', function() {
+                DOM.settingsPanel.classList.add('open');
+            });
+
+            DOM.closeSettings.addEventListener('click', function() {
+                DOM.settingsPanel.classList.remove('open');
+            });
+
+            // 书签功能
+            DOM.bookmarkBtn.addEventListener('click', function() {
+                const chapter = state.chapters[state.currentChapterIndex];
+                layer.msg(`已将 "${chapter.number} ${chapter.title}" 添加到书签`);
+            });
+
+            // 搜索功能
+            DOM.searchBtn.addEventListener('click', function() {
+                layer.msg('搜索功能即将推出');
+            });
+        }
+    };
+
+    // 添加CSS类来处理字体大小和行高
+    const addStyle = function() {
+        const style = document.createElement('style');
+        style.textContent = `
+            .font-small { font-size: 0.9rem; }
+            .font-medium { font-size: 1.1rem; }
+            .font-large { font-size: 1.3rem; }
+            .font-xlarge { font-size: 1.5rem; }
+
+            .line-tight { line-height: 1.5; }
+            .line-normal { line-height: 1.8; }
+            .line-loose { line-height: 2.2; }
+
+            @media (max-width: 768px) {
+                .font-small { font-size: 0.85rem; }
+                .font-medium { font-size: 1rem; }
+                .font-large { font-size: 1.15rem; }
+                .font-xlarge { font-size: 1.3rem; }
+            }
+        `;
+        document.head.appendChild(style);
+    };
+
+    // 初始化
+    const init = function() {
+        addStyle();
+
+        // 加载章节数据
+        chapterManager.loadChapters()
+            .then(() => {
+                // 渲染章节列表(只执行一次)
+                chapterManager.renderChaptersList();
+
+                // 显示第一个章节
+                if (state.chapters.length > 0) {
+                    chapterManager.showChapter(0);
+                }
+
+                // 应用初始设置
+                settingsManager.applyReadingSettings();
+            })
+            .catch(error => {
+                console.error('初始化失败:', error);
+            });
+
+        // 初始化事件
+        eventHandler.initEvents();
+        settingsManager.initSettingsPanel();
+    };
+
+    // 启动初始化
+    init();
+});

+ 2 - 2
imwork-windows/imwork-silos/src/main/resources/static/business/cms/book/contents/list.js

@@ -10,7 +10,7 @@ layui.config({
     //用户列表
     var tableIns = table.render({
         elem: '#list',
-        url: '/silos/cms/books/contents/queryPage',
+        url: '/silos/cms/book/contents/queryPage',
         method: 'POST',
         dataType: 'json',
         contentType: 'application/json;charset=utf-8',
@@ -121,7 +121,7 @@ layui.config({
         const index = layui.layer.open({
             title: title,
             type: 2,
-            content: "/silos/cms/books/contents/edit.html",
+            content: "/silos/cms/book/contents/edit.html",
             scrollbar: false,
             success: function (layero, index) {
                 var body = layui.layer.getChildFrame('body', index);

+ 2 - 2
imwork-windows/imwork-silos/src/main/resources/static/business/cms/book/info/list.js

@@ -120,7 +120,7 @@ layui.config({
             var initials = book.title ? book.title.substring(0, 2) : '??';
 
             return `
-                <div class="book-card" data-id="${book.id}" data-title="${book.title || ''}">
+                <div class="book-card" data-id="${book.isbn}" data-title="${book.title || ''}">
                     <div class="book-cover" style="background-color: ${coverColor}">
                         <span style="color: white; font-weight: bold; font-size: 1.5rem;">${initials}</span>
                     </div>
@@ -283,7 +283,7 @@ layui.config({
             shadeClose: true,
             shade: 0.8,
             area: ['100%', '100%'],
-            content: '/silos/cms/book/chapter/chapter.html'
+            content: '/silos/cms/book/chapter/chapter.html/'+bookId
         });
     }
 

+ 11 - 340
imwork-windows/imwork-silos/src/main/resources/templates/cms/book/chapter/chapter.html

@@ -9,15 +9,17 @@
     <link rel="stylesheet" href="../../../../static/assets/lib/layui/css/layui.css" th:href="@{/assets/lib/layui/css/layui.css}"/>
     <link rel="stylesheet" href="../../../../static/assets/lib/fonts/fontawesome6/css/all.min.css" th:href="@{/assets/lib/fonts/fontawesome6/css/all.min.css}"/>
     <link rel="stylesheet" href="../../../../static/business/cms/book/chapter/chapter.css" th:href="@{/business/cms/book/chapter/chapter.css}"/>
+
 </head>
 <body>
 <div class="container">
     <!-- 侧边栏 -->
     <div class="sidebar" id="sidebar">
         <div class="book-info">
-            <div class="book-cover">设计</div>
+            <input type="hidden" th:value="${bookId}" id="bookId"/>
+            <!--<div class="book-cover">设计</div>
             <div class="book-title">网页设计与开发实战</div>
-            <div class="book-author">作者:张明</div>
+            <div class="book-author">作者:张明</div>-->
         </div>
 
         <div class="chapters-nav">
@@ -72,10 +74,10 @@
             <div class="chapter-header">
                 <div class="chapter-number-display" id="chapterNumberDisplay">第一章</div>
                 <h1 class="chapter-title-display" id="chapterTitleDisplay">HTML基础</h1>
-                <div class="chapter-meta">
+                <!--<div class="chapter-meta">
                     <span>字数:5200</span>
                     <span>阅读时间:约15分钟</span>
-                </div>
+                </div>-->
             </div>
 
             <div class="chapter-content" id="chapterContent">
@@ -87,7 +89,7 @@
         <div class="chapter-nav">
             <button class="nav-btn" id="prevNavBtn">
                 <i class="fas fa-chevron-left"></i>
-                <span>上一章:无</span>
+                <span>上一章:</span>
             </button>
 
             <div class="progress">
@@ -95,7 +97,7 @@
             </div>
 
             <button class="nav-btn" id="nextNavBtn">
-                <span>下一章:CSS样式</span>
+                <span>下一章:</span>
                 <i class="fas fa-chevron-right"></i>
             </button>
         </div>
@@ -155,339 +157,8 @@
         </div>
     </div>
 </div>
-
-<script>
-    // 示例章节数据
-    const chapters = [
-        {
-            id: 1,
-            number: "第一章",
-            title: "HTML基础",
-            content: `
-                    <h2>什么是HTML</h2>
-                    <p>HTML(HyperText Markup Language)是用于创建网页的标准标记语言。它描述了网页的结构,由一系列元素组成,这些元素告诉浏览器如何显示内容。</p>
-
-                    <h2>HTML文档结构</h2>
-                    <p>一个基本的HTML文档包含以下结构:</p>
-                    <pre><code>&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-&lt;head&gt;
-    &lt;title&gt;页面标题&lt;/title&gt;
-&lt;/head&gt;
-&lt;body&gt;
-    &lt;h1&gt;我的第一个标题&lt;/h1&gt;
-    &lt;p&gt;我的第一个段落&lt;/p&gt;
-&lt;/body&gt;
-&lt;/html&gt;</code></pre>
-
-                    <h2>常用HTML标签</h2>
-                    <p>HTML提供了多种标签来定义不同类型的内容:</p>
-                    <ul>
-                        <li><code>&lt;h1&gt; - &lt;h6&gt;</code>:标题标签</li>
-                        <li><code>&lt;p&gt;</code>:段落标签</li>
-                        <li><code>&lt;a&gt;</code>:链接标签</li>
-                        <li><code>&lt;img&gt;</code>:图像标签</li>
-                        <li><code>&lt;div&gt;</code>:分区标签</li>
-                    </ul>
-
-                    <blockquote>
-                        <p>HTML是Web的基石,所有网页都建立在HTML之上。掌握HTML是学习Web开发的第一步。</p>
-                    </blockquote>
-
-                    <h2>HTML5新特性</h2>
-                    <p>HTML5引入了许多新元素和API,使Web开发更加强大:</p>
-                    <ul>
-                        <li>语义化元素:<code>&lt;header&gt;</code>, <code>&lt;footer&gt;</code>, <code>&lt;article&gt;</code>, <code>&lt;section&gt;</code></li>
-                        <li>多媒体支持:<code>&lt;audio&gt;</code>, <code>&lt;video&gt;</code></li>
-                        <li>Canvas绘图</li>
-                        <li>本地存储</li>
-                        <li>地理位置API</li>
-                    </ul>
-                `
-        },
-        {
-            id: 2,
-            number: "第二章",
-            title: "CSS样式",
-            content: `
-                    <h2>CSS简介</h2>
-                    <p>CSS(Cascading Style Sheets)用于描述HTML元素的显示方式,它可以控制网页的布局、颜色、字体等外观特性。</p>
-
-                    <h2>CSS语法</h2>
-                    <p>CSS规则由选择器和声明块组成:</p>
-                    <pre><code>选择器 {
-    属性: 值;
-    属性: 值;
-}</code></pre>
-
-                    <h2>CSS选择器</h2>
-                    <p>CSS选择器用于选择要样式化的HTML元素:</p>
-                    <ul>
-                        <li>元素选择器:<code>p { color: blue; }</code></li>
-                        <li>类选择器:<code>.className { font-size: 16px; }</code></li>
-                        <li>ID选择器:<code>#idName { margin: 0; }</code></li>
-                        <li>后代选择器:<code>div p { line-height: 1.5; }</code></li>
-                    </ul>
-
-                    <h2>盒模型</h2>
-                    <p>CSS盒模型是Web布局的基础概念,每个元素都被视为一个矩形盒子,包含内容、内边距、边框和外边距。</p>
-
-                    <blockquote>
-                        <p>CSS让网页从简单的文档转变为视觉上吸引人的用户体验。</p>
-                    </blockquote>
-                `
-        },
-        {
-            id: 3,
-            number: "第三章",
-            title: "JavaScript编程",
-            content: `
-                    <h2>JavaScript概述</h2>
-                    <p>JavaScript是一种轻量级的解释型编程语言,主要用于Web开发,可以为网页添加交互功能。</p>
-
-                    <h2>变量和数据类型</h2>
-                    <p>JavaScript中的变量使用<code>var</code>, <code>let</code>或<code>const</code>声明:</p>
-                    <pre><code>let name = "张三";
-const age = 25;
-var isStudent = true;</code></pre>
-
-                    <h2>函数</h2>
-                    <p>函数是JavaScript中的基本构建块,用于执行特定任务:</p>
-                    <pre><code>function greet(name) {
-    return "Hello, " + name + "!";
-}
-
-// 箭头函数
-const add = (a, b) => a + b;</code></pre>
-
-                    <h2>DOM操作</h2>
-                    <p>JavaScript可以通过DOM(文档对象模型)与HTML元素交互:</p>
-                    <pre><code>// 获取元素
-const element = document.getElementById("myElement");
-
-// 修改内容
-element.innerHTML = "新内容";
-
-// 添加事件监听器
-element.addEventListener("click", function() {
-    alert("元素被点击了!");
-});</code></pre>
-                `
-        }
-    ];
-
-    let currentChapterIndex = 0;
-    let fontSize = 'medium';
-    let theme = 'light';
-    let lineHeight = 'normal';
-    let fontFamily = 'system';
-
-    // 生成章节列表
-    function renderChaptersList() {
-        const chaptersList = document.getElementById('chaptersList');
-        chaptersList.innerHTML = chapters.map((chapter, index) => `
-                <div class="chapter-item ${index === currentChapterIndex ? 'active' : ''}" data-index="${index}">
-                    <div class="chapter-number">${chapter.number}</div>
-                    <div class="chapter-title">${chapter.title}</div>
-                </div>
-            `).join('');
-    }
-
-    // 显示章节内容
-    function showChapter(index) {
-        if (index < 0 || index >= chapters.length) return;
-
-        currentChapterIndex = index;
-        const chapter = chapters[index];
-
-        document.getElementById('chapterNumberDisplay').textContent = chapter.number;
-        document.getElementById('chapterTitleDisplay').textContent = chapter.title;
-        document.getElementById('chapterContent').innerHTML = chapter.content;
-
-        // 更新导航按钮状态
-        document.getElementById('prevNavBtn').disabled = index === 0;
-        document.getElementById('nextNavBtn').disabled = index === chapters.length - 1;
-
-        // 更新章节列表激活状态
-        renderChaptersList();
-
-        // 更新阅读进度
-        updateProgress();
-    }
-
-    // 更新阅读进度
-    function updateProgress() {
-        const progress = ((currentChapterIndex + 1) / chapters.length * 100).toFixed(0);
-        document.getElementById('progressPercent').textContent = `${progress}%`;
-    }
-
-    // 应用阅读设置
-    function applyReadingSettings() {
-        const readingArea = document.getElementById('readingArea');
-
-        // 字体大小
-        readingArea.className = readingArea.className.replace(/\bfont-\w+\b/g, '');
-        readingArea.classList.add(`font-${fontSize}`);
-
-        // 主题
-        document.body.className = document.body.className.replace(/\btheme-\w+\b/g, '');
-        document.body.classList.add(`theme-${theme}`);
-        if (theme === 'dark') {
-            document.body.classList.add('dark-mode');
-        } else {
-            document.body.classList.remove('dark-mode');
-        }
-
-        // 行高
-        readingArea.className = readingArea.className.replace(/\bline-\w+\b/g, '');
-        readingArea.classList.add(`line-${lineHeight}`);
-
-        // 字体
-        const content = document.getElementById('chapterContent');
-        content.style.fontFamily = getFontFamily(fontFamily);
-    }
-
-    // 获取字体族
-    function getFontFamily(font) {
-        switch(font) {
-            case 'serif': return "'Noto Serif SC', 'Times New Roman', serif";
-            case 'sans-serif': return "'Segoe UI', 'Microsoft YaHei', sans-serif";
-            case 'monospace': return "'Courier New', monospace";
-            default: return "system-ui, -apple-system, sans-serif";
-        }
-    }
-
-    // 初始化页面
-    document.addEventListener('DOMContentLoaded', function() {
-        renderChaptersList();
-        showChapter(currentChapterIndex);
-        applyReadingSettings();
-
-        // 切换侧边栏
-        document.getElementById('toggleSidebar').addEventListener('click', function() {
-            const sidebar = document.getElementById('sidebar');
-            const mainContent = document.getElementById('mainContent');
-
-            sidebar.classList.toggle('collapsed');
-            mainContent.classList.toggle('expanded');
-        });
-
-        // 章节导航
-        document.getElementById('prevChapter').addEventListener('click', function() {
-            if (currentChapterIndex > 0) {
-                showChapter(currentChapterIndex - 1);
-            }
-        });
-
-        document.getElementById('nextChapter').addEventListener('click', function() {
-            if (currentChapterIndex < chapters.length - 1) {
-                showChapter(currentChapterIndex + 1);
-            }
-        });
-
-        document.getElementById('prevNavBtn').addEventListener('click', function() {
-            if (currentChapterIndex > 0) {
-                showChapter(currentChapterIndex - 1);
-            }
-        });
-
-        document.getElementById('nextNavBtn').addEventListener('click', function() {
-            if (currentChapterIndex < chapters.length - 1) {
-                showChapter(currentChapterIndex + 1);
-            }
-        });
-
-        // 章节列表点击事件
-        document.getElementById('chaptersList').addEventListener('click', function(e) {
-            const chapterItem = e.target.closest('.chapter-item');
-            if (chapterItem) {
-                const index = parseInt(chapterItem.getAttribute('data-index'));
-                showChapter(index);
-
-                // 在移动端点击章节后自动关闭侧边栏
-                if (window.innerWidth <= 768) {
-                    document.getElementById('sidebar').classList.remove('open');
-                }
-            }
-        });
-
-        // 设置面板
-        document.getElementById('settingsBtn').addEventListener('click', function() {
-            document.getElementById('settingsPanel').classList.add('open');
-        });
-
-        document.getElementById('closeSettings').addEventListener('click', function() {
-            document.getElementById('settingsPanel').classList.remove('open');
-        });
-
-        // 字体大小设置
-        document.querySelectorAll('.font-size-btn').forEach(btn => {
-            btn.addEventListener('click', function() {
-                document.querySelectorAll('.font-size-btn').forEach(b => b.classList.remove('active'));
-                this.classList.add('active');
-                fontSize = this.getAttribute('data-size');
-                applyReadingSettings();
-            });
-        });
-
-        // 主题设置
-        document.querySelectorAll('.theme-btn').forEach(btn => {
-            btn.addEventListener('click', function() {
-                document.querySelectorAll('.theme-btn').forEach(b => b.classList.remove('active'));
-                this.classList.add('active');
-                theme = this.getAttribute('data-theme');
-                applyReadingSettings();
-            });
-        });
-
-        // 行高设置
-        document.querySelectorAll('[data-lineheight]').forEach(btn => {
-            btn.addEventListener('click', function() {
-                document.querySelectorAll('[data-lineheight]').forEach(b => b.classList.remove('active'));
-                this.classList.add('active');
-                lineHeight = this.getAttribute('data-lineheight');
-                applyReadingSettings();
-            });
-        });
-
-        // 字体设置
-        document.getElementById('fontSelect').addEventListener('change', function() {
-            fontFamily = this.value;
-            applyReadingSettings();
-        });
-
-        // 书签功能
-        document.getElementById('bookmarkBtn').addEventListener('click', function() {
-            const chapter = chapters[currentChapterIndex];
-            alert(`已将 "${chapter.number} ${chapter.title}" 添加到书签`);
-        });
-
-        // 搜索功能
-        document.getElementById('searchBtn').addEventListener('click', function() {
-            alert('搜索功能即将推出');
-        });
-    });
-
-    // 添加CSS类来处理字体大小和行高
-    const style = document.createElement('style');
-    style.textContent = `
-            .font-small { font-size: 0.9rem; }
-            .font-medium { font-size: 1.1rem; }
-            .font-large { font-size: 1.3rem; }
-            .font-xlarge { font-size: 1.5rem; }
-
-            .line-tight { line-height: 1.5; }
-            .line-normal { line-height: 1.8; }
-            .line-loose { line-height: 2.2; }
-
-            @media (max-width: 768px) {
-                .font-small { font-size: 0.85rem; }
-                .font-medium { font-size: 1rem; }
-                .font-large { font-size: 1.15rem; }
-                .font-xlarge { font-size: 1.3rem; }
-            }
-        `;
-    document.head.appendChild(style);
-</script>
+<script src="../../../../static/assets/lib/jquery/jquery.js" th:src="@{/assets/lib/jquery/jquery.js}"></script>
+<script src="../../../../static/assets/lib/layui/layui.js" th:src="@{/assets/lib/layui/layui.js}"></script>
+<script src="../../../../static/business/cms/book/chapter/chapter.js" th:src="@{/business/cms/book/chapter/chapter.js}"></script>
 </body>
 </html>