153693workbudy 通读这个工程项目
我来全面通读这个网页管理系统项目。先看核心文档和入口文件,同时启动一个深度探索代理梳理整体代码结构。
README 已经把设计思路讲得很透。我继续深入核心实现层,并让一个探索代理梳理后台、主题和内容目录的细节结构。
核心引擎层还差"索引 schema"和"生成流水线"两块,我把 Db.php 和 Builder.php 读完,就能把整条数据链路串齐。Db.php 把索引层摸透了。生成引擎 Builder.php 太大,我用 grep 拉出它的方法清单来补足"生成流水线"这一块,不必全量读取。
我已经把整个项目从入口、配置、索引、扫描、生成到后台和主题都通读了一遍。先把这次通读的结论记进项目日志,再给你一份完整的梳理。
通读完成。这是一套设计相当成熟的本地静态站点生成系统,下面按"它是什么 → 怎么跑 → 代码怎么分层 → 关键设计"给你一份完整梳理。
一、一句话定位
本地 PHP 8.1 + SQLite(FTS5) + 原生 JS 的 CMS:用 content/ 源文件 + SQLite 索引 + config/site.json 配置,在本地把四条内容管线统一渲染成纯静态站,一键产出 dist/,拷到任意静态托管(Netlify / Cloudflare / GitHub Pages)即可。线上不需要 PHP、不需要数据库、不需要 Python。
content/ 源文件 + media/ 图片 + config/site.json
│ php cli.php scan → 建索引(data/site.db,可删重建)
│ php cli.php build → 渲染 theme/ 进 dist/
▼
dist/ 纯静态,唯一部署物
二、四条内容管线
| 管线 | 源路径 | 处理方式 |
|---|---|---|
| A Markdown 书籍 | content/book_markdown/分类/书名/章节.md | 文件夹=书,章节渲染成阅读器 |
| B HTML 页面集 | content/html/分类/页面集/页面.html | 原样直出,只注入 SEO/悬浮组件 |
| C 富文本粘贴 | content/loose/分类/slug.html | 后台 contenteditable 录入,服务端清洗 |
| D Markdown 源码 | content/loose/分类/slug.md | 后台粘源码,生成时才渲染 |
核心约定:含文件的目录=一个条目(书/页面集),上层目录都是分类,分类树完全由文件夹决定。
三、代码分层(lib 是心脏)
入口层
bootstrap.php:定义所有路径常量(APP_ROOT / DIST_DIR / MEDIA_DIR…),require全部lib/*,暴露site_config()扁平视图。cli.php:命令行入口,scan / plan / build / all / verify / config / search / serve / admin / passwd。
配置层
config/site.json:站点配置,进版本管理、删库不丢,含 site/domain/seo/analytics/adsense/layout/media/redirects/ai 九段。当前已配base_url=https://zlib.gooli.fun、AI 已启用(sensenova,key 明文写在文件里)。lib/Config.php:DEFAULTS 深合并(磁盘只存改动过的字段,加新配置项无需迁移老文件)+ 生成前validate()(域名还是 127.0.0.1、标题空、广告 ID 格式错等会拒绝生成)。
工具层 lib/Util.php:slug 生成(中文保留 CJK 不转拼音)、UTF-8 三级净化(GBK→UTF-8→丢非法字节,专门治 Windows 终端 GBK 传参导致的 json_encode 静默失败)、增量写文件 u_write()(内容没变不动 mtime)、链接/相对路径/规范链接 u_canonical()(全站 www 与 .html 口径的唯一真源)、广告代码拼装。
索引层 lib/Db.php:SQLite schema = categories / items / chapters / tags / item_tags / media / redirects / meta + FTS5(仅服务后台检索)。关键设计:文件派生的字段每次扫描覆盖,人工字段(status/seo/置顶/排序)只在源文件真写了 key 时才覆盖,否则保留库值——否则每扫一次后台设置就被抹掉。upsertItem 顺手记 URL 变更,扫描结束统一登记 301 重定向;还做了重定向链压平、删源文件级联清重定向、空分类清理(手工建的分类受保护)。
扫描层 lib/Scanner.php:scan() 先把 media/ 重新索引、回灌 _redirects.json 侧车(删库重建不丢 301),再走三目录 → 建索引 + 双写侧车 + 登记重定向。
生成层 lib/Builder.php(约 2900 行的大类):build() 入口,按范围(all/changed/category:id/item:id)选页;postProcess() 统一流水线 resolveLinks → fixMediaPaths → fixAssetPaths → fixBodyHeadings → injectInArticleAd(四条管线只在"变正文 HTML"上各做各的,后处理只做一次)。还负责 sitemap(超 sitemap_limit=1000 自动分片 + robots.txt 跟着切)、feed.xml(RSS)、search.json、重定向产物(_redirects/.htaccess/meta refresh 兜底页)、ads.txt、JSON-LD、面包屑、阅读器/列表/网格/时间线/表格等多种集合视图。
其他 lib:Markdown.php(无依赖渲染器:锚点/嵌套列表/表格/围栏代码/中文软换行)、Cleaner.php(DOM 清洗:砍危险标签、剥 class、拆 fixed/sticky 连带删偏移属性、内联样式 60KB/页预算)、Media.php(图片按内容 hash 落盘去重、data:/外链本地化、引用扫描)、Inspector.php(生成后 15 项校验:title 不重复/有 description/canonical/JSON-LD 可解析/正文只一个 H1/站内链接有效/无 <script>…)、Ai.php(sensenova 接入,AI 生成 SEO/alt,生成即落库)。
四、后台 admin/ + 主题 theme/
- 后台:
index.php(录入台:树+拖拽调序+双模式编辑器+详情面板)、library.php(内容库:服务端分页/FTS5/批量)、media.php/tags.php/redirects.php/settings.php,核心大脑是api.php(约 1300 行,所有 action:tree/scan/buildPlan/build/verify/save/saveMeta/libraryList/media/upload/tags/tagMerge/redirects/aiSeo/aiAlt/config/saveConfig…)。认证在_auth_core.php+_auth.php,密码存data/auth.json(0600)。 - 主题:
layout.php是唯一骨架(所有 SEO/OG/JSON-LD/GA4/GSC/AdSense 注入点),home/category/item/chapter/page/search/tags/tag9 套模板,assets/里prose.css前台与后台编辑器共用同一份(保证所见即所得)、site.js(浮动目录窗/锚点)、md-loader.js(按需拉 mermaid/highlight/KaTeX)、list-tools.js(聚合页过滤排序)。
五、删库不丢的三样东西(侧车文件,在 content/ 下)
_categories.json:分类显示名与排序(文件夹名只是 slug)_tags.json:源文件路径 → 标签数组(标签是后台打的,正文里没有)_redirects.json:[{old,new,at}],301 一旦丢旧链就永久 404
六、当前项目状态与提醒
- ✅ 配置已就绪(
base_url已填真实域名、AI 已启用);media/2026/11/已有 2 张图。 - ⚠️
dist/尚未生成:需要跑php cli.php all(或后台"生成")才会有产物。 - ⚠️ 安全:
config/site.json里 AIapi_key是明文;README 明确后台无登录、仅监听 127.0.0.1。部署到公网前必须php cli.php passwd设密码(SSH 上执行,避免网页首设被抢注),并参照docs/部署-云服务器.md把系统装在 webroot 外、/admin带登录暴露。 - 已把这次通读结论写入项目日志
.workbuddy/memory/2026-11-03.md。
需要我下一步做什么?比如:跑一次 scan/build 生成 dist/ 看实际产物、深入读某个具体文件(如 Builder::postProcess 流水线或 api.php 的某个 action)、或者帮你做部署前的配置检查与安全加固(把明文 API key 从仓库挪走、加密码)?
嗯,作为一个,你认为它作为我生产网站放到作为内容站,它合格吗?符合搜索引擎,符合能够生产文章,符合能够怎么说一个合格的网站,你认为它和,你认为它还欠缺什么,它的优点是什么?总而言之就是说,他适不适合做一个静态站,能够符合各种要求的
直接给结论,再拆开讲。
总评:合格,而且超出“个人自建 CMS”的平均水准
作为一个内容型静态站的生成器,它在我通读过的同类自建系统里属于上游水平。核心判断依据是:搜索引擎在意的硬指标它基本都做对了,而且做在了“唯一真源”上,不是散装补丁。
优点(都是代码里验证过的,不是 README 吹的)
SEO 这块是强项,接近“开箱即合规”:
- canonical / og:url / sitemap / JSON-LD 四条路径全部走
u_canonical()一个口子,www 与.html口径不会出现双版本——这是自建站最容易翻车、也最影响收录的地方 - sitemap 超 1000 条自动分片 +
lastmod取源文件 mtime(不是构建时间,这点很多商业系统都做错) - 逐页 JSON-LD(Book/Chapter/BreadcrumbList)、OG/Twitter 卡片、robots.txt、RSS、ads.txt、GSC 验证
- 301 重定向是自动的:改 slug / 挪分类,扫描时发现 URL 变了自动登记,还能出
_redirects/.htaccess/ meta refresh 兜底页三种形态——这对内容站的长期权重保护非常关键 - 生成后 15 项自检(title 重复、死链、双 H1、无 script……),“出的站不如不出”的拒绝生成校验,这个工程自觉很少见
工程可靠性:
- 删库不丢:正文是文件真相,人工元数据双写侧车 JSON,
site.db随时可重建 - 增量生成靠内容指纹,改 1 页只写 1 页
- 不依赖 mbstring / Composer / Node,任何有 PHP 的机器能跑
- 草稿默认不上线、图片 hash 去重、内联样式 60KB 预算——都是踩过坑才会有的设计
内容生产能力: 四管线覆盖“文件夹书、成品 HTML、后台粘贴”三种真实工作流,标签、置顶、六种集合视图、AI 补 SEO/alt,日常发文的闭环是完整的。
欠缺什么(按重要性排)
- 搜索索引会随规模膨胀。
search.json是整站一份,几百篇没问题,上千篇后首次加载可能好几 MB。到时候需要做分片或按分类懒加载。 - 图片没有响应式处理。没有 WebP/缩略图生成、没有 srcset。正文图少无所谓,做图多的站(图库类、封面重的列表页)会拖累 LCP。
- 没有自动化部署链路。目前是本地 build → 手动拷 dist。缺一条
git push→ CI build → rsync/对象存储 的流水线,发文的最后一步全靠人肉,长期会烦。 - E-E-A-T 素材要自己补:关于页、作者页、联系方式、隐私政策这些“让搜索引擎信任的页面”系统不拦你,但也得你自己写。域名
zlib.gooli.fun做图书推荐这类站,内容同质化竞争激烈,SEO 合规只是及格线,排名靠内容本身。 - 无交互能力:评论、点赞、浏览计数都没有。静态站正常,真需要就外挂 giscus/twikoo,不算缺陷但要预留。
- 杂项:Atom 未做(RSS 有);无 HTML minify(影响很小);无多语言 hreflang;后台公网暴露时安全全押在那一个密码上,AI key 还是明文放在
config/site.json里——这份文件如果进版本管理,key 会跟着走,建议挪到环境变量或本地不入库的覆盖文件。
直接回答你的问题
- 适合做静态内容站吗? 适合,尤其是“一个人维护、几百到一两千篇”的规模,这套系统的 SEO 底子和防丢设计正好匹配这个场景。
- 符合搜索引擎要求吗? 技术性 SEO(收录、规范化、结构化数据、重定向)已经合格,剩下的是内容质量和 E-E-A-T 的事,工具帮不了。
- 它不是什么? 它不是拖拽建站工具、不是多用户平台、不是电商框架。定位很清楚:个人内容站的生产机器。
如果要我挑一件最值得马上做的事:把 AI key 从 site.json 里挪走 + 跑一次 verify 看 15 项全过不过,这两件事半小时内能做完,一个管安全一个管验收。要做的话说一声。