思源笔记 html 块实时交互 JS 提示词,html 块终于可以输入框实时交互了!

先打开设置——编辑器——打开 允许执行 HTML 块内脚本(这样 html 块才能使用 JS 脚本)

提示词(可根据自己喜欢的风格微调,或者直接将提示词变成智能体用)

我需要一个为思源笔记深度定制的 HTML 块,请严格遵循以下所有要求,并且**使用 HTML 和 CSS**和JS则必须遵循和使用JS模板的全部内容(注意模板的交互内容和光标内容必须使用,其他功能JS按照用户所需使用):

1.  **功能目标**: 创建一个[这里填写你的具体功能,例如:会议纪要模板、项目信息卡、读书笔记模板...]。

2.  **思源笔记兼容性优化 (最高优先级,必须遵循以下规则)**:
    * 最终生成的代码**绝对不能**包含 `<!DOCTYPE html>`, `<html>`, `<head>`, `<body>` 这些顶层标签。
    * 所有 HTML 元素以及 `<style>` 标签,都必须被包裹在一个**唯一的父 `<div>`** 标签内。
    * 请确保最终代码是**删除所有在两行内容之间起分隔作用的、完全为空的行**,以防止思源笔记错误地将其解析为多个代码块。

3.  **核心交互元素 (关键!)**:
    * 重点!!!模板中所有需要用户填写或修改的内容,**必须**使用 `<input>`, `<textarea>` 或任何其他表单元素,因为是笔记,所以只要能有个输入框的元素,不用真正的表单元素UI界面
    **事件监听** 必须为整个组件的主容器(例如,class为.universal-container的div)添加一个全局的input事件监听器并配合JS模板的交互。如果组件中包含复选框(checkbox)或其他需要点击交互的元素,也需要为主容器添加click事件监听器,并判断事件目标是否为这些元素。

4.  **外观和样式 (CSS)**:
    **整体风格**: 设计为[用户选择风格]模板的风格为Notion模板风格,但**背景色如果用户定义配色则需要整体配色也请围绕这个主色调进行协调设计**
    **图标化标题**: 每个主要板块的标题(如 <h2>)前添加一个合适的 Emoji 图标,以增强结构感和视觉吸引力。
    **文本样式**: 确保所有文本内容(包括标题和段落)都清晰易读。你可以为不同的文本元素设置不同的颜色、字重或样式,以区分其功能。
    **字体与排版**: 使用优雅、易读的中文字体(如“思源黑体”),并设置合适的行高和间距,保证整体的美观性。移除不必要的边框、阴影和复杂的背景,让它看起来像一个真正的笔记页面,而不是一个网页卡片。
    **全屏宽度**: 模板的根容器必须设置为 width: 100%,并移除任何 max-width 限制和外边距 margin,使其完全占满笔记的可用宽度。
    **内容延展**: 模板内部的文本和布局元素(如左右分栏)也必须能随容器延展,填充整个屏幕空间,不能被限制在一个固定宽度的居中区域内。
    **栏目结构**: 设计为[这里填写布局要求,例如:优雅的单栏布局、响应式左右双栏布局...]。如果是双栏或多栏,请确保在移动端等窄屏幕上能自动切换为单栏垂直排列。
    **动态效果** (可选): 如果需要动画效果(例如:[这里填写想要的动效,如“樱花飘落”...]),必须使用纯 CSS 的 @keyframes 来实现,并确保动画元素不会干扰到下方内容的编辑,并且尽量减少cpu消耗的代码例如transform 和 opacity等

