Files
laralog/README.md
T
ak 8fdf8dbb4b docs: 开发规范/教程/demo 全套 + 修复插件运行期自动加载缺口
- demo 插件 plugins/demo.hello-world:演示短代码过滤器、comment.created 钩子、路由+命名空间视图、迁移+模型、后台设置页、filament.post_form 表单注入
- demo 主题 themes/demo:最小可运行主题(覆盖 partials + 绿色系样式)
- 教程 docs/tutorial-plugin.md / docs/tutorial-theme.md(10 分钟上手);规范 docs/development.md(代码/插件/主题/队列/测试/提交)
- README 增加开发者文档导航与上手示例
- 修复关键缺口:插件类原来靠 composer.json 硬编码加载,第三方 ZIP 安装的插件无法加载;现改为启动时扫描 plugins/*/src 运行期注册 PSR-4(register 阶段,保证 Filament 面板解析插件页面前就绪),composer.json 移除硬编码
- 测试:demo 插件 3 个用例 + demo 主题渲染;全量 89 通过
2026-08-12 17:26:34 +08:00

158 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LaraLog
基于 **Laravel 12 + Filament 5 + Livewire 4 + Spatie 生态** 的现代化博客系统,从 SaBlog-X 1.6 完整迁移而来:
- **脚本迁移**`php artisan sablog:import` 一键从老库迁入全部数据(文章/分类/评论/标签/友链/用户/附件),保留原始 ID,老 URL 全部 301 兼容
- **多主题**`themes/` 目录即皮肤,后台一键切换/上传 ZIP;内置 sablog 经典风 + modern 简约风两套
- **插件系统**`plugins/` 目录 + 钩子系统(action/filter),ZIP 安装 + 可选远程市场
- **内置插件**SEO & GEOJSON-LD/OG/llms.txt/Markdown 导出)、AI 评论审核 + 内容润色(Workerman 异步)、支付(支付宝/微信/沙箱)、会员(套餐订阅 + 付费文章)
- **附件全走 S3**R2 / COS / OSS 兼容,新上传零落盘,`attachments:sync-s3` 一键同步老附件(大文件 Multipart)
## 技术栈
| 组件 | 版本 | 说明 |
|------|------|------|
| Laravel | ^12.0 | 应用框架 |
| Filament | ^5.7 | 后台面板(zh_CN |
| Livewire | ^4.4 | 前台交互 |
| Workerman | ^5.2 | 常驻进程:队列消费者 + WebSocket 进度推送 |
| yansongda/pay | ^3.7 | 支付宝 / 微信支付 |
| spatie 库 | — | permission / medialibrary / sitemap / robots / tags / backup |
| league/commonmark | ^2.9 | Markdown 渲染(GFM |
| league/html-to-markdown | ^5.1 | 老 HTML 内容转换 |
| MySQL | 8.x | 数据库 |
## 快速开始
```bash
# 1. 安装依赖
composer install
cp .env.example .env
php artisan key:generate
# 2. 配置 .envMySQL 8
DB_DATABASE=laralog
DB_USERNAME=root
DB_PASSWORD=
# 3. 迁移 + 种子(创建 admin@laralog.test / password
php artisan migrate --seed
# 4. 启动(Herd 或 artisan serve
php artisan serve
# 5. 后台:http://laralog.test/admin
```
## 迁移老 Sablog
```bash
# 原始导入(内容保持 HTML,[attach=xx] 渲染时解析)
php artisan sablog:import \
--database=sablog --host=127.0.0.1 --port=3306 \
--username=root --password=xxx \
--attachments-dir=/path/to/old/attachments --sync-attachments
# 同时把内容转换为 Markdown[attach=xx] 转为 {{attach:xx}} 令牌)
php artisan sablog:import ... --convert-markdown
# 事后单独转换 / 同步附件到 S3
php artisan content:convert --all
S3_ACCESS_KEY=... S3_BUCKET=... S3_ENDPOINT=... php artisan attachments:sync-s3 --legacy-dir=/path/to/old/attachments
```
> 不迁移的过时功能:trackback(引用通告,垃圾来源)、搜索缓存表、验证码(由 AI 审核 + 蜜罐 + 频控取代)、WAP、广告位变量。
## 主题
- 目录:`themes/{name}/`,含 `theme.json`(标题/版本/描述/作者)+ `views/**` + `assets/`
- 激活主题的 views 目录前置到全局视图路径:主题覆盖同名视图,缺失自动回退默认视图
- 资产开发期由 `/themes/{name}/assets/...` 流式返回;生产可 `php artisan theme:publish`(见 docs/deploy.md
- 后台「主题管理」可激活 / 上传 ZIP / 删除
## 插件
- 目录:`plugins/{vendor}.{name}/`,含 `plugin.json` + `src/ServiceProvider.php`(继承 `App\Blog\Support\PluginServiceProvider`+ 可选 `database/migrations``routes/web.php``views/`
- 钩子:`addAction(hook, cb)` / `addFilter(hook, cb, priority)`,核心钩子:
- `comment.created`AI 审核)、`payment.paid`(按 payable 分发订阅激活/解锁)、`post.rendered`(付费内容过滤/paywall)、`seo.structured_data`
- `filament.post_form` / `filament.post_table`(后台文章表单/表格注入)
- 插件依赖 `requires` 强制校验:启用需依赖已启用,停用/卸载会被依赖者阻止;启动时依赖不满足的插件跳过
- 订单商品化:`Payment` 多态 `payable` 关联购买实体,实体实现 `payableLabel()` / `payableUrl()` 接入订单展示(详见 docs/plugins.md
- 后台「插件管理」:启停 / 上传 ZIP 安装 / 卸载 / 市场拉取(配置 `MARKET_URL` 后可用)
- 插件自带迁移由 `migrate` 自动加载(`app/Providers/AppServiceProvider` 注册 plugins/*/database/migrations
## 内容格式
- 每篇文章有 `content_format`markdown / html),新文章默认 Markdown
- 老数据导入标记为 html 原样保留;`content:convert` 批量转 Markdown
- 附件短代码:HTML 内容用 `[attach=1]` / `[img=1]`Markdown 内容用 `{{attach:1}}` / `{{img:1}}``[]` 是 Markdown 保留字符),渲染时统一解析
- 付费内容:`[paid]...[/paid]` 短代码,非会员/未解锁访客隐藏(会员插件)
## 异步处理(Workerman
```bash
php artisan workerman:serve start # 队列消费者 × N + WebSocket :8787
php artisan workerman:serve stop
```
- 消费者复用 Laravel `Queue\Worker`**database / redis 队列统一支持**,常驻进程内框架只启动一次(省去每个任务的启动开销)
- 任务统一实现 `App\Blog\Jobs\AiJob` 接口(`handle(LlmClient)`),依赖由容器自动注入
- 队列选择:
- database(默认):`WORKERMAN_QUEUE_CONNECTION=database`
- redis`WORKERMAN_QUEUE_CONNECTION=redis` 并确保 `QUEUE_CONNECTION=redis``REDIS_*` 配置正确;`redis` 连接的 `block_for` 建议设为 `0`(配合 1s 轮询,避免阻塞 Workerman event loop
- 消费队列:`WORKERMAN_QUEUES=default,ai`(ai 队列为 AI 审核/润色任务)
- 失败重试:`WORKERMAN_MAX_TRIES`(默认 3),超时 `WORKERMAN_TIMEOUT`(默认 60s),重试耗尽进 `failed_jobs`
- 降级路径:`php artisan queue:work` 照常可用(同一队列)
## 前台缓存
- 匿名 GET 页面整页缓存(首页/列表/文章/归档/标签等),TTL 默认 300 秒(`PAGE_CACHE_TTL`),命中时零数据库查询
- 文章浏览量由独立 `/track-view` 端点统计,不受整页缓存影响(实时)
- 后台「缓存管理」:清空页面/侧边栏/设置/全部缓存、重建编译缓存
- 侧边栏数据与站点设置另有 1 小时缓存
## 对外 API
- 交互式文档(OpenAPI/Swagger 风格):`GET /docs/api`
- 端点:`/api/site``/api/posts``/api/posts/{slug}``/api/categories``/api/tags``POST /api/comments``/api/me`Bearer Token
- 供小程序 / 第三方平台接入,详见 `docs/api.md`
## 测试
```bash
php artisan test # 84 个用例:迁移/老路由 301/主题/插件/会员支付流/AI 审核/商城购买
```
## 开发者文档
| 文档 | 内容 |
|------|------|
| [docs/development.md](docs/development.md) | 开发规范(代码/插件/主题/队列/测试/提交) |
| [docs/tutorial-plugin.md](docs/tutorial-plugin.md) | 插件开发教程(10 分钟上手,配套 demo) |
| [docs/tutorial-theme.md](docs/tutorial-theme.md) | 主题开发教程(10 分钟上手,配套 demo) |
| [docs/plugins.md](docs/plugins.md) | 插件 API 详解(钩子/依赖/商品化/市场契约) |
| [docs/themes.md](docs/themes.md) | 主题 API 详解(视图解析/注入点/变量) |
| [docs/architecture.md](docs/architecture.md) | 架构与设计决策 |
| [docs/api.md](docs/api.md) | 对外 API(小程序/第三方) |
| [docs/deploy.md](docs/deploy.md) | 部署(nginx/systemd/workerman/cron |
**上手示例**
- 插件:`plugins/demo.hello-world/`(短代码 / 钩子 / 路由 / 后台页 / 迁移 / 表单注入,全演示)
- 主题:`themes/demo/`(最小可运行主题,绿色系,覆盖 partials 即可换肤)
## 目录结构
```
app/
Blog/ # 前台域模块(Controllers/Jobs/Services/Support/View
Filament/ # 后台资源与页面
Console/Commands # sablog:import / attachments:sync-s3 / workerman:serve / content:convert
themes/ # 主题(sablog / modern / demo 示例)
plugins/ # 内置插件(blog-seo / ai-moderation / payment / membership+ demo.hello-world 示例
docs/ # 全部文档(见上文表格)
```
## 许可
MIT