Greasy Fork

Greasy Fork is available in English.

超星学习通高效刷题小助手

一键隐藏超星学习通作业页面中所有答案块,支持单个/全局控制、一键复制题目、富文本笔记编辑(16个格式按钮)、编辑/预览模式切换、完整的按钮样式管理、双按钮导出试题为Word文档(含图片、可选导出内容)、竖屏响应式布局、样式持久化存储。

当前为 2025-12-07 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         超星学习通高效刷题小助手
// @namespace    http://tampermonkey.net/
// @version      2.7.9
// @description  一键隐藏超星学习通作业页面中所有答案块,支持单个/全局控制、一键复制题目、富文本笔记编辑(16个格式按钮)、编辑/预览模式切换、完整的按钮样式管理、双按钮导出试题为Word文档(含图片、可选导出内容)、竖屏响应式布局、样式持久化存储。
// @author       You
// @match        https://*.chaoxing.com/mooc-ans/mooc2/work/view*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=chaoxing.com
// @grant        GM_xmlhttpRequest
// @connect      p.ananas.chaoxing.com
// @connect      chaoxing.com
// @connect      *.chaoxing.com
// @connect      *
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/html-docx.min.js
// @run-at       document-end
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // ===================== 配置管理模块 =====================
    class Config {
        static DEFAULT = {
            // ========== DOM 选择器配置 ==========
            selectors: {
                answerBlock: 'div.mark_answer',    // 答案块的选择器
                container: 'div.topicNumber',      // 题目容器的选择器
                questionItem: 'div.mark_item',     // 题目项的选择器
                sidePanel: 'div.fanyaMarking_right' // 侧边栏容器的选择器
            },

            // ========== 延迟配置 ==========
            delays: {
                initialization: 800  // 脚本初始化延迟时间(毫秒),确保页面加载完成
            },

            // ========== 复制题目按钮配置 ==========
            copyButton: {
                // --- 按钮位置配置(绝对定位到题目右上角) ---
                position: {
                    top: '0px',              // 距离顶部
                    right: '0px'             // 距离右侧
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '12px',        // 字体大小
                    padding: '4px 10px',     // 内边距
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',  // 阴影效果
                    minWidth: '70px',        // 最小宽度(确保"已复制"不会撑开其他按钮)
                    textAlign: 'center'      // 文字居中
                },
                // --- 按钮颜色配置 ---
                colors: {
                    background: '#718096',       // 按钮背景色(灰色)
                    hoverBackground: '#4a5568',  // 悬停背景色
                    successBackground: '#48bb78', // 复制成功背景色(绿色)
                    textColor: 'white',          // 按钮文字颜色
                    hoverOpacity: '0.8'          // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    copy: '复制题目',     // 复制按钮文字
                    copied: '已复制'     // 复制成功文字
                }
            },

            // ========== 单个答案控制按钮配置 ==========
            answerButton: {
                // --- 按钮位置配置 ---
                position: {
                    marginLeft: '10px',      // 按钮左外边距
                    marginRight: '0px',      // 按钮右外边距
                    marginTop: '10px',       // 按钮上外边距
                    marginBottom: '0px',     // 按钮下外边距
                    verticalAlign: 'middle'  // 垂直对齐方式(top/middle/bottom)
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '12px',        // 字体大小
                    padding: '4px 10px',     // 内边距(上下 左右)- 缩小尺寸
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细(normal/bold/100-900)
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    showBackground: '#4299e1',     // "显示答案"按钮背景色(蓝色)
                    hideBackground: '#9f7aea',     // "隐藏答案"按钮背景色(紫色)
                    showHoverBackground: '#3182ce', // "显示答案"悬停背景色
                    hideHoverBackground: '#805ad5', // "隐藏答案"悬停背景色
                    textColor: 'white',            // 按钮文字颜色
                    hoverOpacity: '0.8'            // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    show: '显示答案',   // "显示答案"按钮文字
                    hide: '隐藏答案'    // "隐藏答案"按钮文字
                }
            },

            // ========== 笔记控制按钮配置 ==========
            noteButton: {
                // --- 按钮位置配置 ---
                position: {
                    marginLeft: '5px',       // 按钮左外边距(与答案按钮的间距)
                    marginRight: '0px',      // 按钮右外边距
                    marginTop: '10px',        // 按钮上外边距
                    marginBottom: '0px',     // 按钮下外边距
                    verticalAlign: 'middle'  // 垂直对齐方式
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '12px',        // 字体大小
                    padding: '4px 10px',     // 内边距(上下 左右)- 缩小尺寸
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    showBackground: '#48bb78',     // "显示笔记"按钮背景色(绿色)
                    hideBackground: '#9f7aea',     // "隐藏笔记"按钮背景色(紫色)
                    showHoverBackground: '#38a169', // "显示笔记"悬停背景色
                    hideHoverBackground: '#805ad5', // "隐藏笔记"悬停背景色
                    textColor: 'white',            // 按钮文字颜色
                    hoverOpacity: '0.8'            // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    show: '显示笔记',   // "显示笔记"按钮文字
                    hide: '隐藏笔记'    // "隐藏笔记"按钮文字
                }
            },

            // ========== 保存笔记按钮配置 ==========
            saveNoteButton: {
                // --- 按钮位置配置 ---
                position: {
                    marginLeft: '5px',       // 按钮左外边距(与笔记按钮的间距)
                    marginRight: '0px',      // 按钮右外边距
                    marginTop: '10px',        // 按钮上外边距
                    marginBottom: '0px',     // 按钮下外边距
                    verticalAlign: 'middle'  // 垂直对齐方式
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '12px',        // 字体大小
                    padding: '4px 10px',     // 内边距(上下 左右)- 缩小尺寸
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',  // 阴影效果
                    minWidth: '75px',        // 最小宽度(确保文字变化不会撑开按钮)
                    textAlign: 'center'      // 文字居中
                },
                // --- 按钮颜色配置 ---
                colors: {
                    background: '#38b2ac',   // 按钮背景色(青色)
                    textColor: 'white',      // 按钮文字颜色
                    hoverBackground: '#319795', // 悬停时背景色
                    successBackground: '#48bb78', // 保存成功背景色(绿色)
                    hoverOpacity: '0.8'      // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    save: '💾 保存',        // 保存按钮文字
                    saved: '✅ 已保存'     // 保存成功文字
                }
            },

            // ========== 编辑模式切换按钮配置 ==========
            editModeButton: {
                // --- 按钮位置配置 ---
                position: {
                    marginLeft: '5px',       // 按钮左外边距(与笔记按钮的间距)
                    marginRight: '0px',      // 按钮右外边距
                    marginTop: '10px',       // 按钮上外边距
                    marginBottom: '0px',     // 按钮下外边距
                    verticalAlign: 'middle'  // 垂直对齐方式
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '12px',        // 字体大小
                    padding: '4px 10px',     // 内边距(上下 左右)- 缩小尺寸
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    editBackground: '#48bb78',   // 编辑模式按钮背景色(绿色)
                    previewBackground: '#ed8936', // 预览模式按钮背景色(橙色)
                    editHoverBackground: '#38a169', // 编辑模式悬停背景色
                    previewHoverBackground: '#dd6b20', // 预览模式悬停背景色
                    textColor: 'white',          // 按钮文字颜色
                    hoverOpacity: '0.8'          // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    edit: '编辑',      // 编辑模式按钮文字
                    preview: '预览'   // 预览模式按钮文字
                }
            },

            // ========== 全局控制按钮配置 ==========
            globalButton: {
                // --- 按钮位置配置 ---
                position: {
                    top: '8px',              // 距离容器顶部的距离(在最上方)
                    right: '8px',            // 距离容器右侧的距离
                    zIndex: '9999'           // 层级(确保在最上层)
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '13px',        // 字体大小
                    padding: '6px 12px',     // 内边距
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    showAllBackground: '#4299e1',  // "显示全部答案"按钮背景色(蓝色)
                    hideAllBackground: '#9f7aea',  // "隐藏全部答案"按钮背景色(紫色)
                    showAllHoverBackground: '#3182ce', // "显示全部答案"悬停背景色
                    hideAllHoverBackground: '#805ad5', // "隐藏全部答案"悬停背景色
                    textColor: 'white',            // 按钮文字颜色
                    hoverOpacity: '0.8'            // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: {
                    showAll: '显示全部答案',   // "显示全部答案"按钮文字
                    hideAll: '隐藏全部答案'    // "隐藏全部答案"按钮文字
                }
            },

            // ========== 笔记编辑器配置 ==========
            noteEditor: {
                placeholder: '在这里记录你的笔记...',  // 编辑器占位符文字
                width: '114.5%',                          // 编辑器宽度
                minHeight: '60px',                      // 编辑器最小高度
                maxHeight: '400px',                     // 编辑器最大高度(超出滚动)
                fontSize: '14px',                       // 编辑器字体大小
                padding: '10px',                        // 编辑器内边距
                marginTop: '10px',                      // 编辑器上外边距
                marginBottom: '10px',                   // 编辑器下外边距
                borderRadius: '4px',                    // 编辑器圆角半径
                borderWidth: '1px',                     // 编辑器边框宽度
                borderStyle: 'solid',                   // 编辑器边框样式
                borderColor: '#cbd5e0',                 // 编辑器边框颜色(默认)
                focusBorderColor: '#4299e1',            // 编辑器获得焦点时的边框颜色
                backgroundColor: '#f7fafc',             // 编辑器背景颜色
                textColor: '#2d3748',                   // 编辑器文字颜色
                fontFamily: 'inherit',                  // 编辑器字体(继承父元素)
                resize: 'vertical'                      // 调整大小方式(none/vertical/horizontal/both)
            },

            // ========== 用户设置默认值 ==========
            settings: {
                autoSave: false,                        // 是否开启自动保存(默认关闭)
                autoSaveDelay: 5000                     // 自动保存延迟时间(毫秒)
            },

            // ========== 控制面板按钮配置 ==========
            manageButton: {
                // --- 按钮位置配置 ---
                position: {
                    top: '42px',             // 距离容器顶部的距离(在全局按钮下方)
                    right: '8px',            // 距离容器右侧的距离
                    zIndex: '9999'           // 层级(确保在最上层)
                },
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '13px',        // 字体大小
                    padding: '6px 12px',     // 内边距
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    background: '#ed8936',   // 按钮背景色(橙色)
                    hoverBackground: '#dd6b20', // 悬停背景色
                    textColor: 'white',      // 按钮文字颜色
                    hoverOpacity: '0.8'      // 鼠标悬停时的透明度
                },
                // --- 按钮文字配置 ---
                text: '控制面板'    // 控制面板按钮文字
            },

            // ========== 导出试题按钮配置 ==========
            exportButton: {
                // --- 按钮样式配置 ---
                style: {
                    fontSize: '13px',        // 字体大小
                    padding: '6px 12px',     // 内边距
                    borderRadius: '6px',     // 圆角半径
                    border: 'none',          // 边框样式
                    fontWeight: '500',       // 字体粗细
                    cursor: 'pointer',       // 鼠标样式
                    transition: 'all 0.2s',  // 过渡动画
                    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)'  // 阴影效果
                },
                // --- 按钮颜色配置 ---
                colors: {
                    background: '#38b2ac',   // 按钮背景色(青色)
                    hoverBackground: '#319795', // 悬停背景色
                    textColor: 'white',      // 按钮文字颜色
                    hoverOpacity: '0.8',     // 鼠标悬停时的透明度
                    // 带答案导出按钮颜色
                    withAnswerBackground: '#805ad5',  // 紫色
                    withAnswerHoverBackground: '#6b46c1'
                },
                // --- 按钮文字配置 ---
                text: '📄 导出试题(无答案)',           // 导出按钮文字(不带答案)
                textWithAnswer: '📝 导出试题(含答案)'   // 导出按钮文字(带答案)
            },

            // ========== 控制面板保存按钮配置 ==========
            panelSaveButton: {
                // --- 按钮样式配置 ---
                style: {
                    padding: '10px 24px',       // 内边距(上下 左右)
                    borderRadius: '6px',        // 圆角半径
                    border: 'none',             // 边框样式
                    fontSize: '14px',           // 字体大小
                    fontWeight: '600',          // 字体粗细
                    cursor: 'pointer',          // 鼠标样式
                    transition: 'all 0.2s'      // 过渡动画
                },
                // --- 按钮颜色配置 ---
                colors: {
                    background: '#4299e1',          // 按钮背景色(蓝色)
                    hoverBackground: '#3182ce',     // 悬停时背景色
                    textColor: 'white',             // 按钮文字颜色
                    successBackground: '#48bb78',   // 保存成功背景色(绿色)
                    errorBackground: '#f56565',     // 保存失败背景色(红色)
                    boxShadow: '0 2px 4px rgba(66, 153, 225, 0.3)',           // 默认阴影
                    hoverBoxShadow: '0 4px 6px rgba(66, 153, 225, 0.4)'       // 悬停阴影
                },
                // --- 按钮文字配置 ---
                text: {
                    save: '💾 保存设置',      // 默认文字
                    success: '✅ 保存成功',   // 保存成功文字
                    error: '❌ 保存失败'      // 保存失败文字
                }
            },

            // ========== 导出设置配置 ==========
            exportSettings: {
                // 注意:includeAnswer 已由导出按钮控制,不再从此配置读取
                fontFamily: '宋体',          // 字体
                fontSize: 12,                // 字号(pt)
                titleFontSize: 18,           // 标题字号(pt)
                lineHeight: 1.8,             // 行高
                pageMargin: '2.5cm 2cm 2cm 2cm',  // 页边距
                // 导出内容选项
                exportMyAnswer: true,        // 导出"我的答案"
                exportCorrectAnswer: true,   // 导出"正确答案"
                exportScore: true,           // 导出"本题得分"
                exportAnalysis: true         // 导出"答案解析"
            },

            // ========== 数据库配置 ==========
            database: {
                name: 'ChaoxingNotesDB',     // IndexedDB 数据库名称
                version: 3,                   // 数据库版本号(v3:添加设置存储)
                stores: {
                    notes: 'notes',           // 笔记存储名称
                    attachments: 'attachments', // 附件存储名称
                    settings: 'settings'      // 用户设置存储名称
                }
            },

            // ========== 提示消息配置 ==========
            messages: {
                noAnswerBlocks: 'ℹ️ 未找到答案块(可能页面未完全加载,可刷新重试)',
                noContainer: 'ℹ️ 未找到容器模块,仅启用单个答案块控制功能',
                success: '✅ 超星学习通高效刷题小助手启动成功!',
                hiddenCount: (count) => `- 已为 ${count} 个题目添加答案控制按钮,可自由控制显示/隐藏`,
                globalButton: (hasContainer) => `- ${hasContainer ? '已在右上角添加全局控制按钮' : '未找到容器模块,未添加全局按钮'}`,
                noteSaved: '💾 笔记已自动保存',
                noteLoadError: '⚠️ 加载笔记失败'
            }
        };

        constructor(customConfig = {}) {
            this.config = this._deepMerge(Config.DEFAULT, customConfig);
        }

        get(path) {
            return path.split('.').reduce((obj, key) => obj?.[key], this.config);
        }

        _deepMerge(target, source) {
            const result = { ...target };
            for (const key in source) {
                // 排除函数和数组,只对普通对象进行深度合并
                if (source[key] instanceof Object && 
                    !(source[key] instanceof Function) && 
                    !Array.isArray(source[key]) &&
                    key in target &&
                    target[key] instanceof Object &&
                    !(target[key] instanceof Function) &&
                    !Array.isArray(target[key])) {
                    result[key] = this._deepMerge(target[key], source[key]);
                } else {
                    result[key] = source[key];
                }
            }
            return result;
        }
    }

    // ===================== 日志管理模块 =====================
    class Logger {
        static log(message, type = 'info') {
            const prefix = type === 'error' ? '❌' : type === 'warn' ? '⚠️' : 'ℹ️';
            console.log(`${prefix} ${message}`);
        }

        static success(message) {
            console.log(`✅ ${message}`);
        }

        static error(message, error) {
            console.error(`❌ ${message}`, error);
        }
    }

    // ===================== URL 解析器 =====================
    class URLParser {
        static parseWorkInfo() {
            const url = new URL(window.location.href);
            return {
                courseId: url.searchParams.get('courseId') || '',
                classId: url.searchParams.get('classId') || '',
                workId: url.searchParams.get('workId') || ''
            };
        }

        static getWorkKey() {
            const { courseId, classId, workId } = this.parseWorkInfo();
            return `${courseId}_${classId}_${workId}`;
        }
    }

    // ===================== IndexedDB 管理器 =====================
    class DatabaseManager {
        constructor(config) {
            this.config = config;
            this.db = null;
        }

        async init() {
            return new Promise((resolve, reject) => {
                const request = indexedDB.open(
                    this.config.get('database.name'),
                    this.config.get('database.version')
                );

                request.onerror = () => reject(request.error);
                request.onsuccess = () => {
                    this.db = request.result;
                    resolve(this.db);
                };

                request.onupgradeneeded = (event) => {
                    const db = event.target.result;
                    const oldVersion = event.oldVersion;
                    
                    // 创建或升级笔记存储
                    if (!db.objectStoreNames.contains(this.config.get('database.stores.notes'))) {
                        const notesStore = db.createObjectStore(
                            this.config.get('database.stores.notes'),
                            { keyPath: 'id' }
                        );
                        notesStore.createIndex('workKey', 'workKey', { unique: false });
                        notesStore.createIndex('questionId', 'questionId', { unique: false });
                        notesStore.createIndex('timestamp', 'timestamp', { unique: false });
                    }
                    
                    // v2: 创建附件存储(为未来图片等附件做准备)
                    if (oldVersion < 2 && !db.objectStoreNames.contains(this.config.get('database.stores.attachments'))) {
                        const attachmentsStore = db.createObjectStore(
                            this.config.get('database.stores.attachments'),
                            { keyPath: 'id' }
                        );
                        attachmentsStore.createIndex('noteId', 'noteId', { unique: false });
                        attachmentsStore.createIndex('workKey', 'workKey', { unique: false });
                        attachmentsStore.createIndex('type', 'type', { unique: false });
                        attachmentsStore.createIndex('timestamp', 'timestamp', { unique: false });
                    }

                    // v3: 创建设置存储
                    if (oldVersion < 3 && !db.objectStoreNames.contains(this.config.get('database.stores.settings'))) {
                        db.createObjectStore(
                            this.config.get('database.stores.settings'),
                            { keyPath: 'key' }
                        );
                    }
                };
            });
        }

        async saveNote(workKey, questionId, content) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readwrite'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                
                const id = `${workKey}_${questionId}`;
                const data = {
                    id,
                    workKey,
                    questionId,
                    content,
                    contentType: 'text',  // 内容类型:text, html等
                    hasAttachments: false, // 是否有附件
                    attachmentCount: 0,    // 附件数量
                    timestamp: Date.now(),
                    updatedAt: Date.now()
                };

                const request = objectStore.put(data);
                request.onsuccess = () => resolve(data);
                request.onerror = () => reject(request.error);
            });
        }

        async getNote(workKey, questionId) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                
                const id = `${workKey}_${questionId}`;
                const request = objectStore.get(id);

                request.onsuccess = () => resolve(request.result?.content || '');
                request.onerror = () => reject(request.error);
            });
        }

        async getAllNotes(workKey) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                const index = objectStore.index('workKey');
                const request = index.getAll(workKey);

                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        }

        /**
         * 获取整个域名下的所有笔记
         */
        async getAllDomainNotes() {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                const request = objectStore.getAll();

                request.onsuccess = () => resolve(request.result);
                request.onerror = () => reject(request.error);
            });
        }

        async deleteNote(workKey, questionId) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readwrite'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                
                const id = `${workKey}_${questionId}`;
                const request = objectStore.delete(id);

                request.onsuccess = () => resolve();
                request.onerror = () => reject(request.error);
            });
        }

        /**
         * 批量删除笔记
         * @param {Array<string>} noteIds - 笔记ID数组
         */
        async deleteNotes(noteIds) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readwrite'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                
                let completedCount = 0;
                const totalCount = noteIds.length;

                if (totalCount === 0) {
                    resolve(0);
                    return;
                }

                noteIds.forEach(id => {
                    const request = objectStore.delete(id);
                    request.onsuccess = () => {
                        completedCount++;
                        if (completedCount === totalCount) {
                            resolve(completedCount);
                        }
                    };
                    request.onerror = () => {
                        Logger.error(`删除笔记失败: ${id}`, request.error);
                        completedCount++;
                        if (completedCount === totalCount) {
                            resolve(completedCount);
                        }
                    };
                });
            });
        }

        /**
         * 获取数据库统计信息
         */
        async getStatistics() {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.notes')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.notes'));
                const countRequest = objectStore.count();

                countRequest.onsuccess = () => {
                    resolve({
                        totalNotes: countRequest.result,
                        databaseName: this.config.get('database.name'),
                        version: this.config.get('database.version')
                    });
                };
                countRequest.onerror = () => reject(countRequest.error);
            });
        }

        /**
         * 保存设置
         * @param {string} key - 设置键
         * @param {any} value - 设置值
         */
        async saveSetting(key, value) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.settings')],
                    'readwrite'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.settings'));
                
                const data = { key, value, updatedAt: Date.now() };
                const request = objectStore.put(data);

                request.onsuccess = () => resolve(data);
                request.onerror = () => reject(request.error);
            });
        }

        /**
         * 获取设置
         * @param {string} key - 设置键
         * @param {any} defaultValue - 默认值
         */
        async getSetting(key, defaultValue = null) {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.settings')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.settings'));
                const request = objectStore.get(key);

                request.onsuccess = () => {
                    const result = request.result;
                    resolve(result ? result.value : defaultValue);
                };
                request.onerror = () => reject(request.error);
            });
        }

        /**
         * 获取所有设置
         */
        async getAllSettings() {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                const transaction = this.db.transaction(
                    [this.config.get('database.stores.settings')],
                    'readonly'
                );
                const objectStore = transaction.objectStore(this.config.get('database.stores.settings'));
                const request = objectStore.getAll();

                request.onsuccess = () => {
                    const settings = {};
                    request.result.forEach(item => {
                        settings[item.key] = item.value;
                    });
                    resolve(settings);
                };
                request.onerror = () => reject(request.error);
            });
        }

        /**
         * 清空所有数据(还原到初始状态)
         */
        async clearAllData() {
            if (!this.db) await this.init();

            return new Promise((resolve, reject) => {
                try {
                    const storeNames = [
                        this.config.get('database.stores.notes'),
                        this.config.get('database.stores.settings'),
                        this.config.get('database.stores.attachments')
                    ];

                    const transaction = this.db.transaction(storeNames, 'readwrite');
                    let completed = 0;

                    storeNames.forEach(storeName => {
                        if (this.db.objectStoreNames.contains(storeName)) {
                            const objectStore = transaction.objectStore(storeName);
                            const request = objectStore.clear();

                            request.onsuccess = () => {
                                completed++;
                                if (completed === storeNames.filter(name => this.db.objectStoreNames.contains(name)).length) {
                                    resolve();
                                }
                            };

                            request.onerror = () => reject(request.error);
                        } else {
                            completed++;
                        }
                    });

                    transaction.onerror = () => reject(transaction.error);
                } catch (error) {
                    reject(error);
                }
            });
        }
    }

    // ===================== 笔记编辑器组件 =====================
    class NoteEditor {
        constructor(questionId, workKey, dbManager, config, styleGenerator) {
            this.questionId = questionId;
            this.workKey = workKey;
            this.dbManager = dbManager;
            this.config = config;
            this.styleGenerator = styleGenerator;
            this.container = null;
            this.editor = null;
            this.toolbar = null;
            this.saveTimer = null;
            this.isVisible = false;
            this.isEditMode = false; // 初始为预览模式
            this.toolbarButtons = new Map(); // 存储按钮引用
        }

        async create() {
            const noteConfig = this.config.get('noteEditor');

            // 创建容器
            this.container = DOMHelper.createElement('div', {
                style: {
                    display: 'none',
                    marginTop: '12px'
                }
            });

            // 创建工具栏
            this.toolbar = this._createToolbar();
            this.container.appendChild(this.toolbar);

            // 创建编辑器(初始为预览模式)
            this.editor = DOMHelper.createElement('div', {
                contentEditable: 'false',
                style: {
                    width: noteConfig.width || '100%',
                    minHeight: noteConfig.minHeight,
                    maxHeight: noteConfig.maxHeight,
                    padding: noteConfig.padding,
                    fontSize: noteConfig.fontSize,
                    border: `${noteConfig.borderWidth} ${noteConfig.borderStyle} ${noteConfig.borderColor}`,
                    borderRadius: noteConfig.borderRadius,
                    backgroundColor: noteConfig.backgroundColor,
                    color: noteConfig.textColor,
                    fontFamily: noteConfig.fontFamily,
                    overflowY: 'auto',
                    overflowX: 'auto',
                    outline: 'none',
                    whiteSpace: 'pre-wrap',
                    wordWrap: 'break-word',
                    transition: 'border-color 0.2s',
                    boxSizing: 'border-box',
                    cursor: 'default'
                }
            });

            this.editor.setAttribute('data-placeholder', noteConfig.placeholder);

            // 添加占位符样式
            const style = document.createElement('style');
            style.textContent = `
                [contenteditable][data-placeholder]:empty:before {
                    content: attr(data-placeholder);
                    color: #a0aec0;
                    cursor: text;
                }
                [contenteditable] h1 { font-size: 2em; font-weight: bold; margin: 0.67em 0; }
                [contenteditable] h2 { font-size: 1.5em; font-weight: bold; margin: 0.75em 0; }
                [contenteditable] h3 { font-size: 1.17em; font-weight: bold; margin: 0.83em 0; }
                [contenteditable] ul, [contenteditable] ol { margin: 1em 0; padding-left: 2em; }
                [contenteditable] li { margin: 0.5em 0; }
                [contenteditable] blockquote { 
                    border-left: 4px solid #cbd5e0; 
                    padding-left: 1em; 
                    margin: 1em 0;
                    color: #718096;
                    font-style: italic;
                }
                [contenteditable] code {
                    background: #f7fafc;
                    padding: 2px 6px;
                    border-radius: 3px;
                    font-family: 'Courier New', monospace;
                    font-size: 0.9em;
                }
                [contenteditable] pre {
                    background: #2d3748;
                    color: #e2e8f0;
                    padding: 12px;
                    border-radius: 4px;
                    overflow-x: auto;
                    margin: 1em 0;
                }
                [contenteditable] a {
                    color: #4299e1;
                    text-decoration: underline;
                }
                [contenteditable] hr {
                    border: none;
                    border-top: 2px solid #e2e8f0;
                    margin: 1.5em 0;
                }
            `;
            document.head.appendChild(style);

            // 加载已保存的笔记
            try {
                const savedContent = await this.dbManager.getNote(this.workKey, this.questionId);
                if (savedContent) {
                    this.editor.innerHTML = this._sanitizeHTML(savedContent);
                }
            } catch (error) {
                Logger.error(this.config.get('messages.noteLoadError'), error);
            }

            // 监听输入事件
            this.editor.addEventListener('input', () => {
                this._scheduleAutoSave();
            });

            // 监听光标移动和选择变化
            this.editor.addEventListener('mouseup', () => this._updateToolbarState());
            this.editor.addEventListener('keyup', () => this._updateToolbarState());
            this.editor.addEventListener('click', () => this._updateToolbarState());

            // 移除自动进入编辑模式的焦点事件处理
            // 编辑/预览模式切换将由切换按钮控制

            // 处理快捷键
            this.editor.addEventListener('keydown', (e) => {
                if (e.ctrlKey || e.metaKey) {
                    switch(e.key.toLowerCase()) {
                        case 'b':
                            e.preventDefault();
                            this._execCommand('bold');
                            break;
                        case 'i':
                            e.preventDefault();
                            this._execCommand('italic');
                            break;
                        case 'u':
                            e.preventDefault();
                            this._execCommand('underline');
                            break;
                    }
                }
            });

            this.container.appendChild(this.editor);
            return this.container;
        }

        _createToolbar() {
            const toolbar = DOMHelper.createElement('div', {
                style: {
                    display: 'none',
                    flexWrap: 'wrap',
                    gap: '4px',
                    padding: '8px',
                    backgroundColor: '#f7fafc',
                    borderRadius: '6px 6px 0 0',
                    border: '1px solid #e2e8f0',
                    borderBottom: 'none'
                }
            });

            const buttons = [
                { icon: '𝐁', title: '粗体 (Ctrl+B)', command: 'bold' },
                { icon: '𝐼', title: '斜体 (Ctrl+I)', command: 'italic', style: 'font-style: italic;' },
                { icon: 'U̲', title: '下划线 (Ctrl+U)', command: 'underline', style: 'text-decoration: underline;' },
                { icon: 'S̶', title: '删除线', command: 'strikeThrough', style: 'text-decoration: line-through;' },
                { type: 'separator' },
                { icon: 'H1', title: '标题1', command: 'formatBlock', value: '<h1>' },
                { icon: 'H2', title: '标题2', command: 'formatBlock', value: '<h2>' },
                { icon: 'H3', title: '标题3', command: 'formatBlock', value: '<h3>' },
                { type: 'separator' },
                { icon: '•', title: '无序列表', command: 'insertUnorderedList' },
                { icon: '1.', title: '有序列表', command: 'insertOrderedList' },
                { icon: '"', title: '引用', command: 'formatBlock', value: '<blockquote>' },
                { type: 'separator' },
                { icon: '🔗', title: '插入链接', command: 'createLink', prompt: true },
                { icon: '</>', title: '代码', command: 'code' },
                { icon: '—', title: '分隔线', command: 'insertHorizontalRule' },
                { type: 'separator' },
                { icon: '↶', title: '撤销', command: 'undo' },
                { icon: '↷', title: '重做', command: 'redo' },
                { icon: '🗑', title: '清除格式', command: 'removeFormat' }
            ];

            buttons.forEach(btn => {
                if (btn.type === 'separator') {
                    const separator = DOMHelper.createElement('div', {
                        style: {
                            width: '1px',
                            height: '20px',
                            backgroundColor: '#cbd5e0',
                            margin: '0 4px'
                        }
                    });
                    toolbar.appendChild(separator);
                } else {
                    const button = DOMHelper.createElement('button', {
                        innerHTML: btn.icon,
                        title: btn.title,
                        style: {
                            padding: '6px 10px',
                            border: '1px solid #cbd5e0',
                            borderRadius: '4px',
                            backgroundColor: 'white',
                            cursor: 'pointer',
                            fontSize: '14px',
                            fontWeight: 'bold',
                            transition: 'all 0.2s',
                            ...(btn.style ? this._parseStyle(btn.style) : {})
                        }
                    });

                    button.addEventListener('mouseenter', () => {
                        const isActive = button.style.backgroundColor === 'rgb(66, 153, 225)' || 
                                       button.style.backgroundColor === '#4299e1';
                        if (!isActive) {
                            button.style.backgroundColor = '#e2e8f0';
                        }
                    });

                    button.addEventListener('mouseleave', () => {
                        const isActive = button.style.color === 'white';
                        if (!isActive) {
                            button.style.backgroundColor = 'white';
                        }
                    });

                    button.addEventListener('mousedown', (e) => {
                        e.preventDefault();
                        
                        // 保存当前选区
                        const selection = window.getSelection();
                        let savedRange = null;
                        if (selection.rangeCount > 0) {
                            savedRange = selection.getRangeAt(0);
                        }
                        
                        if (btn.prompt) {
                            // 处理链接插入
                            const url = prompt('请输入链接地址:');
                            if (url) {
                                // 恢复选区
                                if (savedRange) {
                                    selection.removeAllRanges();
                                    selection.addRange(savedRange);
                                }
                                this._execCommand(btn.command, url);
                            }
                        } else if (btn.value) {
                            // 恢复选区
                            if (savedRange) {
                                selection.removeAllRanges();
                                selection.addRange(savedRange);
                            }
                            this._execCommand(btn.command, btn.value);
                        } else if (btn.command === 'code') {
                            // 恢复选区
                            if (savedRange) {
                                selection.removeAllRanges();
                                selection.addRange(savedRange);
                            }
                            this._toggleCodeStyle();
                        } else if (btn.command) {
                            // 恢复选区
                            if (savedRange) {
                                selection.removeAllRanges();
                                selection.addRange(savedRange);
                            }
                            this._execCommand(btn.command);
                        }
                        
                        // 确保编辑器获得焦点
                        setTimeout(() => {
                            this.editor.focus();
                            this._updateToolbarState();
                        }, 10);
                    });

                    // 保存按钮引用
                    if (btn.command) {
                        this.toolbarButtons.set(btn.command, button);
                    }

                    toolbar.appendChild(button);
                }
            });

            return toolbar;
        }

        _parseStyle(styleString) {
            const styles = {};
            styleString.split(';').forEach(rule => {
                const [key, value] = rule.split(':').map(s => s.trim());
                if (key && value) {
                    const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
                    styles[camelKey] = value;
                }
            });
            return styles;
        }

        _execCommand(command, value = null) {
            document.execCommand(command, false, value);
            this._updateToolbarState();
        }

        _updateToolbarState() {
            // 更新可切换状态的按钮
            const commands = ['bold', 'italic', 'underline', 'strikeThrough', 'insertUnorderedList', 'insertOrderedList'];
            
            commands.forEach(command => {
                const button = this.toolbarButtons.get(command);
                if (button) {
                    const isActive = document.queryCommandState(command);
                    if (isActive) {
                        button.style.backgroundColor = '#4299e1';
                        button.style.color = 'white';
                        button.style.borderColor = '#3182ce';
                    } else {
                        button.style.backgroundColor = 'white';
                        button.style.color = 'inherit';
                        button.style.borderColor = '#cbd5e0';
                    }
                }
            });
        }

        _toggleCodeStyle() {
            const selection = window.getSelection();
            if (!selection.rangeCount) return;

            const range = selection.getRangeAt(0);
            const selectedText = range.toString();

            if (selectedText) {
                const code = document.createElement('code');
                code.textContent = selectedText;
                
                try {
                    range.deleteContents();
                    range.insertNode(code);
                    
                    // 恢复光标位置到代码块之后
                    range.setStartAfter(code);
                    range.setEndAfter(code);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    
                    this.editor.focus();
                } catch (error) {
                    Logger.error('插入代码失败', error);
                }
            } else {
                // 如果没有选中文本,在光标位置插入代码标记
                const code = document.createElement('code');
                code.textContent = '代码';
                
                try {
                    range.insertNode(code);
                    range.setStartAfter(code);
                    range.setEndAfter(code);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    this.editor.focus();
                } catch (error) {
                    Logger.error('插入代码失败', error);
                }
            }
        }

        _sanitizeHTML(html) {
            // 基本的 HTML 清理,防止 XSS
            const div = document.createElement('div');
            div.innerHTML = html;
            
            // 移除危险的标签和属性
            const scripts = div.querySelectorAll('script, iframe, object, embed');
            scripts.forEach(el => el.remove());
            
            return div.innerHTML;
        }

        _scheduleAutoSave() {
            // 检查自动保存是否启用
            this.dbManager.getSetting('autoSave', this.config.get('settings.autoSave'))
                .then(autoSaveEnabled => {
                    if (!autoSaveEnabled) return;

                    if (this.saveTimer) {
                        clearTimeout(this.saveTimer);
                    }

                    this.dbManager.getSetting('autoSaveDelay', this.config.get('settings.autoSaveDelay'))
                        .then(delay => {
                            this.saveTimer = setTimeout(async () => {
                                await this.save();
                            }, delay);
                        });
                });
        }

        async save() {
            try {
                const content = this.editor.innerHTML;
                await this.dbManager.saveNote(this.workKey, this.questionId, content);
            } catch (error) {
                Logger.error('保存笔记失败', error);
            }
        }

        show() {
            this.container.style.display = 'block';
            this.isVisible = true;
        }

        hide() {
            this.container.style.display = 'none';
            this.isVisible = false;
        }

        toggle() {
            if (this.isVisible) {
                this.hide();
            } else {
                this.show();
            }
        }

        toggleEditMode() {
            this.isEditMode = !this.isEditMode;
            
            if (this.isEditMode) {
                // 切换到编辑模式
                this.editor.contentEditable = 'true';
                this.editor.style.cursor = 'text';
                this.toolbar.style.display = 'flex';
                this.editor.style.borderColor = this.config.get('noteEditor.focusBorderColor');
                this.editor.focus();
                this._updateToolbarState();
            } else {
                // 切换到预览模式
                this.editor.contentEditable = 'false';
                this.editor.style.cursor = 'default';
                this.toolbar.style.display = 'none';
                this.editor.style.borderColor = this.config.get('noteEditor.borderColor');
                this.editor.blur();
            }
        }

        getElement() {
            return this.container;
        }
    }

    // ===================== 控制面板UI组件 =====================
    class ControlPanelUI {
        constructor(dbManager, workKey, config) {
            this.dbManager = dbManager;
            this.workKey = workKey;
            this.config = config;
            this.modal = null;
            this.notesList = [];
            this.selectedNotes = new Set();
            this.notesScope = 'current'; // 'current', 'course', 'class', 'domain'
            this.currentTab = 'settings'; // 'settings', 'notes', 'styles'
            this.settings = {};
            this.notesMenuExpanded = false; // 管理笔记子菜单是否展开
            this.notesSortBy = 'time'; // 'time' 或 'alpha' (字母序)
            this.notesSortOrder = 'desc'; // 'asc' 升序 或 'desc' 降序
            
            // 解析 workKey 获取 courseId, classId, workId
            const parts = workKey.split('_');
            this.courseId = parts[0] || '';
            this.classId = parts[1] || '';
            this.workId = parts[2] || '';
        }

        /**
         * 显示控制面板
         */
        async show() {
            await this._loadSettings();
            await this._loadNotes();
            this._createModal();
            this._renderContent();
        }

        /**
         * 加载用户设置
         */
        async _loadSettings() {
            try {
                this.settings = await this.dbManager.getAllSettings();
                // 填充默认值
                if (!('autoSave' in this.settings)) {
                    this.settings.autoSave = this.config.get('settings.autoSave');
                }
                if (!('autoSaveDelay' in this.settings)) {
                    this.settings.autoSaveDelay = this.config.get('settings.autoSaveDelay');
                }
            } catch (error) {
                Logger.error('加载设置失败', error);
                this.settings = {
                    autoSave: this.config.get('settings.autoSave'),
                    autoSaveDelay: this.config.get('settings.autoSaveDelay')
                };
            }
        }

        /**
         * 加载笔记数据
         */
        async _loadNotes() {
            try {
                const allNotes = await this.dbManager.getAllDomainNotes();
                
                switch (this.notesScope) {
                    case 'current':
                        // 当前页面:完全匹配 workKey
                        this.notesList = allNotes.filter(note => note.workKey === this.workKey);
                        break;
                    case 'course':
                        // 当前课程:courseId 相同
                        this.notesList = allNotes.filter(note => {
                            const parts = note.workKey.split('_');
                            return parts[0] === this.courseId;
                        });
                        break;
                    case 'class':
                        // 当前班级:courseId 和 classId 都相同
                        this.notesList = allNotes.filter(note => {
                            const parts = note.workKey.split('_');
                            return parts[0] === this.courseId && parts[1] === this.classId;
                        });
                        break;
                    case 'domain':
                        // 整个域名:所有笔记
                        this.notesList = allNotes;
                        break;
                    default:
                        this.notesList = allNotes.filter(note => note.workKey === this.workKey);
                }
                
                this.notesList.sort((a, b) => b.timestamp - a.timestamp);
            } catch (error) {
                Logger.error('加载笔记失败', error);
                this.notesList = [];
            }
        }

        /**
         * 创建模态框
         */
        _createModal() {
            // 创建遮罩层
            const overlay = DOMHelper.createElement('div', {
                style: {
                    position: 'fixed',
                    top: '0',
                    left: '0',
                    width: '100%',
                    height: '100%',
                    backgroundColor: 'rgba(0, 0, 0, 0.5)',
                    zIndex: '99999',
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center'
                }
            });

            // 创建主容器
            const mainContainer = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '12px',
                    width: '90%',
                    maxWidth: '900px',
                    height: '85vh',
                    display: 'flex',
                    boxShadow: '0 10px 40px rgba(0, 0, 0, 0.2)',
                    overflow: 'hidden'
                }
            });

            // 创建左侧边栏
            const sidebar = this._createSidebar();
            mainContainer.appendChild(sidebar);

            // 创建右侧内容区
            const contentArea = DOMHelper.createElement('div', {
                id: 'panel-content-area',
                style: {
                    flex: '1',
                    display: 'flex',
                    flexDirection: 'column',
                    backgroundColor: '#f7fafc'
                }
            });

            // 创建内容区标题栏
            const contentHeader = DOMHelper.createElement('div', {
                id: 'panel-content-header',
                style: {
                    padding: '20px 30px',
                    borderBottom: '1px solid #e2e8f0',
                    backgroundColor: 'white',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center'
                }
            });

            const headerTitle = DOMHelper.createElement('h2', {
                id: 'panel-header-title',
                innerText: '⚙️ 设置',
                style: {
                    margin: '0',
                    fontSize: '20px',
                    fontWeight: 'bold',
                    color: '#2d3748'
                }
            });

            const closeBtn = DOMHelper.createElement('button', {
                innerText: '✕',
                style: {
                    background: 'none',
                    border: 'none',
                    fontSize: '24px',
                    cursor: 'pointer',
                    color: '#718096',
                    padding: '0',
                    width: '30px',
                    height: '30px',
                    lineHeight: '30px',
                    textAlign: 'center',
                    borderRadius: '50%',
                    transition: 'background 0.2s'
                }
            });

            closeBtn.addEventListener('mouseenter', () => {
                closeBtn.style.backgroundColor = '#e2e8f0';
            });

            closeBtn.addEventListener('mouseleave', () => {
                closeBtn.style.backgroundColor = 'transparent';
            });

            closeBtn.addEventListener('click', () => this._close());

            contentHeader.appendChild(headerTitle);
            contentHeader.appendChild(closeBtn);
            contentArea.appendChild(contentHeader);

            // 创建内容主体
            const contentBody = DOMHelper.createElement('div', {
                id: 'panel-content-body',
                style: {
                    flex: '1',
                    overflow: 'auto',
                    padding: '30px'
                }
            });

            contentArea.appendChild(contentBody);
            mainContainer.appendChild(contentArea);
            overlay.appendChild(mainContainer);

            // 点击遮罩层关闭
            overlay.addEventListener('click', (e) => {
                if (e.target === overlay) {
                    this._close();
                }
            });

            this.modal = overlay;
            document.body.appendChild(overlay);
        }

        /**
         * 创建左侧边栏
         */
        _createSidebar() {
            const sidebar = DOMHelper.createElement('div', {
                style: {
                    width: '220px',
                    backgroundColor: '#2d3748',
                    display: 'flex',
                    flexDirection: 'column',
                    padding: '20px 0'
                }
            });

            // 标题
            const title = DOMHelper.createElement('div', {
                innerText: '控制面板',
                style: {
                    padding: '0 20px 20px',
                    fontSize: '18px',
                    fontWeight: 'bold',
                    color: 'white',
                    borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
                    marginBottom: '10px'
                }
            });

            sidebar.appendChild(title);

            // 菜单项
            const menuItems = [
                { id: 'settings', icon: '⚙️', text: '设置' },
                { id: 'export', icon: '📄', text: '导出设置' },
                { 
                    id: 'notes', 
                    icon: '📝', 
                    text: '笔记管理',
                    hasSubmenu: true,
                    submenu: [
                        { id: 'notes-current', icon: '📄', text: '当前页面', scope: 'current' },
                        { id: 'notes-course', icon: '📚', text: '当前课程', scope: 'course' },
                        { id: 'notes-domain', icon: '🌐', text: '当前域名', scope: 'domain' }
                    ]
                },
                { id: 'styles', icon: '🎨', text: '样式管理' }
            ];

            menuItems.forEach(item => {
                const menuItem = this._createMenuItem(item);
                sidebar.appendChild(menuItem);
            });

            return sidebar;
        }

        /**
         * 创建菜单项(支持子菜单)
         */
        _createMenuItem(item) {
            const container = DOMHelper.createElement('div');
            
            // 主菜单项
            const menuItem = DOMHelper.createElement('div', {
                dataset: { tab: item.id },
                style: {
                    padding: '12px 20px',
                    cursor: 'pointer',
                    color: this.currentTab === item.id ? 'white' : '#a0aec0',
                    backgroundColor: this.currentTab === item.id ? '#4a5568' : 'transparent',
                    borderLeft: this.currentTab === item.id ? '3px solid #4299e1' : '3px solid transparent',
                    fontWeight: this.currentTab === item.id ? 'bold' : 'normal',
                    transition: 'all 0.2s',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '10px',
                    justifyContent: 'space-between'
                }
            });

            const leftContent = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    alignItems: 'center',
                    gap: '10px'
                }
            });

            const iconSpan = DOMHelper.createElement('span', {
                innerText: item.icon,
                style: {
                    fontSize: '16px'
                }
            });

            const textSpan = DOMHelper.createElement('span', {
                innerText: item.text,
                style: {
                    fontSize: '14px'
                }
            });

            leftContent.appendChild(iconSpan);
            leftContent.appendChild(textSpan);
            menuItem.appendChild(leftContent);

            // 如果有子菜单,添加展开图标
            if (item.hasSubmenu) {
                const expandIcon = DOMHelper.createElement('span', {
                    innerText: '▼',
                    style: {
                        fontSize: '10px',
                        transition: 'transform 0.2s',
                        transform: this.notesMenuExpanded ? 'rotate(0deg)' : 'rotate(-90deg)'
                    }
                });
                menuItem.appendChild(expandIcon);

                // 创建子菜单容器
                const submenuContainer = DOMHelper.createElement('div', {
                    style: {
                        display: this.notesMenuExpanded ? 'block' : 'none',
                        backgroundColor: '#1a202c'
                    }
                });

                item.submenu.forEach(subItem => {
                    const subMenuItem = this._createSubMenuItem(subItem);
                    submenuContainer.appendChild(subMenuItem);
                });

                menuItem.addEventListener('click', () => {
                    this.notesMenuExpanded = !this.notesMenuExpanded;
                    expandIcon.style.transform = this.notesMenuExpanded ? 'rotate(0deg)' : 'rotate(-90deg)';
                    submenuContainer.style.display = this.notesMenuExpanded ? 'block' : 'none';
                });

                container.appendChild(menuItem);
                container.appendChild(submenuContainer);
            } else {
                // 无子菜单的普通菜单项
                menuItem.addEventListener('mouseenter', () => {
                    if (this.currentTab !== item.id) {
                        menuItem.style.backgroundColor = '#4a5568';
                        menuItem.style.color = '#e2e8f0';
                    }
                });

                menuItem.addEventListener('mouseleave', () => {
                    if (this.currentTab !== item.id) {
                        menuItem.style.backgroundColor = 'transparent';
                        menuItem.style.color = '#a0aec0';
                    }
                });

                menuItem.addEventListener('click', () => {
                    this.currentTab = item.id;
                    this._updateSidebarState();
                    this._renderContent();
                });

                container.appendChild(menuItem);
            }

            return container;
        }

        /**
         * 创建子菜单项
         */
        _createSubMenuItem(subItem) {
            const isActive = this.currentTab === 'notes' && this.notesScope === subItem.scope;
            
            const subMenuItem = DOMHelper.createElement('div', {
                dataset: { scope: subItem.scope },
                style: {
                    padding: '10px 20px 10px 50px',
                    cursor: 'pointer',
                    color: isActive ? '#4299e1' : '#718096',
                    backgroundColor: isActive ? '#2d3748' : 'transparent',
                    fontSize: '13px',
                    transition: 'all 0.2s',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '8px'
                }
            });

            const icon = DOMHelper.createElement('span', {
                innerText: subItem.icon,
                style: {
                    fontSize: '14px'
                }
            });

            const text = DOMHelper.createElement('span', {
                innerText: subItem.text
            });

            subMenuItem.appendChild(icon);
            subMenuItem.appendChild(text);

            subMenuItem.addEventListener('mouseenter', () => {
                if (!(this.currentTab === 'notes' && this.notesScope === subItem.scope)) {
                    subMenuItem.style.backgroundColor = '#2d3748';
                    subMenuItem.style.color = '#a0aec0';
                }
            });

            subMenuItem.addEventListener('mouseleave', () => {
                const isCurrentScope = this.currentTab === 'notes' && this.notesScope === subItem.scope;
                if (!isCurrentScope) {
                    subMenuItem.style.backgroundColor = 'transparent';
                    subMenuItem.style.color = '#718096';
                } else {
                    subMenuItem.style.backgroundColor = '#2d3748';
                    subMenuItem.style.color = '#4299e1';
                }
            });

            subMenuItem.addEventListener('click', async () => {
                this.currentTab = 'notes';
                this.notesScope = subItem.scope;
                this.selectedNotes.clear();
                await this._loadNotes();
                this._updateSidebarState();
                this._renderContent();
            });

            return subMenuItem;
        }

        /**
         * 更新侧边栏状态
         */
        _updateSidebarState() {
            const menuItems = this.modal.querySelectorAll('[data-tab]');
            menuItems.forEach(item => {
                const isActive = item.dataset.tab === this.currentTab;
                item.style.color = isActive ? 'white' : '#a0aec0';
                item.style.backgroundColor = isActive ? '#4a5568' : 'transparent';
                item.style.borderLeft = isActive ? '3px solid #4299e1' : '3px solid transparent';
                item.style.fontWeight = isActive ? 'bold' : 'normal';
            });

            // 更新子菜单项状态
            const subMenuItems = this.modal.querySelectorAll('[data-scope]');
            subMenuItems.forEach(item => {
                const isActive = this.currentTab === 'notes' && this.notesScope === item.dataset.scope;
                item.style.color = isActive ? '#4299e1' : '#718096';
                item.style.backgroundColor = isActive ? '#2d3748' : 'transparent';
            });
        }

        /**
         * 创建统一的底部悬浮操作栏
         * @param {Object} options - 配置选项
         * @param {string} options.saveText - 保存按钮文字
         * @param {Function} options.onSave - 保存回调函数
         * @param {Function} options.onReset - 重置回调函数(可选)
         * @param {string} options.resetText - 重置按钮文字(可选)
         * @returns {HTMLElement} 操作栏元素
         */
        _createFloatingActionBar(options) {
            const { 
                saveText = '💾 保存设置', 
                onSave, 
                onReset = null, 
                resetText = '🔄 重置为默认' 
            } = options;
            
            const buttonConfig = this.config.get('panelSaveButton');
            
            // 创建悬浮操作栏容器
            const actionBar = DOMHelper.createElement('div', {
                className: 'floating-action-bar',
                style: {
                    position: 'sticky',
                    bottom: '0',
                    left: '0',
                    right: '0',
                    padding: '12px 20px',
                    backgroundColor: 'white',
                    borderTop: '1px solid #e2e8f0',
                    display: 'flex',
                    justifyContent: onReset ? 'space-between' : 'flex-end',
                    alignItems: 'center',
                    boxShadow: '0 -2px 8px rgba(0, 0, 0, 0.06)',
                    zIndex: '100',
                    marginTop: '16px'
                }
            });

            // 创建重置按钮(如果提供了重置回调)
            if (onReset) {
                const resetButton = DOMHelper.createElement('button', {
                    innerText: resetText,
                    style: {
                        padding: '8px 16px',
                        border: '1px solid #e2e8f0',
                        borderRadius: '6px',
                        backgroundColor: 'white',
                        color: '#718096',
                        fontSize: '13px',
                        fontWeight: '500',
                        cursor: 'pointer',
                        transition: 'all 0.2s'
                    }
                });

                resetButton.addEventListener('mouseenter', () => {
                    resetButton.style.backgroundColor = '#f7fafc';
                    resetButton.style.borderColor = '#cbd5e0';
                    resetButton.style.transform = 'translateY(-1px)';
                    resetButton.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
                });

                resetButton.addEventListener('mouseleave', () => {
                    resetButton.style.backgroundColor = 'white';
                    resetButton.style.borderColor = '#e2e8f0';
                    resetButton.style.transform = 'translateY(0)';
                    resetButton.style.boxShadow = 'none';
                });

                resetButton.addEventListener('click', onReset);
                actionBar.appendChild(resetButton);
            }

            // 创建保存按钮
            const saveButton = DOMHelper.createElement('button', {
                innerText: saveText,
                style: {
                    padding: '8px 18px',
                    border: 'none',
                    borderRadius: '6px',
                    backgroundColor: buttonConfig.colors.background,
                    color: buttonConfig.colors.textColor,
                    fontSize: '13px',
                    fontWeight: '500',
                    cursor: 'pointer',
                    transition: 'all 0.2s',
                    boxShadow: buttonConfig.colors.boxShadow
                }
            });

            saveButton.addEventListener('mouseenter', () => {
                saveButton.style.backgroundColor = buttonConfig.colors.hoverBackground;
                saveButton.style.transform = 'translateY(-1px)';
                saveButton.style.boxShadow = buttonConfig.colors.hoverBoxShadow;
            });

            saveButton.addEventListener('mouseleave', () => {
                if (!saveButton.dataset.success && !saveButton.dataset.error) {
                    saveButton.style.backgroundColor = buttonConfig.colors.background;
                    saveButton.style.transform = 'translateY(0)';
                    saveButton.style.boxShadow = buttonConfig.colors.boxShadow;
                }
            });

            // 封装保存逻辑
            saveButton.addEventListener('click', async () => {
                try {
                    saveButton.disabled = true;
                    saveButton.innerText = '⏳ 保存中...';
                    
                    await onSave();
                    
                    // 显示成功状态
                    saveButton.dataset.success = 'true';
                    saveButton.innerText = buttonConfig.text.success;
                    saveButton.style.backgroundColor = buttonConfig.colors.successBackground;
                    
                    setTimeout(() => {
                        delete saveButton.dataset.success;
                        saveButton.innerText = saveText;
                        saveButton.style.backgroundColor = buttonConfig.colors.background;
                        saveButton.disabled = false;
                    }, 2000);
                    
                } catch (error) {
                    Logger.error('保存失败', error);
                    
                    // 显示错误状态
                    saveButton.dataset.error = 'true';
                    saveButton.innerText = buttonConfig.text.error;
                    saveButton.style.backgroundColor = buttonConfig.colors.errorBackground;
                    
                    setTimeout(() => {
                        delete saveButton.dataset.error;
                        saveButton.innerText = saveText;
                        saveButton.style.backgroundColor = buttonConfig.colors.background;
                        saveButton.disabled = false;
                    }, 2000);
                }
            });

            actionBar.appendChild(saveButton);
            
            return actionBar;
        }

        /**
         * 渲染内容区
         */
        _renderContent() {
            const headerTitle = document.getElementById('panel-header-title');
            const contentBody = document.getElementById('panel-content-body');

            if (this.currentTab === 'settings') {
                headerTitle.innerText = '⚙️ 设置';
                this._renderSettingsPanel(contentBody);
            } else if (this.currentTab === 'export') {
                headerTitle.innerText = '📄 导出设置';
                this._renderExportSettingsPanel(contentBody);
            } else if (this.currentTab === 'notes') {
                headerTitle.innerText = '📝 笔记管理';
                this._renderNotesPanel(contentBody);
            } else if (this.currentTab === 'styles') {
                headerTitle.innerText = '🎨 样式管理';
                this._renderStylesPanel(contentBody);
            }
        }

        /**
         * 渲染设置面板
         */
        _renderSettingsPanel(container) {
            container.innerHTML = '';

            const settingsContainer = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '8px',
                    padding: '24px',
                    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
                    marginBottom: '20px'
                }
            });

            // 自动保存开关
            const autoSaveSection = this._createSettingItem(
                '自动保存',
                '开启后会在输入停止一段时间后自动保存笔记',
                'checkbox',
                'autoSave',
                this.settings.autoSave
            );

            settingsContainer.appendChild(autoSaveSection);

            // 自动保存延迟时间
            const delaySection = this._createSettingItem(
                '自动保存延迟',
                '输入停止后多久开始保存(毫秒)',
                'number',
                'autoSaveDelay',
                this.settings.autoSaveDelay
            );

            settingsContainer.appendChild(delaySection);

            container.appendChild(settingsContainer);

            // 危险操作区域
            const dangerZone = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '8px',
                    padding: '24px',
                    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
                    marginBottom: '20px',
                    border: '2px solid #feb2b2'
                }
            });

            const dangerTitle = DOMHelper.createElement('div', {
                innerText: '⚠️ 危险操作',
                style: {
                    fontSize: '16px',
                    fontWeight: 'bold',
                    color: '#c53030',
                    marginBottom: '16px'
                }
            });

            const clearDbSection = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    paddingBottom: '16px'
                }
            });

            const clearDbInfo = DOMHelper.createElement('div');

            const clearDbLabel = DOMHelper.createElement('div', {
                innerText: '清空所有数据',
                style: {
                    fontSize: '14px',
                    fontWeight: '600',
                    color: '#2d3748',
                    marginBottom: '4px'
                }
            });

            const clearDbDesc = DOMHelper.createElement('div', {
                innerText: '删除所有笔记、设置和自定义样式,还原到初始状态。此操作不可恢复!',
                style: {
                    fontSize: '13px',
                    color: '#718096',
                    lineHeight: '1.5'
                }
            });

            clearDbInfo.appendChild(clearDbLabel);
            clearDbInfo.appendChild(clearDbDesc);

            const clearDbBtn = DOMHelper.createElement('button', {
                innerText: '清空数据库',
                style: {
                    padding: '8px 16px',
                    border: 'none',
                    borderRadius: '4px',
                    backgroundColor: '#f56565',
                    color: 'white',
                    fontSize: '13px',
                    fontWeight: '600',
                    cursor: 'pointer',
                    transition: 'all 0.2s',
                    whiteSpace: 'nowrap'
                }
            });

            clearDbBtn.addEventListener('mouseenter', () => {
                clearDbBtn.style.backgroundColor = '#e53e3e';
                clearDbBtn.style.transform = 'translateY(-1px)';
            });

            clearDbBtn.addEventListener('mouseleave', () => {
                clearDbBtn.style.backgroundColor = '#f56565';
                clearDbBtn.style.transform = 'translateY(0)';
            });

            clearDbBtn.addEventListener('click', async () => {
                const confirmText = '确认要清空所有数据吗?\n\n将删除:\n- 所有笔记\n- 所有设置\n- 所有自定义样式\n\n此操作不可恢复!\n\n请输入 "CLEAR" 确认操作:';
                const userInput = prompt(confirmText);

                if (userInput === 'CLEAR') {
                    try {
                        clearDbBtn.disabled = true;
                        clearDbBtn.innerText = '清空中...';
                        clearDbBtn.style.backgroundColor = '#cbd5e0';

                        await this.dbManager.clearAllData();

                        alert('✅ 数据库已清空!\n\n页面将在 2 秒后刷新...');
                        Logger.success('数据库已成功清空');

                        setTimeout(() => {
                            window.location.reload();
                        }, 2000);
                    } catch (error) {
                        Logger.error('清空数据库失败', error);
                        alert('❌ 清空失败,请查看控制台了解详情');
                        clearDbBtn.disabled = false;
                        clearDbBtn.innerText = '清空数据库';
                        clearDbBtn.style.backgroundColor = '#f56565';
                    }
                } else if (userInput !== null) {
                    alert('输入不正确,操作已取消');
                }
            });

            clearDbSection.appendChild(clearDbInfo);
            clearDbSection.appendChild(clearDbBtn);

            dangerZone.appendChild(dangerTitle);
            dangerZone.appendChild(clearDbSection);

            container.appendChild(dangerZone);

            // 添加统一的底部操作栏
            const actionBar = this._createFloatingActionBar({
                saveText: '💾 保存基础设置',
                onSave: async () => {
                    await this.dbManager.saveSetting('autoSave', this.settings.autoSave);
                    await this.dbManager.saveSetting('autoSaveDelay', this.settings.autoSaveDelay);
                    Logger.success('基础设置已保存');
                },
                onReset: async () => {
                    if (confirm('确定要重置基础设置为默认值吗?')) {
                        const defaults = this.config.get('settings');
                        this.settings.autoSave = defaults.autoSave;
                        this.settings.autoSaveDelay = defaults.autoSaveDelay;
                        await this.dbManager.saveSetting('autoSave', defaults.autoSave);
                        await this.dbManager.saveSetting('autoSaveDelay', defaults.autoSaveDelay);
                        Logger.success('基础设置已重置');
                        this._renderSettingsPanel(container);
                    }
                },
                resetText: '🔄 重置基础设置'
            });
            container.appendChild(actionBar);
        }

        /**
         * 创建设置项
         */
        _createSettingItem(label, description, type, key, value) {
            const item = DOMHelper.createElement('div', {
                style: {
                    marginBottom: '24px',
                    paddingBottom: '24px',
                    borderBottom: '1px solid #e2e8f0'
                }
            });

            const labelEl = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    marginBottom: '8px'
                }
            });

            const labelText = DOMHelper.createElement('span', {
                innerText: label,
                style: {
                    fontSize: '16px',
                    fontWeight: '600',
                    color: '#2d3748'
                }
            });

            let input;
            if (type === 'checkbox') {
                input = DOMHelper.createElement('input', {
                    type: 'checkbox',
                    checked: value,
                    style: {
                        width: '20px',
                        height: '20px',
                        cursor: 'pointer'
                    }
                });

                input.addEventListener('change', () => {
                    this.settings[key] = input.checked;
                });
            } else if (type === 'number') {
                input = DOMHelper.createElement('input', {
                    type: 'number',
                    value: value,
                    style: {
                        width: '120px',
                        padding: '6px 12px',
                        border: '1px solid #cbd5e0',
                        borderRadius: '4px',
                        fontSize: '14px'
                    }
                });

                input.addEventListener('change', () => {
                    const numValue = parseInt(input.value);
                    if (numValue > 0) {
                        this.settings[key] = numValue;
                    }
                });
            }

            labelEl.appendChild(labelText);
            labelEl.appendChild(input);

            const desc = DOMHelper.createElement('div', {
                innerText: description,
                style: {
                    fontSize: '13px',
                    color: '#718096',
                    marginTop: '4px'
                }
            });

            item.appendChild(labelEl);
            item.appendChild(desc);

            return item;
        }

        /**
         * 渲染导出设置面板
         */
        _renderExportSettingsPanel(container) {
            container.innerHTML = '';

            // 加载导出设置
            const exportDefaults = this.config.get('exportSettings');
            const exportSettings = {
                fontFamily: this.settings.exportFontFamily ?? exportDefaults.fontFamily,
                fontSize: this.settings.exportFontSize ?? exportDefaults.fontSize,
                titleFontSize: this.settings.exportTitleFontSize ?? exportDefaults.titleFontSize,
                lineHeight: this.settings.exportLineHeight ?? exportDefaults.lineHeight,
                pageMargin: this.settings.exportPageMargin ?? exportDefaults.pageMargin,
                // 导出内容选项
                exportMyAnswer: this.settings.exportMyAnswer ?? exportDefaults.exportMyAnswer,
                exportCorrectAnswer: this.settings.exportCorrectAnswer ?? exportDefaults.exportCorrectAnswer,
                exportScore: this.settings.exportScore ?? exportDefaults.exportScore,
                exportAnalysis: this.settings.exportAnalysis ?? exportDefaults.exportAnalysis
            };

            // 提示说明区域
            const tipContainer = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: '#ebf8ff',
                    borderRadius: '8px',
                    padding: '16px',
                    marginBottom: '20px',
                    border: '1px solid #bee3f8'
                }
            });

            const tipText = DOMHelper.createElement('div', {
                innerHTML: '💡 <strong>提示:</strong>使用「📄 导出试题(无答案)」按钮导出不带答案的试卷,使用「📝 导出试题(含答案)」按钮导出带答案的试卷。下方「导出内容选项」仅在导出含答案时生效。',
                style: {
                    fontSize: '14px',
                    color: '#2b6cb0',
                    lineHeight: '1.6'
                }
            });
            tipContainer.appendChild(tipText);
            container.appendChild(tipContainer);

            // ========== 导出内容选项区域 ==========
            const contentContainer = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '8px',
                    padding: '24px',
                    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
                    marginBottom: '20px'
                }
            });

            const contentTitle = DOMHelper.createElement('div', {
                innerText: '📋 导出内容选项',
                style: {
                    fontSize: '16px',
                    fontWeight: 'bold',
                    color: '#2d3748',
                    marginBottom: '20px',
                    paddingBottom: '10px',
                    borderBottom: '2px solid #4299e1'
                }
            });
            contentContainer.appendChild(contentTitle);

            const contentDesc = DOMHelper.createElement('div', {
                innerText: '选择导出含答案时包含哪些内容(导出无答案时此选项不生效)',
                style: {
                    fontSize: '13px',
                    color: '#718096',
                    marginBottom: '16px'
                }
            });
            contentContainer.appendChild(contentDesc);

            // 创建勾选框容器
            const checkboxGrid = DOMHelper.createElement('div', {
                style: {
                    display: 'grid',
                    gridTemplateColumns: 'repeat(2, 1fr)',
                    gap: '12px'
                }
            });

            // 我的答案
            const myAnswerCheckbox = this._createExportCheckboxItem(
                '我的答案',
                '导出时包含"我的答案"信息',
                'exportMyAnswer',
                exportSettings.exportMyAnswer
            );
            checkboxGrid.appendChild(myAnswerCheckbox);

            // 正确答案
            const correctAnswerCheckbox = this._createExportCheckboxItem(
                '正确答案',
                '导出时包含"正确答案"信息',
                'exportCorrectAnswer',
                exportSettings.exportCorrectAnswer
            );
            checkboxGrid.appendChild(correctAnswerCheckbox);

            // 本题得分
            const scoreCheckbox = this._createExportCheckboxItem(
                '本题得分',
                '导出时包含本题得分信息',
                'exportScore',
                exportSettings.exportScore
            );
            checkboxGrid.appendChild(scoreCheckbox);

            // 答案解析
            const analysisCheckbox = this._createExportCheckboxItem(
                '答案解析',
                '导出时包含答案解析内容',
                'exportAnalysis',
                exportSettings.exportAnalysis
            );
            checkboxGrid.appendChild(analysisCheckbox);

            contentContainer.appendChild(checkboxGrid);
            container.appendChild(contentContainer);

            // 样式设置区域
            const styleContainer = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '8px',
                    padding: '24px',
                    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
                    marginBottom: '20px'
                }
            });

            const styleTitle = DOMHelper.createElement('div', {
                innerText: '🎨 样式设置',
                style: {
                    fontSize: '16px',
                    fontWeight: 'bold',
                    color: '#2d3748',
                    marginBottom: '20px',
                    paddingBottom: '10px',
                    borderBottom: '2px solid #48bb78'
                }
            });
            styleContainer.appendChild(styleTitle);

            // 字体选择
            const fontFamilySection = this._createExportSettingItem(
                '字体',
                '导出文档使用的字体',
                'select',
                'exportFontFamily',
                exportSettings.fontFamily,
                [
                    { value: '宋体', label: '宋体' },
                    { value: '黑体', label: '黑体' },
                    { value: '楷体', label: '楷体' },
                    { value: '仿宋', label: '仿宋' },
                    { value: '微软雅黑', label: '微软雅黑' },
                    { value: 'Arial', label: 'Arial' },
                    { value: 'Times New Roman', label: 'Times New Roman' }
                ]
            );
            styleContainer.appendChild(fontFamilySection);

            // 正文字号
            const fontSizeSection = this._createExportSettingItem(
                '正文字号',
                '导出文档正文的字体大小(pt)',
                'number',
                'exportFontSize',
                exportSettings.fontSize
            );
            styleContainer.appendChild(fontSizeSection);

            // 标题字号
            const titleFontSizeSection = this._createExportSettingItem(
                '标题字号',
                '导出文档标题的字体大小(pt)',
                'number',
                'exportTitleFontSize',
                exportSettings.titleFontSize
            );
            styleContainer.appendChild(titleFontSizeSection);

            // 行高
            const lineHeightSection = this._createExportSettingItem(
                '行高',
                '行与行之间的间距倍数',
                'number',
                'exportLineHeight',
                exportSettings.lineHeight,
                null,
                0.1  // step
            );
            styleContainer.appendChild(lineHeightSection);

            // 页边距
            const marginSection = this._createExportSettingItem(
                '页边距',
                '导出文档的页边距(格式:上 右 下 左)',
                'text',
                'exportPageMargin',
                exportSettings.pageMargin
            );
            styleContainer.appendChild(marginSection);

            container.appendChild(styleContainer);

            // 添加统一的底部操作栏
            const actionBar = this._createFloatingActionBar({
                saveText: '💾 保存导出设置',
                onSave: async () => {
                    // 保存样式设置
                    await this.dbManager.saveSetting('exportFontFamily', this.settings.exportFontFamily ?? exportSettings.fontFamily);
                    await this.dbManager.saveSetting('exportFontSize', this.settings.exportFontSize ?? exportSettings.fontSize);
                    await this.dbManager.saveSetting('exportTitleFontSize', this.settings.exportTitleFontSize ?? exportSettings.titleFontSize);
                    await this.dbManager.saveSetting('exportLineHeight', this.settings.exportLineHeight ?? exportSettings.lineHeight);
                    await this.dbManager.saveSetting('exportPageMargin', this.settings.exportPageMargin ?? exportSettings.pageMargin);
                    // 保存导出内容选项
                    await this.dbManager.saveSetting('exportMyAnswer', this.settings.exportMyAnswer ?? exportSettings.exportMyAnswer);
                    await this.dbManager.saveSetting('exportCorrectAnswer', this.settings.exportCorrectAnswer ?? exportSettings.exportCorrectAnswer);
                    await this.dbManager.saveSetting('exportScore', this.settings.exportScore ?? exportSettings.exportScore);
                    await this.dbManager.saveSetting('exportAnalysis', this.settings.exportAnalysis ?? exportSettings.exportAnalysis);
                    Logger.success('导出设置已保存');
                },
                onReset: async () => {
                    if (confirm('确定要重置导出设置为默认值吗?')) {
                        const defaults = this.config.get('exportSettings');
                        // 重置样式设置
                        this.settings.exportFontFamily = defaults.fontFamily;
                        this.settings.exportFontSize = defaults.fontSize;
                        this.settings.exportTitleFontSize = defaults.titleFontSize;
                        this.settings.exportLineHeight = defaults.lineHeight;
                        this.settings.exportPageMargin = defaults.pageMargin;
                        // 重置导出内容选项
                        this.settings.exportMyAnswer = defaults.exportMyAnswer;
                        this.settings.exportCorrectAnswer = defaults.exportCorrectAnswer;
                        this.settings.exportScore = defaults.exportScore;
                        this.settings.exportAnalysis = defaults.exportAnalysis;
                        await this.dbManager.saveSetting('exportFontFamily', defaults.fontFamily);
                        await this.dbManager.saveSetting('exportFontSize', defaults.fontSize);
                        await this.dbManager.saveSetting('exportTitleFontSize', defaults.titleFontSize);
                        await this.dbManager.saveSetting('exportLineHeight', defaults.lineHeight);
                        await this.dbManager.saveSetting('exportPageMargin', defaults.pageMargin);
                        await this.dbManager.saveSetting('exportMyAnswer', defaults.exportMyAnswer);
                        await this.dbManager.saveSetting('exportCorrectAnswer', defaults.exportCorrectAnswer);
                        await this.dbManager.saveSetting('exportScore', defaults.exportScore);
                        await this.dbManager.saveSetting('exportAnalysis', defaults.exportAnalysis);
                        Logger.success('导出设置已重置');
                        this._renderExportSettingsPanel(container);
                    }
                },
                resetText: '🔄 重置导出设置'
            });
            container.appendChild(actionBar);
        }

        /**
         * 创建导出内容勾选框项
         */
        _createExportCheckboxItem(label, description, key, checked) {
            const item = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    alignItems: 'center',
                    padding: '12px',
                    backgroundColor: '#f7fafc',
                    borderRadius: '6px',
                    cursor: 'pointer',
                    transition: 'all 0.2s',
                    border: '1px solid #e2e8f0'
                }
            });

            const checkbox = DOMHelper.createElement('input', {
                type: 'checkbox',
                checked: checked,
                style: {
                    width: '18px',
                    height: '18px',
                    marginRight: '12px',
                    cursor: 'pointer',
                    accentColor: '#4299e1'
                }
            });

            const textContainer = DOMHelper.createElement('div', {
                style: {
                    flex: '1'
                }
            });

            const labelText = DOMHelper.createElement('div', {
                innerText: label,
                style: {
                    fontSize: '14px',
                    fontWeight: '600',
                    color: '#2d3748'
                }
            });

            const descText = DOMHelper.createElement('div', {
                innerText: description,
                style: {
                    fontSize: '12px',
                    color: '#718096',
                    marginTop: '2px'
                }
            });

            textContainer.appendChild(labelText);
            textContainer.appendChild(descText);

            // 点击整个项切换勾选状态
            item.addEventListener('click', (e) => {
                if (e.target !== checkbox) {
                    checkbox.checked = !checkbox.checked;
                }
                this.settings[key] = checkbox.checked;
                item.style.backgroundColor = checkbox.checked ? '#ebf8ff' : '#f7fafc';
                item.style.borderColor = checkbox.checked ? '#4299e1' : '#e2e8f0';
            });

            checkbox.addEventListener('change', () => {
                this.settings[key] = checkbox.checked;
                item.style.backgroundColor = checkbox.checked ? '#ebf8ff' : '#f7fafc';
                item.style.borderColor = checkbox.checked ? '#4299e1' : '#e2e8f0';
            });

            // 初始样式
            if (checked) {
                item.style.backgroundColor = '#ebf8ff';
                item.style.borderColor = '#4299e1';
            }

            // 悬停效果
            item.addEventListener('mouseenter', () => {
                item.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });
            item.addEventListener('mouseleave', () => {
                item.style.boxShadow = 'none';
            });

            item.appendChild(checkbox);
            item.appendChild(textContainer);

            return item;
        }

        /**
         * 创建导出设置项
         */
        _createExportSettingItem(label, description, type, key, value, options = null, step = 1) {
            const item = DOMHelper.createElement('div', {
                style: {
                    marginBottom: '20px',
                    paddingBottom: '20px',
                    borderBottom: '1px solid #e2e8f0'
                }
            });

            const labelEl = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    marginBottom: '8px'
                }
            });

            const labelText = DOMHelper.createElement('span', {
                innerText: label,
                style: {
                    fontSize: '14px',
                    fontWeight: '600',
                    color: '#2d3748'
                }
            });

            let input;
            if (type === 'select' && options) {
                input = DOMHelper.createElement('select', {
                    style: {
                        width: '160px',
                        padding: '6px 12px',
                        border: '1px solid #cbd5e0',
                        borderRadius: '4px',
                        fontSize: '14px',
                        cursor: 'pointer',
                        backgroundColor: 'white'
                    }
                });

                options.forEach(opt => {
                    const option = DOMHelper.createElement('option', {
                        value: opt.value,
                        innerText: opt.label
                    });
                    if (opt.value === value) {
                        option.selected = true;
                    }
                    input.appendChild(option);
                });

                input.addEventListener('change', () => {
                    this.settings[key] = input.value;
                });
            } else if (type === 'number') {
                input = DOMHelper.createElement('input', {
                    type: 'number',
                    value: value,
                    step: step,
                    style: {
                        width: '100px',
                        padding: '6px 12px',
                        border: '1px solid #cbd5e0',
                        borderRadius: '4px',
                        fontSize: '14px',
                        textAlign: 'center'
                    }
                });

                input.addEventListener('change', () => {
                    const numValue = parseFloat(input.value);
                    if (numValue > 0) {
                        this.settings[key] = numValue;
                    }
                });
            } else if (type === 'text') {
                input = DOMHelper.createElement('input', {
                    type: 'text',
                    value: value,
                    style: {
                        width: '200px',
                        padding: '6px 12px',
                        border: '1px solid #cbd5e0',
                        borderRadius: '4px',
                        fontSize: '14px'
                    }
                });

                input.addEventListener('change', () => {
                    this.settings[key] = input.value;
                });
            }

            labelEl.appendChild(labelText);
            labelEl.appendChild(input);

            const desc = DOMHelper.createElement('div', {
                innerText: description,
                style: {
                    fontSize: '12px',
                    color: '#718096',
                    marginTop: '4px'
                }
            });

            item.appendChild(labelEl);
            item.appendChild(desc);

            return item;
        }

        /**
         * 渲染笔记管理面板
         */
        _renderNotesPanel(container) {
            container.innerHTML = '';
            container.style.padding = '0';

            if (this.notesList.length === 0) {
                const emptyMsg = DOMHelper.createElement('div', {
                    innerText: '📭 暂无笔记',
                    style: {
                        textAlign: 'center',
                        color: '#a0aec0',
                        padding: '60px 20px',
                        fontSize: '16px'
                    }
                });
                container.appendChild(emptyMsg);
                return;
            }

            // 操作栏
            const toolbar = DOMHelper.createElement('div', {
                style: {
                    padding: '15px 30px',
                    backgroundColor: 'white',
                    borderBottom: '1px solid #e2e8f0',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center'
                }
            });

            const info = DOMHelper.createElement('span', {
                id: 'notes-info-text',
                innerText: `共 ${this.notesList.length} 条笔记`,
                style: {
                    fontSize: '14px',
                    color: '#718096'
                }
            });

            const actions = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    gap: '10px'
                }
            });

            // 时间排序按钮
            const timeSortBtn = DOMHelper.createElement('button', {
                innerText: this.notesSortBy === 'time' 
                    ? (this.notesSortOrder === 'desc' ? '🕒 时间 ↓' : '🕒 时间 ↑')
                    : '🕒 时间',
                style: {
                    padding: '6px 12px',
                    border: '1px solid #cbd5e0',
                    borderRadius: '4px',
                    backgroundColor: this.notesSortBy === 'time' ? '#4299e1' : 'white',
                    color: this.notesSortBy === 'time' ? 'white' : '#4a5568',
                    cursor: 'pointer',
                    fontSize: '12px',
                    fontWeight: '500',
                    transition: 'all 0.2s'
                }
            });

            timeSortBtn.addEventListener('mouseenter', () => {
                timeSortBtn.style.transform = 'translateY(-1px)';
                timeSortBtn.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });

            timeSortBtn.addEventListener('mouseleave', () => {
                timeSortBtn.style.transform = 'translateY(0)';
                timeSortBtn.style.boxShadow = 'none';
            });

            timeSortBtn.addEventListener('click', () => {
                if (this.notesSortBy === 'time') {
                    // 已经是时间排序,切换升降序
                    this.notesSortOrder = this.notesSortOrder === 'desc' ? 'asc' : 'desc';
                } else {
                    // 切换到时间排序,默认降序(最新在前)
                    this.notesSortBy = 'time';
                    this.notesSortOrder = 'desc';
                }
                this._sortNotes();
                this._renderContent();
            });

            // 字母排序按钮
            const alphaSortBtn = DOMHelper.createElement('button', {
                innerText: this.notesSortBy === 'alpha' 
                    ? (this.notesSortOrder === 'asc' ? '🔤 字母 ↑' : '🔤 字母 ↓')
                    : '🔤 字母',
                style: {
                    padding: '6px 12px',
                    border: '1px solid #cbd5e0',
                    borderRadius: '4px',
                    backgroundColor: this.notesSortBy === 'alpha' ? '#48bb78' : 'white',
                    color: this.notesSortBy === 'alpha' ? 'white' : '#4a5568',
                    cursor: 'pointer',
                    fontSize: '12px',
                    fontWeight: '500',
                    transition: 'all 0.2s'
                }
            });

            alphaSortBtn.addEventListener('mouseenter', () => {
                alphaSortBtn.style.transform = 'translateY(-1px)';
                alphaSortBtn.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });

            alphaSortBtn.addEventListener('mouseleave', () => {
                alphaSortBtn.style.transform = 'translateY(0)';
                alphaSortBtn.style.boxShadow = 'none';
            });

            alphaSortBtn.addEventListener('click', () => {
                if (this.notesSortBy === 'alpha') {
                    // 已经是字母排序,切换升降序
                    this.notesSortOrder = this.notesSortOrder === 'asc' ? 'desc' : 'asc';
                } else {
                    // 切换到字母排序,默认升序(A-Z)
                    this.notesSortBy = 'alpha';
                    this.notesSortOrder = 'asc';
                }
                this._sortNotes();
                this._renderContent();
            });

            const selectAllBtn = DOMHelper.createElement('button', {
                innerText: '全选',
                style: {
                    padding: '6px 12px',
                    border: '1px solid #cbd5e0',
                    borderRadius: '4px',
                    backgroundColor: 'white',
                    cursor: 'pointer',
                    fontSize: '12px',
                    fontWeight: '500',
                    transition: 'all 0.2s'
                }
            });

            selectAllBtn.addEventListener('mouseenter', () => {
                selectAllBtn.style.transform = 'translateY(-1px)';
                selectAllBtn.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });

            selectAllBtn.addEventListener('mouseleave', () => {
                selectAllBtn.style.transform = 'translateY(0)';
                selectAllBtn.style.boxShadow = 'none';
            });

            const deleteBtn = DOMHelper.createElement('button', {
                innerText: '删除选中',
                style: {
                    padding: '6px 12px',
                    border: 'none',
                    borderRadius: '4px',
                    backgroundColor: '#f56565',
                    color: 'white',
                    cursor: 'pointer',
                    fontSize: '12px',
                    fontWeight: '500',
                    transition: 'all 0.2s'
                }
            });

            deleteBtn.addEventListener('mouseenter', () => {
                deleteBtn.style.backgroundColor = '#e53e3e';
                deleteBtn.style.transform = 'translateY(-1px)';
            });

            deleteBtn.addEventListener('mouseleave', () => {
                deleteBtn.style.backgroundColor = '#f56565';
                deleteBtn.style.transform = 'translateY(0)';
            });

            selectAllBtn.addEventListener('click', () => this._toggleSelectAll());
            deleteBtn.addEventListener('click', () => this._deleteSelected());

            actions.appendChild(timeSortBtn);
            actions.appendChild(alphaSortBtn);
            actions.appendChild(selectAllBtn);
            actions.appendChild(deleteBtn);
            toolbar.appendChild(info);
            toolbar.appendChild(actions);

            // 笔记列表
            const notesList = DOMHelper.createElement('div', {
                id: 'notes-list-content',
                style: {
                    padding: '20px 30px',
                    overflow: 'auto',
                    flex: '1'
                }
            });

            if (this.notesScope === 'current') {
                // 当前页面:直接显示笔记列表
                this.notesList.forEach(note => {
                    const noteItem = this._createNoteItem(note);
                    notesList.appendChild(noteItem);
                });
            } else {
                // 其他范围:按 workKey 分组显示
                const groupedNotes = this._groupNotesByWorkKey(this.notesList);
                Object.entries(groupedNotes).forEach(([workKey, notes]) => {
                    const group = this._createNotesGroup(workKey, notes);
                    notesList.appendChild(group);
                });
            }

            container.appendChild(toolbar);
            container.appendChild(notesList);
        }

        /**
         * 创建笔记项
         */
        _createNoteItem(note) {
            const item = DOMHelper.createElement('div', {
                style: {
                    padding: '16px',
                    marginBottom: '12px',
                    border: '1px solid #e2e8f0',
                    borderRadius: '8px',
                    backgroundColor: this.selectedNotes.has(note.id) ? '#ebf8ff' : 'white',
                    cursor: 'pointer',
                    transition: 'all 0.2s'
                }
            });

            item.addEventListener('mouseenter', () => {
                if (!this.selectedNotes.has(note.id)) {
                    item.style.backgroundColor = '#f7fafc';
                }
            });

            item.addEventListener('mouseleave', () => {
                if (!this.selectedNotes.has(note.id)) {
                    item.style.backgroundColor = 'white';
                }
            });

            const header = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    alignItems: 'center',
                    marginBottom: '10px',
                    gap: '10px'
                }
            });

            const checkbox = DOMHelper.createElement('input', {
                type: 'checkbox',
                checked: this.selectedNotes.has(note.id),
                style: {
                    width: '16px',
                    height: '16px',
                    cursor: 'pointer'
                }
            });

            checkbox.addEventListener('change', (e) => {
                e.stopPropagation();
                if (checkbox.checked) {
                    this.selectedNotes.add(note.id);
                    item.style.backgroundColor = '#ebf8ff';
                } else {
                    this.selectedNotes.delete(note.id);
                    item.style.backgroundColor = 'white';
                }
                this._updateNotesInfo();
            });

            const questionId = DOMHelper.createElement('span', {
                innerText: note.questionId,
                style: {
                    fontSize: '14px',
                    fontWeight: '600',
                    color: '#4299e1',
                    flex: '1'
                }
            });

            const time = DOMHelper.createElement('span', {
                innerText: new Date(note.timestamp).toLocaleString('zh-CN'),
                style: {
                    fontSize: '12px',
                    color: '#a0aec0'
                }
            });

            header.appendChild(checkbox);
            header.appendChild(questionId);
            header.appendChild(time);

            const content = DOMHelper.createElement('div', {
                innerText: note.content || '(空笔记)',
                style: {
                    fontSize: '14px',
                    color: note.content ? '#2d3748' : '#a0aec0',
                    lineHeight: '1.6',
                    maxHeight: '80px',
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    whiteSpace: 'pre-wrap'
                }
            });

            item.appendChild(header);
            item.appendChild(content);

            item.addEventListener('click', (e) => {
                if (e.target !== checkbox) {
                    checkbox.checked = !checkbox.checked;
                    checkbox.dispatchEvent(new Event('change'));
                }
            });

            return item;
        }

        /**
         * 切换全选
         */
        _toggleSelectAll() {
            if (this.selectedNotes.size === this.notesList.length) {
                this.selectedNotes.clear();
            } else {
                this.notesList.forEach(note => this.selectedNotes.add(note.id));
            }
            this._renderContent();
        }

        /**
         * 删除选中的笔记
         */
        async _deleteSelected() {
            if (this.selectedNotes.size === 0) {
                alert('请先选择要删除的笔记');
                return;
            }

            if (!confirm(`确定要删除选中的 ${this.selectedNotes.size} 条笔记吗?\n此操作不可恢复!`)) {
                return;
            }

            try {
                const noteIds = Array.from(this.selectedNotes);
                await this.dbManager.deleteNotes(noteIds);
                Logger.success(`已删除 ${noteIds.length} 条笔记`);

                this.selectedNotes.clear();
                await this._loadNotes();
                this._renderContent();
            } catch (error) {
                Logger.error('删除笔记失败', error);
                alert('删除笔记失败,请查看控制台了解详情');
            }
        }

        /**
         * 更新笔记信息
         */
        _updateNotesInfo() {
            const info = document.getElementById('notes-info-text');
            if (info) {
                const selectedText = this.selectedNotes.size > 0 ? `,已选中 ${this.selectedNotes.size} 条` : '';
                info.innerText = `共 ${this.notesList.length} 条笔记${selectedText}`;
            }
        }

        /**
         * 按 workKey 分组笔记
         */
        _groupNotesByWorkKey(notes) {
            const groups = {};
            notes.forEach(note => {
                if (!groups[note.workKey]) {
                    groups[note.workKey] = [];
                }
                groups[note.workKey].push(note);
            });
            // 按时间戳排序每个组
            Object.keys(groups).forEach(key => {
                groups[key].sort((a, b) => b.timestamp - a.timestamp);
            });
            return groups;
        }

        /**
         * 排序笔记
         */
        _sortNotes() {
            if (this.notesSortBy === 'time') {
                // 按时间排序
                if (this.notesSortOrder === 'desc') {
                    // 降序:最新在前
                    this.notesList.sort((a, b) => b.timestamp - a.timestamp);
                } else {
                    // 升序:最旧在前
                    this.notesList.sort((a, b) => a.timestamp - b.timestamp);
                }
            } else {
                // 按 questionId 字母序
                this.notesList.sort((a, b) => {
                    const idA = a.questionId.toLowerCase();
                    const idB = b.questionId.toLowerCase();
                    if (this.notesSortOrder === 'asc') {
                        // 升序:A-Z
                        return idA.localeCompare(idB);
                    } else {
                        // 降序:Z-A
                        return idB.localeCompare(idA);
                    }
                });
            }
        }

        /**
         * 创建笔记组(用于域名模式)
         */
        _createNotesGroup(workKey, notes) {
            const group = DOMHelper.createElement('div', {
                style: {
                    marginBottom: '30px'
                }
            });

            // 组标题
            const groupHeader = DOMHelper.createElement('div', {
                style: {
                    padding: '12px 16px',
                    backgroundColor: '#e3f2fd',
                    borderRadius: '8px',
                    marginBottom: '12px',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    cursor: 'pointer',
                    transition: 'all 0.2s'
                }
            });

            const headerLeft = DOMHelper.createElement('div', {
                style: {
                    display: 'flex',
                    alignItems: 'center',
                    gap: '10px'
                }
            });

            const collapseIcon = DOMHelper.createElement('span', {
                innerText: '▼',
                style: {
                    fontSize: '12px',
                    color: '#1976d2',
                    transition: 'transform 0.2s'
                }
            });

            // 格式化 workKey 显示
            const parts = workKey.split('_');
            let displayText = '📄 ';
            if (parts.length === 3) {
                displayText += `Course${parts[0]}_Class${parts[1]}_Work${parts[2]}`;
            } else {
                displayText += workKey;
            }

            const groupTitle = DOMHelper.createElement('span', {
                innerText: displayText,
                style: {
                    fontSize: '14px',
                    fontWeight: '600',
                    color: '#1976d2'
                }
            });

            const groupCount = DOMHelper.createElement('span', {
                innerText: `(${notes.length} 条)`,
                style: {
                    fontSize: '13px',
                    color: '#64b5f6',
                    marginLeft: '8px'
                }
            });

            headerLeft.appendChild(collapseIcon);
            headerLeft.appendChild(groupTitle);
            headerLeft.appendChild(groupCount);

            // 全选此组的按钮
            const selectGroupBtn = DOMHelper.createElement('button', {
                innerText: '全选',
                style: {
                    padding: '4px 10px',
                    border: '1px solid #2196f3',
                    borderRadius: '4px',
                    backgroundColor: 'white',
                    color: '#2196f3',
                    cursor: 'pointer',
                    fontSize: '12px',
                    fontWeight: '500',
                    transition: 'all 0.2s'
                }
            });

            selectGroupBtn.addEventListener('mouseenter', () => {
                selectGroupBtn.style.transform = 'translateY(-1px)';
                selectGroupBtn.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });

            selectGroupBtn.addEventListener('mouseleave', () => {
                selectGroupBtn.style.transform = 'translateY(0)';
                selectGroupBtn.style.boxShadow = 'none';
            });

            selectGroupBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                const allSelected = notes.every(note => this.selectedNotes.has(note.id));
                if (allSelected) {
                    notes.forEach(note => this.selectedNotes.delete(note.id));
                    selectGroupBtn.innerText = '全选';
                } else {
                    notes.forEach(note => this.selectedNotes.add(note.id));
                    selectGroupBtn.innerText = '取消';
                }
                this._renderContent();
            });

            groupHeader.appendChild(headerLeft);
            groupHeader.appendChild(selectGroupBtn);

            // 笔记列表容器
            const notesContainer = DOMHelper.createElement('div', {
                style: {
                    display: 'block',
                    paddingLeft: '20px'
                }
            });

            notes.forEach(note => {
                const noteItem = this._createNoteItem(note);
                notesContainer.appendChild(noteItem);
            });

            // 折叠/展开功能
            let isCollapsed = false;
            groupHeader.addEventListener('click', (e) => {
                if (e.target === selectGroupBtn) return;
                isCollapsed = !isCollapsed;
                notesContainer.style.display = isCollapsed ? 'none' : 'block';
                collapseIcon.style.transform = isCollapsed ? 'rotate(-90deg)' : 'rotate(0deg)';
            });

            group.appendChild(groupHeader);
            group.appendChild(notesContainer);

            return group;
        }

        /**
         * 渲染样式管理面板
         */
        async _renderStylesPanel(container) {
            container.innerHTML = '';

            // 样式配置的分类
            const styleCategories = [
                {
                    title: '答案按钮样式',
                    key: 'answerButton',
                    fields: [
                        // 位置配置
                        { name: 'marginLeft', label: '左边距', type: 'text', path: 'position.marginLeft' },
                        { name: 'marginTop', label: '上边距', type: 'text', path: 'position.marginTop' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'showBackground', label: '显示按钮背景色', type: 'color', path: 'colors.showBackground' },
                        { name: 'hideBackground', label: '隐藏按钮背景色', type: 'color', path: 'colors.hideBackground' },
                        { name: 'showHoverBackground', label: '显示按钮悬停色', type: 'color', path: 'colors.showHoverBackground' },
                        { name: 'hideHoverBackground', label: '隐藏按钮悬停色', type: 'color', path: 'colors.hideHoverBackground' }
                    ]
                },
                {
                    title: '笔记按钮样式',
                    key: 'noteButton',
                    fields: [
                        // 位置配置
                        { name: 'marginLeft', label: '左边距', type: 'text', path: 'position.marginLeft' },
                        { name: 'marginTop', label: '上边距', type: 'text', path: 'position.marginTop' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'showBackground', label: '显示按钮背景色', type: 'color', path: 'colors.showBackground' },
                        { name: 'hideBackground', label: '隐藏按钮背景色', type: 'color', path: 'colors.hideBackground' },
                        { name: 'showHoverBackground', label: '显示按钮悬停色', type: 'color', path: 'colors.showHoverBackground' },
                        { name: 'hideHoverBackground', label: '隐藏按钮悬停色', type: 'color', path: 'colors.hideHoverBackground' }
                    ]
                },
                {
                    title: '编辑按钮样式',
                    key: 'editModeButton',
                    fields: [
                        // 位置配置
                        { name: 'marginLeft', label: '左边距', type: 'text', path: 'position.marginLeft' },
                        { name: 'marginTop', label: '上边距', type: 'text', path: 'position.marginTop' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'editBackground', label: '编辑模式背景色', type: 'color', path: 'colors.editBackground' },
                        { name: 'previewBackground', label: '预览模式背景色', type: 'color', path: 'colors.previewBackground' },
                        { name: 'editHoverBackground', label: '编辑模式悬停色', type: 'color', path: 'colors.editHoverBackground' },
                        { name: 'previewHoverBackground', label: '预览模式悬停色', type: 'color', path: 'colors.previewHoverBackground' }
                    ]
                },
                {
                    title: '保存按钮样式',
                    key: 'saveNoteButton',
                    fields: [
                        // 位置配置
                        { name: 'marginLeft', label: '左边距', type: 'text', path: 'position.marginLeft' },
                        { name: 'marginTop', label: '上边距', type: 'text', path: 'position.marginTop' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'background', label: '背景色', type: 'color', path: 'colors.background' },
                        { name: 'hoverBackground', label: '悬停背景色', type: 'color', path: 'colors.hoverBackground' }
                    ]
                },
                {
                    title: '全局按钮样式',
                    key: 'globalButton',
                    fields: [
                        // 位置配置
                        { name: 'top', label: '距顶部距离', type: 'text', path: 'position.top' },
                        { name: 'right', label: '距右侧距离', type: 'text', path: 'position.right' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'showAllBackground', label: '显示全部背景色', type: 'color', path: 'colors.showAllBackground' },
                        { name: 'hideAllBackground', label: '隐藏全部背景色', type: 'color', path: 'colors.hideAllBackground' },
                        { name: 'showAllHoverBackground', label: '显示全部悬停色', type: 'color', path: 'colors.showAllHoverBackground' },
                        { name: 'hideAllHoverBackground', label: '隐藏全部悬停色', type: 'color', path: 'colors.hideAllHoverBackground' }
                    ]
                },
                {
                    title: '控制面板按钮样式',
                    key: 'manageButton',
                    fields: [
                        // 位置配置
                        { name: 'top', label: '距顶部距离', type: 'text', path: 'position.top' },
                        { name: 'right', label: '距右侧距离', type: 'text', path: 'position.right' },
                        // 尺寸配置
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'style.fontSize' },
                        { name: 'padding', label: '内边距', type: 'text', path: 'style.padding' },
                        { name: 'borderRadius', label: '圆角半径', type: 'text', path: 'style.borderRadius' },
                        { name: 'fontWeight', label: '字体粗细', type: 'text', path: 'style.fontWeight' },
                        // 颜色配置
                        { name: 'background', label: '背景色', type: 'color', path: 'colors.background' },
                        { name: 'hoverBackground', label: '悬停背景色', type: 'color', path: 'colors.hoverBackground' }
                    ]
                },
                {
                    title: '笔记编辑器样式',
                    key: 'noteEditor',
                    fields: [
                        { name: 'width', label: '宽度', type: 'text', path: 'width' },
                        { name: 'minHeight', label: '最小高度', type: 'text', path: 'minHeight' },
                        { name: 'maxHeight', label: '最大高度', type: 'text', path: 'maxHeight' },
                        { name: 'fontSize', label: '字体大小', type: 'text', path: 'fontSize' },
                        { name: 'backgroundColor', label: '背景色', type: 'color', path: 'backgroundColor' },
                        { name: 'borderColor', label: '边框颜色', type: 'color', path: 'borderColor' }
                    ]
                }
            ];

            // 加载已保存的样式配置
            const savedStyles = await this.dbManager.getSetting('customStyles', {});

            // 创建滚动容器
            const scrollContainer = DOMHelper.createElement('div', {
                style: {
                    overflow: 'auto',
                    padding: '20px'
                }
            });

            // 为每个分类创建配置区块
            styleCategories.forEach(category => {
                const section = this._createStyleSection(category, savedStyles);
                scrollContainer.appendChild(section);
            });

            container.appendChild(scrollContainer);

            // 添加统一的底部操作栏
            const actionBar = this._createFloatingActionBar({
                saveText: '💾 保存样式设置',
                onSave: async () => {
                    const customStyles = {};
                    
                    // 收集所有表单数据
                    styleCategories.forEach(category => {
                        category.fields.forEach(field => {
                            const input = document.getElementById(`style-${category.key}-${field.name}`);
                            if (input && input.value) {
                                if (!customStyles[category.key]) {
                                    customStyles[category.key] = {};
                                }
                                // 设置嵌套属性
                                const pathParts = field.path.split('.');
                                let target = customStyles[category.key];
                                for (let i = 0; i < pathParts.length - 1; i++) {
                                    if (!target[pathParts[i]]) {
                                        target[pathParts[i]] = {};
                                    }
                                    target = target[pathParts[i]];
                                }
                                target[pathParts[pathParts.length - 1]] = input.value;
                            }
                        });
                    });

                    await this.dbManager.saveSetting('customStyles', customStyles);
                    Logger.success('样式已保存,刷新页面后生效');
                },
                onReset: async () => {
                    if (confirm('确定要重置所有样式为默认值吗?')) {
                        await this.dbManager.saveSetting('customStyles', {});
                        Logger.success('样式已重置');
                        this._renderStylesPanel(container);
                    }
                },
                resetText: '🔄 重置样式设置'
            });
            container.appendChild(actionBar);
        }

        /**
         * 创建样式配置区块
         */
        _createStyleSection(category, savedStyles) {
            const section = DOMHelper.createElement('div', {
                style: {
                    backgroundColor: 'white',
                    borderRadius: '8px',
                    padding: '20px',
                    marginBottom: '20px',
                    boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'
                }
            });

            const title = DOMHelper.createElement('h3', {
                innerText: category.title,
                style: {
                    margin: '0 0 16px 0',
                    fontSize: '16px',
                    fontWeight: '600',
                    color: '#2d3748',
                    borderBottom: '2px solid #4299e1',
                    paddingBottom: '8px'
                }
            });

            section.appendChild(title);

            category.fields.forEach(field => {
                const fieldGroup = DOMHelper.createElement('div', {
                    style: {
                        marginBottom: '16px',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'space-between'
                    }
                });

                const label = DOMHelper.createElement('label', {
                    innerText: field.label,
                    style: {
                        fontSize: '14px',
                        color: '#4a5568',
                        fontWeight: '500',
                        flex: '1'
                    }
                });

                // 获取当前值(优先使用保存的值,否则使用默认配置值)
                let currentValue;
                if (savedStyles[category.key]) {
                    const pathParts = field.path.split('.');
                    let value = savedStyles[category.key];
                    for (let part of pathParts) {
                        value = value?.[part];
                    }
                    currentValue = value;
                }
                
                if (!currentValue) {
                    const pathParts = field.path.split('.');
                    let value = this.config.get(category.key);
                    for (let part of pathParts) {
                        value = value?.[part];
                    }
                    currentValue = value || '';
                }

                const input = DOMHelper.createElement('input', {
                    type: field.type,
                    value: currentValue,
                    id: `style-${category.key}-${field.name}`,
                    style: {
                        width: field.type === 'color' ? '60px' : '150px',
                        padding: '6px 10px',
                        border: '1px solid #cbd5e0',
                        borderRadius: '4px',
                        fontSize: '13px'
                    }
                });

                fieldGroup.appendChild(label);
                fieldGroup.appendChild(input);
                section.appendChild(fieldGroup);
            });

            return section;
        }

        /**
         * 关闭模态框
         */
        _close() {
            if (this.modal && this.modal.parentNode) {
                document.body.removeChild(this.modal);
                this.modal = null;
            }
        }
    }

    // ===================== DOM 工具类 =====================
    class DOMHelper {
        static createElement(tag, attributes = {}) {
            const element = document.createElement(tag);
            Object.entries(attributes).forEach(([key, value]) => {
                if (key === 'style' && typeof value === 'object') {
                    Object.assign(element.style, value);
                } else if (key === 'dataset' && typeof value === 'object') {
                    Object.entries(value).forEach(([dataKey, dataValue]) => {
                        element.dataset[dataKey] = dataValue;
                    });
                } else {
                    element[key] = value;
                }
            });
            return element;
        }

        static insertElement(element, parent, nextSibling = null) {
            if (nextSibling) {
                parent.insertBefore(element, nextSibling);
            } else {
                parent.appendChild(element);
            }
        }

        static removeElement(element) {
            element?.parentNode?.removeChild(element);
        }

        static ensureRelativePosition(element) {
            if (getComputedStyle(element).position === 'static') {
                element.style.position = 'relative';
            }
        }
    }

    // ===================== 样式生成器 =====================
    class StyleGenerator {
        constructor(config) {
            this.config = config;
        }

        // ========== 通用按钮样式生成方法 ==========
        
        /**
         * 生成内联按钮样式(答案、笔记、保存、编辑等按钮)
         * @param {string} configKey - 配置键名(如 'answerButton', 'noteButton')
         * @param {string} bgColorKey - 背景色配置键名
         * @returns {Object} 样式对象
         */
        _getInlineButtonStyle(configKey, bgColorKey) {
            const position = this.config.get(`${configKey}.position`);
            const style = this.config.get(`${configKey}.style`);
            const colors = this.config.get(`${configKey}.colors`);

            const result = {
                marginLeft: position.marginLeft,
                marginRight: position.marginRight,
                marginTop: position.marginTop,
                marginBottom: position.marginBottom,
                verticalAlign: position.verticalAlign,
                padding: style.padding,
                border: style.border,
                borderRadius: style.borderRadius,
                background: colors[bgColorKey],
                color: colors.textColor,
                fontSize: style.fontSize,
                fontWeight: style.fontWeight,
                cursor: style.cursor,
                transition: style.transition,
                boxShadow: style.boxShadow,
                display: 'inline-block'
            };

            // 可选属性:minWidth 和 textAlign
            if (style.minWidth) {
                result.minWidth = style.minWidth;
            }
            if (style.textAlign) {
                result.textAlign = style.textAlign;
            }

            return result;
        }

        /**
         * 生成浮动按钮样式(全局、控制面板按钮)
         * @param {string} configKey - 配置键名
         * @param {string} bgColorKey - 背景色配置键名
         * @returns {Object} 样式对象
         */
        _getFloatingButtonStyle(configKey, bgColorKey) {
            const style = this.config.get(`${configKey}.style`);
            const colors = this.config.get(`${configKey}.colors`);

            return {
                display: 'inline-block',
                whiteSpace: 'nowrap',
                border: style.border,
                borderRadius: style.borderRadius,
                padding: style.padding,
                fontSize: style.fontSize,
                fontWeight: style.fontWeight,
                color: colors.textColor,
                cursor: style.cursor,
                transition: style.transition,
                boxShadow: style.boxShadow,
                background: colors[bgColorKey]
            };
        }

        // ========== 具体按钮样式获取方法 ==========

        getCopyButtonStyle() {
            const position = this.config.get('copyButton.position');
            const style = this.config.get('copyButton.style');
            const colors = this.config.get('copyButton.colors');
            
            return {
                position: 'absolute',
                top: position.top,
                right: position.right,
                zIndex: '100',
                fontSize: style.fontSize,
                padding: style.padding,
                borderRadius: style.borderRadius,
                border: style.border,
                fontWeight: style.fontWeight,
                cursor: style.cursor,
                transition: style.transition,
                boxShadow: style.boxShadow,
                minWidth: style.minWidth,
                textAlign: style.textAlign,
                background: colors.background,
                color: colors.textColor
            };
        }

        getAnswerButtonStyle(isHidden = true) {
            return this._getInlineButtonStyle('answerButton', isHidden ? 'showBackground' : 'hideBackground');
        }

        getNoteButtonStyle(isVisible = false) {
            return this._getInlineButtonStyle('noteButton', isVisible ? 'hideBackground' : 'showBackground');
        }

        getSaveNoteButtonStyle() {
            return this._getInlineButtonStyle('saveNoteButton', 'background');
        }

        getEditModeButtonStyle(isEditMode = false) {
            return this._getInlineButtonStyle('editModeButton', isEditMode ? 'previewBackground' : 'editBackground');
        }

        getGlobalButtonStyle(isHidden = true) {
            return this._getFloatingButtonStyle('globalButton', isHidden ? 'showAllBackground' : 'hideAllBackground');
        }

        getManageButtonStyle() {
            return this._getFloatingButtonStyle('manageButton', 'background');
        }

        getExportButtonStyle() {
            return this._getFloatingButtonStyle('exportButton', 'background');
        }

        // ========== 悬停效果管理 ==========

        /**
         * 为按钮添加统一的悬停动画效果
         * @param {HTMLElement} button - 按钮元素
         * @param {Object} options - 配置选项
         * @param {Function} options.getHoverBg - 获取悬停背景色的函数
         * @param {Function} options.getNormalBg - 获取正常背景色的函数
         */
        addHoverEffect(button, options) {
            const { getHoverBg, getNormalBg } = options;
            
            button.addEventListener('mouseenter', () => {
                button.style.backgroundColor = getHoverBg();
                button.style.transform = 'translateY(-1px)';
                button.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
            });

            button.addEventListener('mouseleave', () => {
                button.style.backgroundColor = getNormalBg();
                button.style.transform = 'translateY(0)';
                button.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)';
            });
        }

        /**
         * 为双状态按钮添加悬停效果(如显示/隐藏按钮)
         * @param {HTMLElement} button - 按钮元素
         * @param {string} configKey - 配置键名
         * @param {Function} getState - 获取当前状态的函数
         * @param {string} trueHoverKey - 状态为true时的悬停色配置键
         * @param {string} falseHoverKey - 状态为false时的悬停色配置键
         * @param {string} trueBgKey - 状态为true时的背景色配置键
         * @param {string} falseBgKey - 状态为false时的背景色配置键
         */
        addToggleHoverEffect(button, configKey, getState, trueHoverKey, falseHoverKey, trueBgKey, falseBgKey) {
            const colors = this.config.get(`${configKey}.colors`);
            
            this.addHoverEffect(button, {
                getHoverBg: () => getState() ? colors[trueHoverKey] : colors[falseHoverKey],
                getNormalBg: () => getState() ? colors[trueBgKey] : colors[falseBgKey]
            });
        }

        /**
         * 为单状态按钮添加悬停效果
         * @param {HTMLElement} button - 按钮元素
         * @param {string} configKey - 配置键名
         */
        addSimpleHoverEffect(button, configKey) {
            const colors = this.config.get(`${configKey}.colors`);
            
            this.addHoverEffect(button, {
                getHoverBg: () => colors.hoverBackground,
                getNormalBg: () => colors.background
            });
        }

        // ========== 笔记编辑器样式 ==========

        getNoteEditorStyle() {
            const noteConfig = this.config.get('noteEditor');

            return {
                width: noteConfig.width || '100%',
                minHeight: noteConfig.minHeight,
                maxHeight: noteConfig.maxHeight,
                padding: noteConfig.padding,
                marginTop: noteConfig.marginTop,
                marginBottom: noteConfig.marginBottom,
                fontSize: noteConfig.fontSize,
                border: `${noteConfig.borderWidth} ${noteConfig.borderStyle} ${noteConfig.borderColor}`,
                borderRadius: noteConfig.borderRadius,
                backgroundColor: noteConfig.backgroundColor,
                color: noteConfig.textColor,
                resize: noteConfig.resize,
                fontFamily: noteConfig.fontFamily,
                outline: 'none',
                display: 'none',
                transition: 'border-color 0.2s',
                boxSizing: 'border-box'
            };
        }
    }

    // ===================== 答案块控制器 =====================
    class AnswerBlockController {
        constructor(block, config, styleGenerator, dbManager, workKey) {
            this.block = block;
            this.config = config;
            this.styleGenerator = styleGenerator;
            this.dbManager = dbManager;
            this.workKey = workKey;
            this.parent = block.parentNode;
            this.nextSibling = block.nextSibling;
            this.originalHTML = block.outerHTML;
            this.toggleButton = null;
            this.noteButton = null;
            this.saveNoteButton = null;
            this.noteEditor = null;
            this.buttonContainer = null;
            this.currentAnswerBlock = null;  // 跟踪当前显示的答案块
            this.isHidden = false;
            this.questionId = this._extractQuestionId();
        }

        _extractQuestionId() {
            // 从父元素中查找包含 question 的 id
            let element = this.block;
            while (element && element !== document.body) {
                if (element.id && element.id.startsWith('question')) {
                    return element.id;
                }
                element = element.parentElement;
            }
            // 如果没找到,生成一个唯一标识
            return `question_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        }

        async initialize() {
            this._hideBlockInitial();
            await this._createButtons();
            await this._createNoteEditor();
            return this.buttonContainer;
        }

        _hideBlockInitial() {
            // 初始化时删除原始答案块
            DOMHelper.removeElement(this.block);
            this.currentAnswerBlock = null;
            this.isHidden = true;
        }

        async _createButtons() {
            // 创建按钮容器
            this.buttonContainer = DOMHelper.createElement('div', {
                style: {
                    display: 'inline-block',
                    marginLeft: this.config.get('answerButton.position.marginLeft'),
                    marginRight: this.config.get('answerButton.position.marginLeft'), // 使右边距与左边距一致
                    marginTop: this.config.get('answerButton.position.marginTop'),
                    verticalAlign: this.config.get('answerButton.position.verticalAlign')
                }
            });

            // 创建复制按钮(定位到题目区域右上角)
            this._createCopyButton();

            // 创建答案切换按钮
            this._createAnswerToggleButton();

            // 创建笔记切换按钮
            this._createNoteToggleButton();

            // 创建编辑/预览切换按钮
            this._createEditModeToggleButton();

            // 创建保存笔记按钮
            this._createSaveNoteButton();

            // 插入按钮容器
            DOMHelper.insertElement(this.buttonContainer, this.parent, this.nextSibling);
        }

        _createCopyButton() {
            const buttonText = this.config.get('copyButton.text');
            const colors = this.config.get('copyButton.colors');
            
            this.copyButton = DOMHelper.createElement('button', {
                innerText: buttonText.copy,
                style: this.styleGenerator.getCopyButtonStyle(),
                title: '复制题目和选项(纯文本)'
            });

            // 添加悬停效果
            this.copyButton.addEventListener('mouseenter', () => {
                this.copyButton.style.background = colors.hoverBackground;
                this.copyButton.style.transform = 'translateY(-1px)';
            });
            this.copyButton.addEventListener('mouseleave', () => {
                this.copyButton.style.background = colors.background;
                this.copyButton.style.transform = 'translateY(0)';
            });

            this.copyButton.addEventListener('click', () => this._handleCopy());
            
            // 查找题目容器并插入复制按钮到右上角
            let questionContainer = null;
            const questionId = this.questionId;
            
            if (questionId && questionId.startsWith('question')) {
                questionContainer = document.getElementById(questionId);
            }
            
            // 如果没找到,尝试从 parent 向上查找
            if (!questionContainer && this.parent) {
                let element = this.parent;
                while (element && element !== document.body) {
                    if (element.classList && (element.classList.contains('questionLi') || element.classList.contains('mark_item'))) {
                        questionContainer = element;
                        break;
                    }
                    element = element.parentElement;
                }
            }
            
            // 将复制按钮插入到题目容器
            if (questionContainer) {
                // 确保题目容器有相对定位
                const currentPosition = window.getComputedStyle(questionContainer).position;
                if (currentPosition === 'static') {
                    questionContainer.style.position = 'relative';
                }
                questionContainer.appendChild(this.copyButton);
            } else {
                // 如果找不到题目容器,则添加到按钮容器中作为备选
                this.buttonContainer.appendChild(this.copyButton);
            }
        }

        _handleCopy() {
            const buttonText = this.config.get('copyButton.text');
            const colors = this.config.get('copyButton.colors');
            
            // 获取题目容器
            let questionContainer = null;
            const questionId = this.questionId;
            
            if (questionId && questionId.startsWith('question')) {
                questionContainer = document.getElementById(questionId);
            }
            
            // 如果没找到,尝试从 parent 向上查找
            if (!questionContainer && this.parent) {
                let element = this.parent;
                while (element && element !== document.body) {
                    if (element.classList && (element.classList.contains('questionLi') || element.classList.contains('mark_item'))) {
                        questionContainer = element;
                        break;
                    }
                    element = element.parentElement;
                }
            }

            if (!questionContainer) {
                Logger.error('未找到题目容器');
                return;
            }

            // 提取题目文本
            let copyText = '';
            
            // 1. 获取题号和题型(如 "1. (单选题, 3分)")
            const markName = questionContainer.querySelector('.mark_name');
            if (markName) {
                // 提取题号
                const firstTextNode = markName.childNodes[0];
                if (firstTextNode && firstTextNode.nodeType === Node.TEXT_NODE) {
                    copyText += firstTextNode.textContent.trim();
                }
                
                // 提取题型和分值
                const colorShallow = markName.querySelector('.colorShallow');
                if (colorShallow) {
                    copyText += ' ' + colorShallow.textContent.trim();
                }
                
                // 提取题干
                const qtContent = markName.querySelector('.qtContent');
                if (qtContent) {
                    copyText += ' ' + qtContent.textContent.trim();
                }
                copyText += '\n';
            }
            
            // 2. 获取选项(单选/多选题)
            const markLetter = questionContainer.querySelector('ul.mark_letter');
            if (markLetter) {
                const options = markLetter.querySelectorAll('li');
                options.forEach(option => {
                    copyText += option.textContent.trim() + '\n';
                });
            }
            
            // 3. 获取完型填空/填空题选项
            const markGestalt = questionContainer.querySelector('div.mark_gestalt');
            if (markGestalt) {
                const rows = markGestalt.querySelectorAll('.gestalt_row, dl');
                rows.forEach(row => {
                    const dt = row.querySelector('dt');
                    if (dt) {
                        copyText += dt.textContent.trim() + '\n';
                    }
                    const dds = row.querySelectorAll('dd');
                    dds.forEach(dd => {
                        copyText += '  ' + dd.textContent.trim() + '\n';
                    });
                });
            }

            // 复制到剪贴板
            navigator.clipboard.writeText(copyText.trim()).then(() => {
                // 复制成功,更新按钮状态
                this.copyButton.innerText = buttonText.copied;
                this.copyButton.style.background = colors.successBackground;
                
                // 2秒后恢复原状
                setTimeout(() => {
                    this.copyButton.innerText = buttonText.copy;
                    this.copyButton.style.background = colors.background;
                }, 2000);
            }).catch(err => {
                console.error('复制失败:', err);
                // 尝试使用传统方法
                const textarea = document.createElement('textarea');
                textarea.value = copyText.trim();
                textarea.style.position = 'fixed';
                textarea.style.opacity = '0';
                document.body.appendChild(textarea);
                textarea.select();
                try {
                    document.execCommand('copy');
                    this.copyButton.innerText = buttonText.copied;
                    this.copyButton.style.background = colors.successBackground;
                    setTimeout(() => {
                        this.copyButton.innerText = buttonText.copy;
                        this.copyButton.style.background = colors.background;
                    }, 2000);
                } catch (e) {
                    Logger.error('复制失败');
                }
                document.body.removeChild(textarea);
            });
        }

        _createAnswerToggleButton() {
            const buttonText = this.config.get('answerButton.text');
            this.toggleButton = DOMHelper.createElement('button', {
                innerText: buttonText.show,
                style: this.styleGenerator.getAnswerButtonStyle(true),
                title: '点击显示/隐藏当前答案块',
                dataset: {
                    isHidden: 'true',
                    originalHTML: this.originalHTML
                }
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addToggleHoverEffect(
                this.toggleButton,
                'answerButton',
                () => this.toggleButton.dataset.isHidden === 'true',
                'showHoverBackground', 'hideHoverBackground',
                'showBackground', 'hideBackground'
            );

            this.toggleButton.addEventListener('click', () => this._handleAnswerToggle());
            this.buttonContainer.appendChild(this.toggleButton);
        }

        _createNoteToggleButton() {
            const buttonText = this.config.get('noteButton.text');
            this.noteButton = DOMHelper.createElement('button', {
                innerText: buttonText.show,
                style: this.styleGenerator.getNoteButtonStyle(false),
                title: '点击显示/隐藏笔记编辑器',
                dataset: {
                    isVisible: 'false'
                }
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addToggleHoverEffect(
                this.noteButton,
                'noteButton',
                () => !this.noteEditor.isVisible,
                'showHoverBackground', 'hideHoverBackground',
                'showBackground', 'hideBackground'
            );

            this.noteButton.addEventListener('click', () => this._handleNoteToggle());
            this.buttonContainer.appendChild(this.noteButton);
        }

        _createEditModeToggleButton() {
            const buttonText = this.config.get('editModeButton.text');
            const style = this.styleGenerator.getEditModeButtonStyle(false);
            style.display = 'none'; // 初始隐藏
            
            this.editModeButton = DOMHelper.createElement('button', {
                innerText: buttonText.edit,
                style: style,
                title: '切换编辑/预览模式'
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addToggleHoverEffect(
                this.editModeButton,
                'editModeButton',
                () => !this.noteEditor.isEditMode,
                'editHoverBackground', 'previewHoverBackground',
                'editBackground', 'previewBackground'
            );

            this.editModeButton.addEventListener('click', () => {
                const buttonText = this.config.get('editModeButton.text');
                const colors = this.config.get('editModeButton.colors');
                this.noteEditor.toggleEditMode();
                
                if (this.noteEditor.isEditMode) {
                    this.editModeButton.innerText = buttonText.preview;
                    this.editModeButton.style.backgroundColor = colors.previewBackground;
                    // 编辑模式显示保存按钮
                    this.saveNoteButton.style.display = 'inline-block';
                } else {
                    this.editModeButton.innerText = buttonText.edit;
                    this.editModeButton.style.backgroundColor = colors.editBackground;
                    // 预览模式隐藏保存按钮
                    this.saveNoteButton.style.display = 'none';
                }
            });

            this.buttonContainer.appendChild(this.editModeButton);
        }

        _createSaveNoteButton() {
            const buttonText = this.config.get('saveNoteButton.text');
            const colors = this.config.get('saveNoteButton.colors');
            const style = this.styleGenerator.getSaveNoteButtonStyle();
            style.display = 'none'; // 初始隐藏
            this.saveNoteButton = DOMHelper.createElement('button', {
                innerText: buttonText.save,
                style: style,
                title: '手动保存当前笔记'
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addSimpleHoverEffect(this.saveNoteButton, 'saveNoteButton');

            this.saveNoteButton.addEventListener('click', async () => {
                await this.noteEditor.save();
                Logger.success('💾 笔记已保存');
                
                // 点击反馈:文字和颜色变化
                this.saveNoteButton.innerText = buttonText.saved;
                this.saveNoteButton.style.background = colors.successBackground;
                
                // 2秒后恢复原状
                setTimeout(() => {
                    this.saveNoteButton.innerText = buttonText.save;
                    this.saveNoteButton.style.background = colors.background;
                }, 2000);
            });
            this.buttonContainer.appendChild(this.saveNoteButton);
        }

        async _createNoteEditor() {
            this.noteEditor = new NoteEditor(
                this.questionId,
                this.workKey,
                this.dbManager,
                this.config,
                this.styleGenerator
            );

            const editorElement = await this.noteEditor.create();

            // 将编辑器插入到按钮容器之后
            DOMHelper.insertElement(editorElement, this.parent, this.buttonContainer.nextSibling);
        }

        _handleAnswerToggle() {
            if (this.isHidden) {
                this._showBlock();
            } else {
                this._hideBlock();
            }
            this._updateAnswerButtonState();
        }

        _showBlock() {
            // 如果已经有显示的答案块,先删除它(防止重复)
            if (this.currentAnswerBlock && this.currentAnswerBlock.parentNode) {
                DOMHelper.removeElement(this.currentAnswerBlock);
            }

            const tempContainer = document.createElement('div');
            tempContainer.innerHTML = this.originalHTML;
            const restoredBlock = tempContainer.firstChild;

            // 保存对新创建的答案块的引用
            this.currentAnswerBlock = restoredBlock;

            // 插入到笔记编辑器之后(如果可见)或按钮容器之后
            const insertAfter = this.noteEditor.isVisible ?
                this.noteEditor.getElement().nextSibling :
                this.buttonContainer.nextSibling;
            DOMHelper.insertElement(restoredBlock, this.parent, insertAfter);
            this.isHidden = false;
        }

        _hideBlock() {
            // 删除当前显示的答案块
            if (this.currentAnswerBlock && this.currentAnswerBlock.parentNode) {
                DOMHelper.removeElement(this.currentAnswerBlock);
                this.currentAnswerBlock = null;
            }
            this.isHidden = true;
        }

        _updateAnswerButtonState() {
            const buttonText = this.config.get('answerButton.text');
            const colors = this.config.get('answerButton.colors');

            this.toggleButton.innerText = this.isHidden ? buttonText.show : buttonText.hide;
            this.toggleButton.style.background = this.isHidden ? colors.showBackground : colors.hideBackground;
            this.toggleButton.dataset.isHidden = String(this.isHidden);
        }

        _handleNoteToggle() {
            this.noteEditor.toggle();
            this._updateNoteButtonState();
        }

        _updateNoteButtonState() {
            const buttonText = this.config.get('noteButton.text');
            const colors = this.config.get('noteButton.colors');

            this.noteButton.innerText = this.noteEditor.isVisible ? buttonText.hide : buttonText.show;
            this.noteButton.style.background = this.noteEditor.isVisible ? colors.hideBackground : colors.showBackground;
            this.noteButton.dataset.isVisible = String(this.noteEditor.isVisible);
            
            // 联动控制编辑按钮的显示/隐藏
            if (this.noteEditor.isVisible) {
                this.editModeButton.style.display = 'inline-block';
                // 保存按钮只在编辑模式下显示
                if (this.noteEditor.isEditMode) {
                    this.saveNoteButton.style.display = 'inline-block';
                } else {
                    this.saveNoteButton.style.display = 'none';
                }
            } else {
                this.editModeButton.style.display = 'none';
                this.saveNoteButton.style.display = 'none';
            }
        }

        toggle() {
            this._handleAnswerToggle();
        }

        getState() {
            return this.isHidden;
        }
    }

    // ===================== 全局控制器 =====================
    class GlobalController {
        constructor(container, controllers, config, styleGenerator, dbManager, workKey) {
            this.container = container;
            this.controllers = controllers;
            this.config = config;
            this.styleGenerator = styleGenerator;
            this.dbManager = dbManager;
            this.workKey = workKey;
            this.globalButton = null;
            this.manageButton = null;
            this.exportButton = null;
            this.buttonContainer = null;
        }

        initialize() {
            if (!this.container) return null;

            // 将按钮放到 fanyaMarking_right 的右侧外部
            this._createButtonContainer();
            // 注意:按钮创建顺序决定显示顺序(上到下/左到右)
            this._createManageButton();     // 控制面板在最上面
            this._createGlobalButton();     // 显示全部答案在第二
            this._createExportButton();     // 导出按钮在下面
            return this.globalButton;
        }

        _createButtonContainer() {
            // 使用统一的选择器配置获取 fanyaMarking_right
            const sidePanelSelector = this.config.get('selectors.sidePanel');
            const fanyaMarkingRight = document.querySelector(sidePanelSelector) || this.container.parentNode;
            
            // 检测是否为竖屏模式
            const isPortrait = () => window.innerHeight > window.innerWidth;
            
            // 按钮最小宽度配置(用于空间检测)
            const BUTTON_MIN_WIDTH = 140;  // 单个按钮的最小宽度(含padding和margin)
            const BUTTON_GAP = 8;          // 按钮间距
            const SIDE_MARGIN = 10;        // 侧边距
            const REQUIRED_SPACE = BUTTON_MIN_WIDTH + SIDE_MARGIN * 2; // 所需最小空间
            
            // 创建按钮容器,使用固定定位
            this.buttonContainer = DOMHelper.createElement('div', {
                style: {
                    position: 'fixed',
                    display: 'flex',
                    gap: BUTTON_GAP + 'px',
                    zIndex: '9999',
                    transition: 'all 0.3s ease' // 添加平滑过渡效果
                }
            });
            
            // 将按钮容器添加到 body
            document.body.appendChild(this.buttonContainer);
            
            /**
             * 检测右侧是否有足够空间显示按钮
             * @returns {boolean} true表示有足够空间,false表示空间不足
             */
            const hasEnoughRightSpace = (rect) => {
                const windowWidth = window.innerWidth;
                const rightEdge = rect.right;
                const availableSpace = windowWidth - rightEdge;
                return availableSpace >= REQUIRED_SPACE;
            };
            
            /**
             * 更新按钮位置和布局
             * 智能布局逻辑:
             * 1. 竖屏模式:始终在下方横向排列
             * 2. 横屏模式:
             *    - 右侧空间充足:在右侧纵向排列
             *    - 右侧空间不足:在下方纵向排列(从上到下)
             */
            const updatePosition = () => {
                const rect = fanyaMarkingRight.getBoundingClientRect();
                
                if (isPortrait()) {
                    // 竖屏模式:按钮横向排列在侧边栏下方
                    this.buttonContainer.style.flexDirection = 'row';
                    this.buttonContainer.style.flexWrap = 'wrap';
                    this.buttonContainer.style.top = (rect.bottom + SIDE_MARGIN) + 'px';
                    this.buttonContainer.style.left = rect.left + 'px';
                    this.buttonContainer.style.right = 'auto';
                    this.buttonContainer.style.maxWidth = rect.width + 'px';
                    this.buttonContainer.style.justifyContent = 'flex-start';
                    this.buttonContainer.style.alignItems = 'flex-start';
                } else {
                    // 横屏模式:根据右侧空间决定布局
                    const hasSpace = hasEnoughRightSpace(rect);
                    
                    if (hasSpace) {
                        // 右侧空间充足:按钮纵向排列在侧边栏右边
                        this.buttonContainer.style.flexDirection = 'column';
                        this.buttonContainer.style.flexWrap = 'nowrap';
                        this.buttonContainer.style.top = rect.top + 'px';
                        this.buttonContainer.style.left = (rect.right + SIDE_MARGIN) + 'px';
                        this.buttonContainer.style.right = 'auto';
                        this.buttonContainer.style.maxWidth = 'none';
                        this.buttonContainer.style.justifyContent = 'flex-start';
                        this.buttonContainer.style.alignItems = 'stretch';
                    } else {
                        // 右侧空间不足:按钮纵向排列在侧边栏下方(从上到下)
                        this.buttonContainer.style.flexDirection = 'column';
                        this.buttonContainer.style.flexWrap = 'nowrap';
                        this.buttonContainer.style.top = (rect.bottom + SIDE_MARGIN) + 'px';
                        this.buttonContainer.style.left = rect.left + 'px';
                        this.buttonContainer.style.right = 'auto';
                        this.buttonContainer.style.maxWidth = rect.width + 'px';
                        this.buttonContainer.style.justifyContent = 'flex-start';
                        this.buttonContainer.style.alignItems = 'flex-start';
                    }
                }
            };
            
            // 初始更新位置(延迟确保DOM完全渲染)
            setTimeout(updatePosition, 100);
            
            // 滚动和窗口变化时更新位置
            window.addEventListener('scroll', updatePosition, { passive: true });
            window.addEventListener('resize', updatePosition);
            
            // 监听屏幕方向变化(移动设备)
            if (window.matchMedia) {
                window.matchMedia('(orientation: portrait)').addEventListener('change', updatePosition);
            }
            
            // 使用 ResizeObserver 监听侧边栏大小变化(更精确的响应式)
            if (typeof ResizeObserver !== 'undefined') {
                const resizeObserver = new ResizeObserver(() => {
                    updatePosition();
                });
                resizeObserver.observe(fanyaMarkingRight);
            }
        }

        _createGlobalButton() {
            const buttonText = this.config.get('globalButton.text');
            this.globalButton = DOMHelper.createElement('button', {
                innerText: buttonText.showAll,
                style: this.styleGenerator.getGlobalButtonStyle(true),
                title: '点击一键显示/隐藏所有答案块'
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addToggleHoverEffect(
                this.globalButton,
                'globalButton',
                () => this.controllers.every(ctrl => ctrl.getState()),
                'showAllHoverBackground', 'hideAllHoverBackground',
                'showAllBackground', 'hideAllBackground'
            );

            this.globalButton.addEventListener('click', () => this._handleGlobalToggle());
            this.buttonContainer.appendChild(this.globalButton);
        }

        _createManageButton() {
            const buttonText = this.config.get('manageButton.text');
            this.manageButton = DOMHelper.createElement('button', {
                innerText: buttonText,
                style: this.styleGenerator.getManageButtonStyle(),
                title: '打开控制面板:设置和笔记管理'
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addSimpleHoverEffect(this.manageButton, 'manageButton');

            this.manageButton.addEventListener('click', () => this._handleManageClick());
            this.buttonContainer.appendChild(this.manageButton);
        }

        _createExportButton() {
            const buttonText = this.config.get('exportButton.text');
            const buttonTextWithAnswer = this.config.get('exportButton.textWithAnswer');
            const colors = this.config.get('exportButton.colors');
            
            // 创建导出试题按钮(不带答案)
            this.exportButton = DOMHelper.createElement('button', {
                innerText: buttonText,
                style: this.styleGenerator.getExportButtonStyle(),
                title: '导出试题为Word文档(不含答案)'
            });

            // 使用统一的悬停效果管理
            this.styleGenerator.addSimpleHoverEffect(this.exportButton, 'exportButton');

            this.exportButton.addEventListener('click', () => this._handleExport(false));
            this.buttonContainer.appendChild(this.exportButton);
            
            // 创建导出答案按钮(带答案)
            const exportWithAnswerStyle = this.styleGenerator.getExportButtonStyle();
            exportWithAnswerStyle.background = colors.withAnswerBackground;
            
            this.exportWithAnswerButton = DOMHelper.createElement('button', {
                innerText: buttonTextWithAnswer,
                style: exportWithAnswerStyle,
                title: '导出试题为Word文档(含答案)'
            });

            // 手动添加悬停效果(使用紫色)
            this.exportWithAnswerButton.addEventListener('mouseenter', () => {
                this.exportWithAnswerButton.style.background = colors.withAnswerHoverBackground;
                this.exportWithAnswerButton.style.transform = 'translateY(-1px)';
            });
            this.exportWithAnswerButton.addEventListener('mouseleave', () => {
                this.exportWithAnswerButton.style.background = colors.withAnswerBackground;
                this.exportWithAnswerButton.style.transform = 'translateY(0)';
            });

            this.exportWithAnswerButton.addEventListener('click', () => this._handleExport(true));
            this.buttonContainer.appendChild(this.exportWithAnswerButton);
        }

        async _handleExport(includeAnswer = false) {
            // 确定当前操作的按钮
            const currentButton = includeAnswer ? this.exportWithAnswerButton : this.exportButton;
            const originalText = currentButton.innerText;
            
            try {
                // 显示导出中状态
                currentButton.innerText = '⏳ 导出中...';
                currentButton.disabled = true;

                // 从控制器中获取答案信息
                if (this.controllers.length === 0) {
                    alert('未找到任何试题');
                    currentButton.innerText = originalText;
                    currentButton.disabled = false;
                    return;
                }

                // 解析题目内容(使用控制器中保存的原始答案)
                const docContent = this._parseQuestionsToDocx();

                if (!docContent.questions || docContent.questions.length === 0) {
                    alert('未能解析到试题内容');
                    currentButton.innerText = originalText;
                    currentButton.disabled = false;
                    return;
                }

                // 生成并下载文档,传入是否包含答案的参数
                await this._generateDocx(docContent, includeAnswer);

                // 恢复按钮状态
                currentButton.innerText = originalText;
                currentButton.disabled = false;
            } catch (error) {
                console.error('导出失败:', error);
                alert('导出失败,请重试');
                currentButton.innerText = originalText;
                currentButton.disabled = false;
            }
        }

        _parseQuestionsToDocx() {
            const content = [];
            
            // 获取文档标题(从 mark_title 获取)
            const markTitle = document.querySelector('.mark_title');
            const docTitle = markTitle ? markTitle.innerText.trim() : '试题导出';

            this.controllers.forEach((controller, index) => {
                // 从控制器获取原始答案HTML(保留完整HTML结构)
                const answerHTML = controller.originalHTML;
                
                // 获取题目信息 - 找到完整的题目容器
                let questionHTML = '';
                let titleText = `第${index + 1}题`;

                // 使用 questionId 找到完整的题目容器
                const questionId = controller.questionId;
                let questionContainer = null;
                
                if (questionId && questionId.startsWith('question')) {
                    questionContainer = document.getElementById(questionId);
                }
                
                // 如果没找到,尝试从 parent 向上查找
                if (!questionContainer && controller.parent) {
                    let element = controller.parent;
                    while (element && element !== document.body) {
                        if (element.classList && (element.classList.contains('questionLi') || element.classList.contains('mark_item'))) {
                            questionContainer = element;
                            break;
                        }
                        element = element.parentElement;
                    }
                }

                if (questionContainer) {
                    // 克隆元素以避免影响原始DOM
                    const containerClone = questionContainer.cloneNode(true);
                    
                    // 移除答案块(我们单独处理答案)
                    const answerBlocks = containerClone.querySelectorAll('.mark_answer');
                    answerBlocks.forEach(block => block.remove());
                    
                    // 移除脚本添加的按钮
                    const buttons = containerClone.querySelectorAll('button');
                    buttons.forEach(btn => btn.remove());
                    
                    // 移除脚本添加的编辑器容器
                    const editDivs = containerClone.querySelectorAll('div[contenteditable]');
                    editDivs.forEach(div => {
                        const parent = div.closest('div[style*="display: none"]') || div.closest('div[style*="margin-top: 12px"]');
                        if (parent) parent.remove();
                    });
                    
                    // 移除按钮容器(脚本添加的inline-block div)
                    const inlineBlockDivs = containerClone.querySelectorAll('div[style*="display: inline-block"]');
                    inlineBlockDivs.forEach(div => div.remove());

                    // 获取题号和题目内容
                    const markName = containerClone.querySelector('.mark_name');
                    if (markName) {
                        // 提取题号文本(如 "1. (单选题, 4分)")
                        const colorShallow = markName.querySelector('.colorShallow');
                        const firstTextNode = markName.childNodes[0];
                        if (firstTextNode && firstTextNode.nodeType === Node.TEXT_NODE) {
                            titleText = firstTextNode.textContent.trim();
                        }
                        if (colorShallow) {
                            titleText += ' ' + colorShallow.textContent.trim();
                        }
                        
                        // 获取题目正文HTML(在 qtContent 中)
                        const qtContent = markName.querySelector('.qtContent');
                        if (qtContent) {
                            questionHTML = qtContent.innerHTML;
                        }
                    }
                    
                    // 获取选项列表 - 支持多种题型
                    // 1. 单选题/多选题: ul.mark_letter
                    const markLetter = containerClone.querySelector('ul.mark_letter');
                    if (markLetter) {
                        questionHTML += markLetter.outerHTML;
                    }
                    
                    // 2. 完型填空/填空题: div.mark_gestalt
                    const markGestalt = containerClone.querySelector('div.mark_gestalt');
                    if (markGestalt) {
                        // 移除脚本添加的按钮容器(在选项内部的)
                        const innerButtons = markGestalt.querySelectorAll('div[style*="display: inline-block"]');
                        innerButtons.forEach(btn => btn.remove());
                        const innerEditors = markGestalt.querySelectorAll('div[style*="display: none"]');
                        innerEditors.forEach(div => div.remove());
                        questionHTML += markGestalt.outerHTML;
                    }

                    // 移除AI讲解链接
                    const aiLinks = containerClone.querySelectorAll('a.aiAssistant');
                    aiLinks.forEach(link => link.remove());

                    // 如果还是没有内容,尝试从 aiAreaContent 获取
                    if (!questionHTML) {
                        const aiAreaContent = containerClone.querySelector('.aiAreaContent');
                        if (aiAreaContent) {
                            // 移除 mark_name 避免重复
                            const mn = aiAreaContent.querySelector('.mark_name');
                            if (mn) mn.remove();
                            questionHTML = aiAreaContent.innerHTML;
                        }
                    }
                }

                console.log(`题目 ${index + 1}:`, {
                    title: titleText,
                    hasQuestionHTML: !!questionHTML,
                    questionHTMLLength: questionHTML.length,
                    hasAnswerHTML: !!answerHTML,
                    answerHTMLLength: answerHTML?.length || 0
                });

                content.push({
                    type: 'question',
                    index: index + 1,
                    title: titleText,
                    questionHTML: questionHTML,
                    answerHTML: answerHTML
                });
            });

            return { docTitle, questions: content };
        }

        async _generateDocx(content, includeAnswer = false) {
            // 获取导出设置(答案由参数控制,不从设置读取)
            const exportDefaults = this.config.get('exportSettings');
            let exportSettings = {};
            let contentOptions = {};
            try {
                const allSettings = await this.dbManager.getAllSettings();
                exportSettings = {
                    fontFamily: allSettings.exportFontFamily ?? exportDefaults.fontFamily,
                    fontSize: allSettings.exportFontSize ?? exportDefaults.fontSize,
                    titleFontSize: allSettings.exportTitleFontSize ?? exportDefaults.titleFontSize,
                    lineHeight: allSettings.exportLineHeight ?? exportDefaults.lineHeight,
                    pageMargin: allSettings.exportPageMargin ?? exportDefaults.pageMargin
                };
                // 导出内容选项
                contentOptions = {
                    exportMyAnswer: allSettings.exportMyAnswer ?? exportDefaults.exportMyAnswer,
                    exportCorrectAnswer: allSettings.exportCorrectAnswer ?? exportDefaults.exportCorrectAnswer,
                    exportScore: allSettings.exportScore ?? exportDefaults.exportScore,
                    exportAnalysis: allSettings.exportAnalysis ?? exportDefaults.exportAnalysis
                };
            } catch (e) {
                exportSettings = { ...exportDefaults };
                contentOptions = {
                    exportMyAnswer: exportDefaults.exportMyAnswer,
                    exportCorrectAnswer: exportDefaults.exportCorrectAnswer,
                    exportScore: exportDefaults.exportScore,
                    exportAnalysis: exportDefaults.exportAnalysis
                };
            }

            // 根据导出内容选项过滤答案HTML
            const filterAnswerHtml = (answerHTML) => {
                if (!answerHTML) return '';
                
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = answerHTML;

                // 如果不导出"我的答案",移除相关元素
                if (!contentOptions.exportMyAnswer) {
                    // 移除包含"我的答案"的span(查找包含stuAnswerContent的父span)
                    const myAnswerSpans = tempDiv.querySelectorAll('.stuAnswerContent');
                    myAnswerSpans.forEach(span => {
                        // 找到包含"我的答案:"标签的父级span
                        const parentSpan = span.closest('span.colorDeep.marginRight40.fl') || span.parentElement;
                        if (parentSpan) parentSpan.remove();
                    });
                }

                // 如果不导出"正确答案",移除相关元素
                if (!contentOptions.exportCorrectAnswer) {
                    const correctAnswerSpans = tempDiv.querySelectorAll('.rightAnswerContent');
                    correctAnswerSpans.forEach(span => {
                        const parentSpan = span.closest('span.colorGreen.marginRight40.fl') || span.parentElement;
                        if (parentSpan) parentSpan.remove();
                    });
                }

                // 如果不导出"本题得分",移除相关元素
                if (!contentOptions.exportScore) {
                    const scoreDiv = tempDiv.querySelector('.mark_score');
                    if (scoreDiv) scoreDiv.remove();
                }

                // 如果不导出"答案解析",移除相关元素
                if (!contentOptions.exportAnalysis) {
                    const analysisDiv = tempDiv.querySelector('.analysisDiv');
                    if (analysisDiv) analysisDiv.remove();
                }

                return tempDiv.innerHTML;
            };

            // 使用 GM_xmlhttpRequest 下载图片(绕过 CORS 限制)
            const downloadImageAsBase64 = (imgUrl) => {
                return new Promise((resolve) => {
                    // 处理相对路径
                    let fullUrl = imgUrl;
                    if (imgUrl.startsWith('//')) {
                        fullUrl = 'https:' + imgUrl;
                    } else if (imgUrl.startsWith('/')) {
                        fullUrl = window.location.origin + imgUrl;
                    }
                    
                    console.log('[图片下载] 开始下载:', fullUrl);

                    // 检查是否有 GM_xmlhttpRequest 可用
                    if (typeof GM_xmlhttpRequest === 'function') {
                        console.log('[图片下载] 使用 GM_xmlhttpRequest');
                        try {
                            GM_xmlhttpRequest({
                                method: 'GET',
                                url: fullUrl,
                                responseType: 'blob',
                                timeout: 15000,
                                headers: {
                                    'Referer': window.location.href
                                },
                                onload: function(response) {
                                    console.log('[图片下载] 响应状态:', response.status, '类型:', response.response?.type);
                                    if (response.status === 200 && response.response) {
                                        const reader = new FileReader();
                                        reader.onloadend = () => {
                                            console.log('[图片下载] 转换成功, base64长度:', reader.result?.length);
                                            resolve(reader.result);
                                        };
                                        reader.onerror = (e) => {
                                            console.error('[图片下载] FileReader 错误:', e);
                                            resolve(fullUrl);
                                        };
                                        reader.readAsDataURL(response.response);
                                    } else {
                                        console.warn('[图片下载] 响应错误:', response.status, response.statusText);
                                        resolve(fullUrl);
                                    }
                                },
                                onerror: function(error) {
                                    console.error('[图片下载] GM_xmlhttpRequest 错误:', error);
                                    resolve(fullUrl);
                                },
                                ontimeout: function() {
                                    console.warn('[图片下载] 超时:', fullUrl);
                                    resolve(fullUrl);
                                }
                            });
                        } catch (e) {
                            console.error('[图片下载] GM_xmlhttpRequest 异常:', e);
                            resolve(fullUrl);
                        }
                    } else {
                        // GM_xmlhttpRequest 不可用,尝试 fetch
                        console.warn('[图片下载] GM_xmlhttpRequest 不可用,尝试 fetch');
                        fetch(fullUrl, { mode: 'cors', credentials: 'include' })
                            .then(response => response.blob())
                            .then(blob => {
                                const reader = new FileReader();
                                reader.onloadend = () => resolve(reader.result);
                                reader.onerror = () => resolve(fullUrl);
                                reader.readAsDataURL(blob);
                            })
                            .catch(e => {
                                console.error('[图片下载] fetch 错误:', e);
                                resolve(fullUrl);
                            });
                    }
                });
            };

            // 处理HTML中的图片(包括尺寸调整)
            // A4纸内容区域约 21cm - 4cm边距 = 17cm ≈ 480pt,这里设置稍小一点确保不超出
            const MAX_IMAGE_WIDTH = 600;  // 最大宽度(像素)

            // 获取图片尺寸,仅当超出最大宽度时才缩放
            const getScaledImageSize = (base64Data) => {
                return new Promise((resolve) => {
                    const img = new Image();
                    img.onload = () => {
                        const originalWidth = img.naturalWidth;
                        const originalHeight = img.naturalHeight;
                        
                        // 只有当宽度超出时才缩放
                        if (originalWidth > MAX_IMAGE_WIDTH) {
                            const scale = MAX_IMAGE_WIDTH / originalWidth;
                            const newWidth = MAX_IMAGE_WIDTH;
                            const newHeight = Math.round(originalHeight * scale);
                            console.log(`[图片缩放] ${originalWidth}x${originalHeight} → ${newWidth}x${newHeight}`);
                            resolve({ width: newWidth, height: newHeight, scaled: true });
                        } else {
                            // 不需要缩放,保持原尺寸
                            console.log(`[图片尺寸] ${originalWidth}x${originalHeight} (无需缩放)`);
                            resolve({ width: originalWidth, height: originalHeight, scaled: false });
                        }
                    };
                    img.onerror = () => {
                        console.warn('[图片尺寸] 无法获取尺寸');
                        resolve({ width: null, height: null, scaled: false });
                    };
                    img.src = base64Data;
                });
            };

            // 处理HTML中的图片
            const processImagesInHtml = async (html) => {
                if (!html) return '';
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = html;
                
                const images = tempDiv.querySelectorAll('img');
                for (const img of images) {
                    // 优先使用 data-original(高清原图)
                    const originalSrc = img.getAttribute('data-original');
                    const src = originalSrc || img.getAttribute('src');
                    if (src) {
                        console.log('正在处理图片:', src);
                        const processedSrc = await downloadImageAsBase64(src);
                        img.setAttribute('src', processedSrc);
                        // 移除可能干扰的属性
                        img.removeAttribute('data-original');
                        img.removeAttribute('data-src');
                        
                        // 检查是否成功转为 base64
                        if (processedSrc.startsWith('data:')) {
                            // 获取尺寸信息,只有超宽的才会被缩放
                            const sizeInfo = await getScaledImageSize(processedSrc);
                            
                            if (sizeInfo.scaled && sizeInfo.width && sizeInfo.height) {
                                // 只有被缩放的图片才设置固定尺寸
                                img.setAttribute('width', sizeInfo.width);
                                img.setAttribute('height', sizeInfo.height);
                                img.style.width = `${sizeInfo.width}px`;
                                img.style.height = `${sizeInfo.height}px`;
                            }
                            // 未缩放的图片保持原样,不设置尺寸属性
                        } else {
                            console.warn('图片保留原URL:', processedSrc);
                            // 对于未转换的图片,使用CSS限制最大宽度作为保险
                            img.style.maxWidth = `${MAX_IMAGE_WIDTH}px`;
                            img.style.height = 'auto';
                        }
                    }
                }
                
                return tempDiv.innerHTML;
            };

            // 清理HTML,保留原始样式和结构,移除不需要的元素
            const cleanHtml = (html) => {
                if (!html) return '';
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = html;
                
                // 移除 element-invisible-hidden 类的元素(包含选项完整内容,如":1968年NATO会议")
                // 用户只需要答案字母(如"B"),不需要这些冗余内容
                const hiddenElements = tempDiv.querySelectorAll('.element-invisible-hidden');
                hiddenElements.forEach(el => el.remove());
                
                return tempDiv.innerHTML;
            };

            // 构建纯HTML格式文档(Word可以直接打开.doc格式的HTML)
            let htmlContent = `<!DOCTYPE html>
<html xmlns:o="urn:schemas-microsoft-com:office:office"
      xmlns:w="urn:schemas-microsoft-com:office:word"
      xmlns="http://www.w3.org/TR/REC-html40">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="ProgId" content="Word.Document">
    <meta name="Generator" content="Microsoft Word 15">
    <!--[if gte mso 9]>
    <xml>
        <w:WordDocument>
            <w:View>Print</w:View>
            <w:Zoom>100</w:Zoom>
            <w:DoNotOptimizeForBrowser/>
        </w:WordDocument>
    </xml>
    <![endif]-->
    <style>
        /* 页面基础设置 */
        @page { 
            size: A4; 
            margin: ${exportSettings.pageMargin};
        }
        body { 
            font-family: '${exportSettings.fontFamily}', SimSun, serif; 
            font-size: ${exportSettings.fontSize}pt; 
            line-height: ${exportSettings.lineHeight};
            color: #333;
        }
        
        /* 文档标题 */
        .doc-title {
            text-align: center;
            font-size: ${exportSettings.titleFontSize}pt;
            font-weight: bold;
            margin-bottom: 30px;
            color: #000;
        }
        
        /* 题目容器(添加明显分隔线) */
        .question {
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 2px solid #2d3748;
            page-break-inside: avoid;
        }
        .question:last-child {
            border-bottom: none;
        }
        
        /* 题目标题(题号和分值) */
        .question-header {
            font-weight: bold;
            font-size: ${exportSettings.fontSize}pt;
            color: #000;
            margin-bottom: 10px;
            background-color: #f5f5f5;
            padding: 5px 10px;
        }
        
        /* 题目内容区域 */
        .question-content {
            margin: 10px 0;
        }
        .question-content img {
            max-width: 500px;
            height: auto;
        }
        
        /* 答案区域 */
        .answer-section {
            margin-top: 15px;
            padding: 10px;
            background-color: #fff8f8;
            border-left: 3px solid #e74c3c;
        }
        .answer-label {
            font-weight: bold;
            color: #e74c3c;
        }
        .answer-content {
            margin-top: 5px;
        }
        .answer-content img {
            max-width: 500px;
            height: auto;
        }
        
        /* ========== 保留原始网页样式 ========== */
        
        /* 题目名称样式 */
        .mark_name {
            font-weight: bold;
            margin-bottom: 10px;
        }
        .colorShallow {
            color: #999;
            font-weight: normal;
        }
        .colorDeep {
            color: #333;
        }
        .colorGreen {
            color: #48bb78;
        }
        
        /* 单选/多选题选项样式 */
        .mark_letter {
            list-style: none;
            padding: 0;
            margin: 10px 0;
        }
        .mark_letter li {
            padding: 8px 0;
            border-bottom: 1px dashed #e2e8f0;
        }
        .mark_letter li:last-child {
            border-bottom: none;
        }
        
        /* 完型填空选项样式 */
        .mark_gestalt {
            margin: 15px 0;
        }
        .gestalt_row {
            margin: 12px 0;
            padding: 8px 0;
            border-bottom: 1px dashed #e2e8f0;
        }
        .gestalt_row:last-child {
            border-bottom: none;
        }
        .gestalt_row dt {
            font-weight: bold;
            color: #2d3748;
            margin-bottom: 8px;
        }
        .gestalt_row dd {
            display: inline-block;
            margin: 4px 20px 4px 0;
        }
        .gestalt_num {
            font-weight: bold;
            margin-right: 5px;
        }
        
        /* 答案详情样式 */
        .mark_answer {
            padding: 10px;
            background: #f7fafc;
            border-radius: 4px;
        }
        .mark_key {
            margin-bottom: 10px;
        }
        .mark_fill dt {
            font-weight: bold;
        }
        .mark_fill dd {
            display: inline;
        }
        .gestalt_fill {
            display: inline-block;
            margin-right: 15px;
            padding: 2px 8px;
            background: #edf2f7;
            border-radius: 4px;
        }
        .mark_score {
            margin-top: 10px;
            padding-top: 10px;
            border-top: 1px solid #e2e8f0;
        }
        .totalScore {
            font-weight: bold;
            color: #e53e3e;
        }
        .fontWeight {
            font-weight: bold;
        }
        .marginRight40 {
            margin-right: 40px;
        }
        .fl {
            display: inline-block;
        }
        .fr {
            float: right;
        }
        .stuAnswerContent, .rightAnswerContent {
            font-weight: bold;
        }
        
        /* 表格样式 */
        table {
            border-collapse: collapse;
            width: 100%;
            margin: 10px 0;
        }
        td, th {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
    </style>
</head>
<body>
    <div class="doc-title">${this._escapeHtml(content.docTitle)}</div>
`;

            // 处理每道题目
            for (const item of content.questions) {
                // 处理题目HTML中的图片(异步处理,尝试转为base64)
                const processedQuestionHtml = await processImagesInHtml(cleanHtml(item.questionHTML || ''));

                htmlContent += `
    <div class="question">
        <div class="question-header">${this._escapeHtml(item.title)}</div>
        <div class="question-content">${processedQuestionHtml}</div>`;

                // 根据参数决定是否导出答案
                if (includeAnswer && item.answerHTML) {
                    // 先过滤答案内容(根据导出内容选项)
                    const filteredAnswerHtml = filterAnswerHtml(item.answerHTML);
                    // 只有过滤后仍有内容才显示答案区域
                    if (filteredAnswerHtml.trim()) {
                        const processedAnswerHtml = await processImagesInHtml(cleanHtml(filteredAnswerHtml));
                        htmlContent += `
        <div class="answer-section">
            <div class="answer-label">【答案】</div>
            <div class="answer-content">${processedAnswerHtml}</div>
        </div>`;
                    }
                }

                htmlContent += `
    </div>
`;
            }

            htmlContent += `
</body>
</html>`;

            // 生成文件名(使用文档标题 + 时间戳)
            const now = new Date();
            const dateStr = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}`;
            const timeStr = `${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}`;
            // 清理文件名中的非法字符
            const safeTitle = content.docTitle.replace(/[\\/:*?"<>|]/g, '_').substring(0, 50);

            let blob;
            let fileExtension;

            // 尝试使用 html-docx-js 库生成真正的 docx 文件
            if (typeof htmlDocx !== 'undefined' && htmlDocx.asBlob) {
                try {
                    console.log('[导出] 使用 html-docx-js 生成 docx 文件');
                    blob = htmlDocx.asBlob(htmlContent);
                    fileExtension = 'docx';
                    Logger.success('正在生成 docx 文件...');
                } catch (e) {
                    console.warn('[导出] html-docx-js 转换失败,回退到 doc 格式:', e);
                    // 回退到 HTML 格式的 doc 文件
                    blob = new Blob(['\ufeff' + htmlContent], { 
                        type: 'application/msword'
                    });
                    fileExtension = 'doc';
                }
            } else {
                console.log('[导出] html-docx-js 库不可用,使用 doc 格式');
                // html-docx-js 库不可用,使用 HTML 格式的 doc 文件
                blob = new Blob(['\ufeff' + htmlContent], { 
                    type: 'application/msword'
                });
                fileExtension = 'doc';
            }

            // 生成下载链接
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = `${safeTitle}_${dateStr}_${timeStr}.${fileExtension}`;

            // 触发下载
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(url);
        }

        _escapeHtml(text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        _handleManageClick() {
            const controlPanel = new ControlPanelUI(this.dbManager, this.workKey, this.config);
            controlPanel.show();
        }

        _handleGlobalToggle() {
            const allHidden = this.controllers.every(ctrl => ctrl.getState());

            this.controllers.forEach(controller => {
                const shouldToggle = allHidden ? controller.getState() : !controller.getState();
                if (shouldToggle) {
                    controller.toggle();
                }
            });

            this._updateGlobalButtonState(!allHidden);
        }

        _updateGlobalButtonState(allHidden) {
            const buttonText = this.config.get('globalButton.text');
            const colors = this.config.get('globalButton.colors');

            this.globalButton.innerText = allHidden ? buttonText.showAll : buttonText.hideAll;
            this.globalButton.style.background = allHidden ? colors.showAllBackground : colors.hideAllBackground;
        }
    }

    // ===================== 主应用类 =====================
    class ChaoxingAnswerHider {
        constructor(customConfig = {}) {
            this.config = new Config(customConfig);
            this.styleGenerator = new StyleGenerator(this.config);
            this.dbManager = new DatabaseManager(this.config);
            this.answerControllers = [];
            this.globalController = null;
            this.workKey = URLParser.getWorkKey();
        }

        async initialize() {
            try {
                // 初始化数据库
                await this.dbManager.init();
                Logger.success('数据库初始化成功');

                // 加载自定义样式配置
                await this._loadCustomStyles();

                await this._waitForPageLoad();
                const elements = this._findElements();

                if (!this._validateElements(elements)) {
                    return;
                }

                await this._initializeAnswerBlocks(elements.answerBlocks);
                this._initializeGlobalControl(elements.container);
                this._logSuccess(elements.answerBlocks.length, !!elements.container);
            } catch (error) {
                Logger.error('初始化失败', error);
            }
        }

        async _loadCustomStyles() {
            try {
                const customStyles = await this.dbManager.getSetting('customStyles', {});
                if (customStyles && Object.keys(customStyles).length > 0) {
                    // 将自定义样式合并到配置中
                    this.config = new Config(this.config._deepMerge(this.config.config, customStyles));
                    this.styleGenerator = new StyleGenerator(this.config);
                    Logger.log('✨ 已加载自定义样式配置');
                }
            } catch (error) {
                Logger.error('加载自定义样式失败', error);
            }
        }

        _waitForPageLoad() {
            const delay = this.config.get('delays.initialization');
            return new Promise(resolve => setTimeout(resolve, delay));
        }

        _findElements() {
            return {
                container: document.querySelector(this.config.get('selectors.container')),
                answerBlocks: document.querySelectorAll(this.config.get('selectors.answerBlock'))
            };
        }

        _validateElements({ container, answerBlocks }) {
            if (answerBlocks.length === 0) {
                Logger.log(this.config.get('messages.noAnswerBlocks'));
                return false;
            }

            if (!container) {
                Logger.log(this.config.get('messages.noContainer'), 'warn');
            }

            return true;
        }

        async _initializeAnswerBlocks(blocks) {
            for (const block of blocks) {
                const controller = new AnswerBlockController(
                    block,
                    this.config,
                    this.styleGenerator,
                    this.dbManager,
                    this.workKey
                );
                await controller.initialize();
                this.answerControllers.push(controller);
            }
        }

        _initializeGlobalControl(container) {
            this.globalController = new GlobalController(
                container,
                this.answerControllers,
                this.config,
                this.styleGenerator,
                this.dbManager,
                this.workKey
            );
            this.globalController.initialize();
        }

        _logSuccess(count, hasContainer) {
            Logger.success(this.config.get('messages.success'));
            Logger.log(this.config.get('messages.hiddenCount')(count));
            Logger.log(this.config.get('messages.globalButton')(hasContainer));
            Logger.log(`📝 笔记功能已启用,数据存储标识: ${this.workKey}`);
        }
    }

    // ===================== 启动应用 =====================
    const app = new ChaoxingAnswerHider();
    app.initialize();
})();