5.  **最重要的一点**:
    * **JS必须遵循以下模板**使用任何 `<script>` 标签或任何形式的 JavaScript,需要遵循下面模板
    模板要求:1.指纹与全局搜索:必须使用“CUSTOM_ID + 全局搜索”的模式来定位自身。
              在脚本顶部定义一个独一无二的 const CUSTOM_ID = "一个独特的字符串";。
              使用 document.querySelector(\protyle-html[data-content*="${customID}"]`)` 的方式进行全局查找。
    2.使用 Shadow DOM:所有对 HTML 块内部元素的查找和操作,都必须通过获取到的 shadowRoot 引用来进行,例如 self.shadowRoot.getElementById('...')。
    3.作用域隔离:所有 JavaScript 代码必须包裹在一个大括号 {...} 中,以创建局部作用域。
    4.立即执行:核心逻辑应放在一个立即执行的匿名函数 (() => { ... })(); 中,并在此函数内部首先调用 findSelf() 进行初始化。
    5.必须使用下面模板的全部内容,包括交互和光标,如添加其他JS,则在其他JS区添加
JS模板案例如下:   

<!-- 脚本部分 -->
<script>
    {
        // --- 模板核心:请勿修改 ---
        /**
         * 1. “指纹”:为你的每个新功能生成一个独一无二的ID。
         * 你可以使用在线UUID生成器来创建一个新的ID,确保它不会和别的代码块冲突。
         */
        const CUSTOM_ID = "a1b2c3d4-e5f6-7890-1234-567890abcdef-merged-v14-template";
        /**
         * 2. “全局搜索”函数:这是保证脚本正常运行的核心,无需修改。
         */
        function findSelf(customID) {
            const protyle = document.querySelector(`protyle-html[data-content*="${customID}"]`);
            if (protyle && protyle.parentElement && protyle.parentElement.parentElement) {
                const block = protyle.parentElement.parentElement;
                return { id: block.dataset.nodeId, shadowRoot: protyle.shadowRoot };
            }
            return null;
        }
        // --- 模板结束 ---
        // 立即执行主逻辑
        (() => {
            const self = findSelf(CUSTOM_ID);
            if (!self || !self.shadowRoot) {
                console.error(`[${CUSTOM_ID}] 脚本初始化失败:无法定位。`);
                return;
            }
            // --- 核心功能区:自动保存与光标恢复 ---
            function initializeAutoSaveAndCursorRestore(self) {
                const mainContainer = self.shadowRoot.querySelector('.universal-container');
                const titleInput = self.shadowRoot.getElementById('editable-title');
                const contentInput = self.shadowRoot.getElementById('editable-content');
                if (!mainContainer || !titleInput || !contentInput) {
                    console.error(`[${CUSTOM_ID}] 核心元素获取失败,核心功能无法加载。`);
                    return;
                }
                try {
                    const restoreStateJSON = sessionStorage.getItem('siyuanCursorRestoreState');
                    if (restoreStateJSON) {
                        sessionStorage.removeItem('siyuanCursorRestoreState');
                        const restoreState = JSON.parse(restoreStateJSON);
                        if (restoreState.blockId === self.id) {
                            const elementToRestore = self.shadowRoot.getElementById(restoreState.activeElementId);
                            if (elementToRestore) {
                                setTimeout(() => {
                                    elementToRestore.focus();
                                    elementToRestore.setSelectionRange(restoreState.cursorPos, restoreState.cursorPos);
                                }, 10);
                            }
                        }
                    }
                } catch (e) {
                    console.error(`[${CUSTOM_ID}] 恢复光标位置失败:`, e);
                }
                let initialState = { title: '', content: '' };
                const saveContent = (activeElementId, cursorPos) => {
                    const rootWrapper = self.shadowRoot.querySelector('#block-root-wrapper');
                    if (!rootWrapper) return;
                    const restoreState = { blockId: self.id, activeElementId: activeElementId, cursorPos: cursorPos };
                    sessionStorage.setItem('siyuanCursorRestoreState', JSON.stringify(restoreState));
                    const tempWrapper = rootWrapper.cloneNode(true);
                    tempWrapper.querySelector('#editable-title').setAttribute('value', titleInput.value);
                    tempWrapper.querySelector('#editable-content').textContent = contentInput.value;
                    const requestData = { dataType: "markdown", data: tempWrapper.outerHTML, id: self.id };
                    fetch('/api/block/updateBlock', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(requestData)
                    }).then(res => res.json()).then(result => {
                        if (result.code !== 0) sessionStorage.removeItem('siyuanCursorRestoreState');
                    }).catch(() => sessionStorage.removeItem('siyuanCursorRestoreState'));
                };
                mainContainer.addEventListener('focusin', () => {
                    initialState.title = titleInput.value;
                    initialState.content = contentInput.value;
                });
                mainContainer.addEventListener('focusout', (e) => {
                    const focusIsLeavingComponent = !e.relatedTarget || !mainContainer.contains(e.relatedTarget);
                    if (focusIsLeavingComponent) {
                        const contentHasChanged = titleInput.value !== initialState.title || contentInput.value !== initialState.content;
                        if (contentHasChanged) {
                            saveContent(e.target.id, e.target.selectionEnd || 0);
                        }
                    }
                });
                mainContainer.addEventListener('input', (e) => {
                    const target = e.target;
                    if (target.matches('.editable-title, .editable-content')) {
                        const cursorPos = target.selectionEnd;
                        setTimeout(() => {
                            target.focus();
                            target.setSelectionRange(cursorPos, cursorPos);
                        }, 0);
                    }
                });
                console.log(`[${CUSTOM_ID}] 核心功能 (V14: 智能保存 & 光标恢复) 已加载。`);
            }
            initializeAutoSaveAndCursorRestore(self);
            // --- [重要] 用户自定义JS区 ---
            // 你可以在下方这个区域加入你自己的JavaScript代码。
            // 你可以直接使用 `self` 对象来访问当前HTML块的信息 (self.id, self.shadowRoot)。
            //
            // 示例 (取消下面的注释来测试):
            /*
            const titleElement = self.shadowRoot.getElementById('editable-title');
            if (titleElement) {
                titleElement.addEventListener('dblclick', () => {
                    alert('你双击了标题!块ID是: ' + self.id);
                });
            }
            */
            // ------------------------------------
        })();
    }
</script>
</div>


参考完整代码案例

<div id="block-root-wrapper">
<!-- 样式部分 -->
<style>
/* 字体与基础样式 */
:host {
    font-family: "Source Han Sans CN", "思源黑体", "Noto Sans CJK SC", sans-serif;
}
/* 根容器样式:全宽、Notion风格背景 */
.notion-block-container {
    width: 100%;
    padding: 20px 30px;
    background-color: #ffffff;
    color: #37352f;
    box-sizing: border-box; /* 保证 padding 不会撑开宽度 */
}
/* 标题区域样式 */
.title-container {
    display: flex;
    align-items: center;
    margin-bottom: 16px;
    border-bottom: 1px solid #eee;
    padding-bottom: 8px;
}
.title-icon {
    font-size: 24px;
    margin-right: 12px;
}
/* 将 input 样式重置为像普通文本 */
.editable-title {
    border: none;
    outline: none;
    padding: 0;
    font-size: 24px;
    font-weight: 600;
    width: 100%;
    background-color: transparent;
    color: #37352f;
}
/* 内容区域样式 */
.editable-content {
    width: 100%;
    min-height: 150px;
    border: none;
    outline: none;
    padding: 0;
    resize: vertical; /* 允许用户垂直调整大小 */
    font-size: 16px;
    line-height: 1.6;
    background-color: transparent;
    color: #37352f;
}
.editable-content::placeholder,
.editable-title::placeholder {
    color: #b3b3b3;
}
</style>
<!-- HTML 结构 -->
<div id="siyuan-main-wrapper" class="notion-block-container">
<div class="universal-container">
<div class="title-container">
<span class="title-icon">🖋️</span>
<input type="text" id="editable-title" class="editable-title" placeholder="输入标题...">
</div>
<textarea id="editable-content" class="editable-content" placeholder="在这里输入你的内容..."></textarea>
</div>
</div>
<!-- 脚本部分 -->
<script>
    {
        // --- 模板核心:请勿修改 ---
        /**
         * 1. “指纹”:为你的每个新功能生成一个独一无二的ID。
         * 你可以使用在线UUID生成器来创建一个新的ID,确保它不会和别的代码块冲突。
         */
        const CUSTOM_ID = "a1b2c3d4-e5f6-7890-1234-567890abcdef-merged-v14-template";
        /**
         * 2. “全局搜索”函数:这是保证脚本正常运行的核心,无需修改。
         */
        function findSelf(customID) {
            const protyle = document.querySelector(`protyle-html[data-content*="${customID}"]`);
            if (protyle && protyle.parentElement && protyle.parentElement.parentElement) {
                const block = protyle.parentElement.parentElement;
                return { id: block.dataset.nodeId, shadowRoot: protyle.shadowRoot };
            }
            return null;
        }
        // --- 模板结束 ---
        // 立即执行主逻辑
        (() => {
            const self = findSelf(CUSTOM_ID);
            if (!self || !self.shadowRoot) {
                console.error(`[${CUSTOM_ID}] 脚本初始化失败:无法定位。`);
                return;
            }
            // --- 核心功能区:自动保存与光标恢复 ---
            function initializeAutoSaveAndCursorRestore(self) {
                const mainContainer = self.shadowRoot.querySelector('.universal-container');
                const titleInput = self.shadowRoot.getElementById('editable-title');
                const contentInput = self.shadowRoot.getElementById('editable-content');
                if (!mainContainer || !titleInput || !contentInput) {
                    console.error(`[${CUSTOM_ID}] 核心元素获取失败,核心功能无法加载。`);
                    return;
                }
                try {
                    const restoreStateJSON = sessionStorage.getItem('siyuanCursorRestoreState');
                    if (restoreStateJSON) {
                        sessionStorage.removeItem('siyuanCursorRestoreState');
                        const restoreState = JSON.parse(restoreStateJSON);
                        if (restoreState.blockId === self.id) {
                            const elementToRestore = self.shadowRoot.getElementById(restoreState.activeElementId);
                            if (elementToRestore) {
                                setTimeout(() => {
                                    elementToRestore.focus();
                                    elementToRestore.setSelectionRange(restoreState.cursorPos, restoreState.cursorPos);
                                }, 10);
                            }
                        }
                    }
                } catch (e) {
                    console.error(`[${CUSTOM_ID}] 恢复光标位置失败:`, e);
                }
                let initialState = { title: '', content: '' };
                const saveContent = (activeElementId, cursorPos) => {
                    const rootWrapper = self.shadowRoot.querySelector('#block-root-wrapper');
                    if (!rootWrapper) return;
                    const restoreState = { blockId: self.id, activeElementId: activeElementId, cursorPos: cursorPos };
                    sessionStorage.setItem('siyuanCursorRestoreState', JSON.stringify(restoreState));
                    const tempWrapper = rootWrapper.cloneNode(true);
                    tempWrapper.querySelector('#editable-title').setAttribute('value', titleInput.value);
                    tempWrapper.querySelector('#editable-content').textContent = contentInput.value;
                    const requestData = { dataType: "markdown", data: tempWrapper.outerHTML, id: self.id };
                    fetch('/api/block/updateBlock', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(requestData)
                    }).then(res => res.json()).then(result => {
                        if (result.code !== 0) sessionStorage.removeItem('siyuanCursorRestoreState');
                    }).catch(() => sessionStorage.removeItem('siyuanCursorRestoreState'));
                };
                mainContainer.addEventListener('focusin', () => {
                    initialState.title = titleInput.value;
                    initialState.content = contentInput.value;
                });
                mainContainer.addEventListener('focusout', (e) => {
                    const focusIsLeavingComponent = !e.relatedTarget || !mainContainer.contains(e.relatedTarget);
                    if (focusIsLeavingComponent) {
                        const contentHasChanged = titleInput.value !== initialState.title || contentInput.value !== initialState.content;
                        if (contentHasChanged) {
                            saveContent(e.target.id, e.target.selectionEnd || 0);
                        }
                    }
                });
                mainContainer.addEventListener('input', (e) => {
                    const target = e.target;
                    if (target.matches('.editable-title, .editable-content')) {
                        const cursorPos = target.selectionEnd;
                        setTimeout(() => {
                            target.focus();
                            target.setSelectionRange(cursorPos, cursorPos);
                        }, 0);
                    }
                });
                console.log(`[${CUSTOM_ID}] 核心功能 (V14: 智能保存 & 光标恢复) 已加载。`);
            }
            initializeAutoSaveAndCursorRestore(self);
            // --- [重要] 用户自定义JS区 ---
            // 你可以在下方这个区域加入你自己的JavaScript代码。
            // 你可以直接使用 `self` 对象来访问当前HTML块的信息 (self.id, self.shadowRoot)。
            //
            // 示例 (取消下面的注释来测试):
            /*
            const titleElement = self.shadowRoot.getElementById('editable-title');
            if (titleElement) {
                titleElement.addEventListener('dblclick', () => {
                    alert('你双击了标题!块ID是: ' + self.id);
                });
            }
            */
            // ------------------------------------
        })();
    }
</script>
</div>

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    28446 引用 • 119783 回帖
  • 叶归
    25 引用 • 100 回帖 • 37 关注
  • 千千插件

    千千块(自定义块 css 和 js)
    可以用 ai 提示词来无限创作思源笔记

    32 引用 • 69 回帖
1 操作
lovexmm521 在 2025-09-15 14:43:03 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
lovexmm521 MOD
窈窕淑女,君子好逑 爱发电:https://afdian.com/a/QianQian517

推荐标签 标签

  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    215 引用 • 358 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4602 回帖 • 731 关注
  • 电影

    这是一个不能说的秘密。

    125 引用 • 610 回帖
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    695 引用 • 538 回帖 • 1 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 2 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 693 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 633 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 152 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 443 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 702 关注
  • 千千插件

    千千块(自定义块 css 和 js)
    可以用 ai 提示词来无限创作思源笔记

    32 引用 • 69 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 646 关注
  • 博客

    记录并分享人生的经历。

    274 引用 • 2393 回帖 • 1 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    167 引用 • 408 回帖 • 494 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 436 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    99 引用 • 367 回帖 • 1 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 577 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 46 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 838 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 3 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    950 引用 • 1460 回帖 • 2 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 768 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    40 引用 • 157 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 3 关注