wip: article AI polish, category SEO fields, cover generator, membership plan seeder
This commit is contained in:
+216
-33
@@ -1,45 +1,228 @@
|
||||
# 部署与进程管理
|
||||
# 部署(生产)
|
||||
|
||||
## Web
|
||||
- nginx + php-fpm(或 Laravel Herd)
|
||||
- 参考 `deploy/nginx.conf`
|
||||
- 附件:生产 `ATTACHMENTS_DRIVER=s3`;开发可用 `local`
|
||||
Web 由 **nginx + php-fpm**(或同等 PHP-FPM)提供;**不要**把 HTTP 交给 PM2。PM2 只跑队列、调度、Workerman。
|
||||
|
||||
## 长驻进程(PM2)
|
||||
配置文件:仓库根目录 `ecosystem.config.cjs`
|
||||
本地安装见 [install.md](./install.md),迁旧站见 [import.md](./import.md)。
|
||||
|
||||
## 架构
|
||||
|
||||
```text
|
||||
浏览器 → nginx → php-fpm → Laravel (public/index.php)
|
||||
↘ /attachments-local 仅开发;生产走 S3/R2 302
|
||||
|
||||
PM2
|
||||
larablog-queue queue:work 只消费 default
|
||||
larablog-schedule schedule:work
|
||||
larablog-ai-workerman workerman:ai 消费 ai-content / ai-moderation
|
||||
```
|
||||
|
||||
`queue:ai` 是开发用的短生命周期 `queue:work` 包装,**不会**起 Workerman。生产用 `workerman:ai` **或** 单独的 `queue:work --queue=ai-content,ai-moderation`,不要和 Workerman **同时**抢同一批 AI Job。
|
||||
|
||||
## 服务器
|
||||
|
||||
| 项 | 建议 |
|
||||
|---|---|
|
||||
| PHP | 8.2 / 8.3 FPM,扩展同安装文档,外加 `redis` |
|
||||
| Workerman | CLI PHP 需 `pcntl`、`posix`(与 FPM 不是同一 php.ini 时要两边都查) |
|
||||
| 数据库 | MySQL 8 / MariaDB 10.6+(不要用 SQLite 当生产) |
|
||||
| Redis | 队列 + 缓存;多站点共用时设前缀 |
|
||||
| 附件 | S3 兼容(Cloudflare R2 / 腾讯 COS / 阿里 OSS / MinIO) |
|
||||
| 进程 | Node 的 PM2,或 systemd;配置见仓库根目录 `ecosystem.config.cjs` |
|
||||
|
||||
```bash
|
||||
# 建议 QUEUE_CONNECTION=redis,并先起 Redis
|
||||
composer install --no-dev --optimize-autoloader
|
||||
php artisan migrate --force
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan themes:publish
|
||||
php artisan plugins:sync
|
||||
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 save
|
||||
php -m | grep -E 'pcntl|posix|redis|gd'
|
||||
php-fpm -m | grep -E 'redis|gd'
|
||||
```
|
||||
|
||||
进程:
|
||||
| name | 作用 |
|
||||
|---|---|
|
||||
| `larablog-queue` | `queue:work`(default / ai-content / ai-moderation) |
|
||||
| `larablog-schedule` | `schedule:work` |
|
||||
| `larablog-ai-workerman` | Workerman AI 运行时(可选,若只用 queue:work 可删) |
|
||||
|
||||
> HTTP **不要**交给 pm2。
|
||||
|
||||
## GitHub Actions
|
||||
- `.github/workflows/ci.yml`:PHP 8.2/8.3 跑 PHPUnit(sqlite memory)
|
||||
- `deploy` job 仅作占位,需绑定 `production` environment 与自有发布脚本
|
||||
|
||||
## Redis 键前缀
|
||||
`.env`:
|
||||
## `.env`(生产要点)
|
||||
|
||||
```env
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://www.example.com
|
||||
APP_LOCALE=zh_CN
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_DATABASE=larablog
|
||||
DB_USERNAME=larablog
|
||||
DB_PASSWORD=
|
||||
|
||||
QUEUE_CONNECTION=redis
|
||||
CACHE_STORE=redis
|
||||
SESSION_DRIVER=database
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PREFIX=larablog_
|
||||
CACHE_PREFIX=larablog_cache_
|
||||
|
||||
ATTACHMENTS_DRIVER=s3
|
||||
ATTACHMENTS_DISK=attachments
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=auto
|
||||
AWS_BUCKET=
|
||||
AWS_URL=https://cdn.example.com
|
||||
AWS_ENDPOINT=https://xxx.r2.cloudflarestorage.com
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=true
|
||||
|
||||
AI_PROVIDER=openai_compatible
|
||||
AI_API_BASE_URL=
|
||||
AI_API_KEY=
|
||||
AI_MODEL=
|
||||
```
|
||||
|
||||
Laravel 会在 `config/database.php` → `redis.options.prefix` 与 cache prefix 生效。
|
||||
`APP_URL` 必须是对外 origin(含 `https`),否则附件 URL、OG、RSS 会错。
|
||||
`REDIS_PREFIX` / `CACHE_PREFIX` 避免和同机其他 Laravel 抢键。
|
||||
|
||||
## 首次发布
|
||||
|
||||
代码放到目标目录后(示例 `/var/www/larablog`):
|
||||
|
||||
```bash
|
||||
cd /var/www/larablog
|
||||
composer install --no-dev --optimize-autoloader
|
||||
cp .env.example .env
|
||||
# 编辑 .env:生产库、Redis、S3、APP_URL、AI_*
|
||||
php artisan key:generate --force
|
||||
|
||||
php artisan migrate --force
|
||||
php artisan plugins:sync
|
||||
php artisan migrate --force
|
||||
php artisan themes:publish
|
||||
|
||||
# 新站演示数据(迁 sablog 则跳过,改走 import.md)
|
||||
# php artisan db:seed --force
|
||||
|
||||
php artisan db:seed --class=Database\\Seeders\\AiSettingsSeeder --force
|
||||
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
|
||||
chmod -R ug+rwx storage bootstrap/cache
|
||||
chown -R www-data:www-data storage bootstrap/cache
|
||||
```
|
||||
|
||||
FPM 用户以发行版为准(`www-data` / `nginx` / `php-fpm`)。
|
||||
|
||||
然后配 nginx、起 PM2。
|
||||
|
||||
## nginx
|
||||
|
||||
示例:`deploy/nginx.conf`。生产至少保证:
|
||||
|
||||
- `root` 指向 **`.../public`**,不是仓库根
|
||||
- `try_files` 回 `index.php`
|
||||
- PHP 走 php-fpm socket(版本与套接字路径改成你机器上的)
|
||||
- 限制隐藏文件;按需 `client_max_body_size`(后台传附件)
|
||||
|
||||
HTTPS 用发行版 certbot / 已有证书终止 TLS。HTTP 仅作跳转。
|
||||
|
||||
生产 `ATTACHMENTS_DRIVER=s3` 时,**不必**再配 `location /attachments-local/`。正文与 `/attachment.php?id=` 会 302 到对象存储。
|
||||
|
||||
## 附件
|
||||
|
||||
| `ATTACHMENTS_DRIVER` | 行为 |
|
||||
|---|---|
|
||||
| `local` | 文件在 `storage/app/attachments`,URL `/attachments-local/...`(开发) |
|
||||
| `s3` | Flysystem S3;`AWS_*` 指向兼容端点 |
|
||||
|
||||
不要把附件长期放在 `public/` 或应用盘当生产方案。导入旧附件见 [import.md](./import.md)。
|
||||
|
||||
封面模板字需要中文时,设 `LARABLOG_COVER_FONT` 为服务器上的 TTF/OTF 绝对路径。
|
||||
|
||||
## PM2
|
||||
|
||||
`ecosystem.config.cjs` 的 `cwd` 是仓库根。若部署路径不是开发机路径,把该文件里的约定理解成「在项目根执行 `pm2 start ecosystem.config.cjs`」。
|
||||
|
||||
```bash
|
||||
cd /var/www/larablog
|
||||
# 如 PHP 不在 PATH:PHP_BINARY=/usr/bin/php pm2 start ecosystem.config.cjs
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 save
|
||||
pm2 startup
|
||||
pm2 status
|
||||
```
|
||||
|
||||
| name | 命令 | 日志 |
|
||||
|---|---|---|
|
||||
| `larablog-queue` | `queue:work redis --queue=default ...` | `storage/logs/pm2-queue.*.log` |
|
||||
| `larablog-schedule` | `schedule:work` | `storage/logs/pm2-schedule.*.log` |
|
||||
| `larablog-ai-workerman` | `workerman:ai start` | `storage/logs/pm2-ai.*.log` |
|
||||
|
||||
Workerman 自己的 pid / 日志 / 状态文件在 **`storage/logs/workerman-ai.*`**,不要写到仓库根。若根目录已有 `workerman.log` 或 `workerman.artisan.status*`:先停进程再删。
|
||||
|
||||
没有 `pcntl`/`posix` 时不要起 `larablog-ai-workerman`,可从 ecosystem 里去掉该 app,改用:
|
||||
|
||||
```bash
|
||||
php artisan queue:work redis --queue=ai-content,ai-moderation --sleep=1 --tries=3
|
||||
```
|
||||
|
||||
调度任务(`routes/console.php`):Redis 时每天 `cache:prune-stale-tags`;每周清理 7 天前的失败队列。
|
||||
|
||||
## 插件
|
||||
|
||||
```bash
|
||||
php artisan plugins:sync
|
||||
# 后台启用,或:
|
||||
php artisan plugins:sync --enable=larablog/payment,larablog/membership
|
||||
php artisan migrate --force
|
||||
php artisan config:cache
|
||||
```
|
||||
|
||||
付费内容依赖支付插件。Stub 支付仅打通下单,不是微信/支付宝。
|
||||
|
||||
## 日常更新
|
||||
|
||||
```bash
|
||||
cd /var/www/larablog
|
||||
git pull
|
||||
composer install --no-dev --optimize-autoloader
|
||||
php artisan migrate --force
|
||||
php artisan plugins:sync
|
||||
php artisan themes:publish
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
php artisan filament:upgrade
|
||||
pm2 reload ecosystem.config.cjs
|
||||
```
|
||||
|
||||
维护窗口:
|
||||
|
||||
```bash
|
||||
php artisan down
|
||||
# …发布…
|
||||
php artisan up
|
||||
```
|
||||
|
||||
改 `.env` 后必须再 `config:cache`。
|
||||
|
||||
## 日志与排障
|
||||
|
||||
| 文件 | 来源 |
|
||||
|---|---|
|
||||
| `storage/logs/laravel.log` | 应用 |
|
||||
| `storage/logs/pm2-*.log` | PM2 stdout/err |
|
||||
| `storage/logs/workerman-ai.log` | Workerman |
|
||||
| `storage/logs/workerman-ai.status` | Workerman 状态(`workerman:ai status`) |
|
||||
|
||||
```bash
|
||||
php artisan workerman:ai status
|
||||
pm2 logs larablog-ai-workerman --lines 100
|
||||
```
|
||||
|
||||
队列堆积:Redis 里看 `REDIS_PREFIX` 下的队列键;确认只开了一种 AI 消费者。
|
||||
|
||||
## 发布后自检
|
||||
|
||||
- `https://站点/`、一篇 `/show-{id}.shtml`、`/rss.xml`、`/sitemap.xml`
|
||||
- `/admin` 可登录
|
||||
- 上传一张附件,前台 `/attachment.php?id=` 能跳到对象存储
|
||||
- 后台触发一次 AI 润色,对应队列被消费(stub 或真实 API)
|
||||
- `APP_DEBUG=false`,`.env` 不能从 Web 读到
|
||||
|
||||
## CI
|
||||
|
||||
`.github/workflows/ci.yml`:PHP 8.2/8.3 PHPUnit(sqlite memory)。`deploy` job 只是占位,需绑定 GitHub `production` environment 并改成你的 rsync/ssh + 上文更新步骤。
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
# 从 sablog 导入
|
||||
|
||||
把 SaBlog-X 的内容迁到 LaraBlog:**保留文章 / 分类 ID 与内容向 URL**,附件进对象存储(或本地磁盘),源库只读、不改源站文件。
|
||||
|
||||
命令:`php artisan sablog:import`
|
||||
实现:`app/Console/Commands/SablogImportCommand.php`
|
||||
回归夹具:`tests/fixtures/sablog/`(`php artisan test --filter=SablogImportTest`)
|
||||
|
||||
## 迁什么、不迁什么
|
||||
|
||||
| 源表(默认前缀 `sablog_`) | 结果 |
|
||||
|---|---|
|
||||
| `users` | 保留 `userid`;密码写入 `password_legacy`(无盐 MD5);随机 bcrypt 占位;**邮箱为空** |
|
||||
| `categories` | 保留 `cid` |
|
||||
| `articles` | 保留 `articleid`、阅读数、置顶、可见、关闭评论、阅读密码 |
|
||||
| `comments` | `visible=1` → 已通过,否则待审;**不触发**评论插件/AI 审核 |
|
||||
| `tags` + `aids` | 标签及文章关联 |
|
||||
| `links` / `stylevars` | 友情链接、站点片段 |
|
||||
| `attachments` | 元数据 + 按 `--attachments` 目录上传;正文仍存引用,不写死 CDN |
|
||||
| `trackbacks` / `trackbacklog` / `searchindex` / `sessions` | **跳过**,只在报告里计数 |
|
||||
|
||||
不导入旧 PHP 后台、WAP、Trackback。旧 `/admin/*.php` 在新站返回 410;新后台是 `/admin`(Filament)。
|
||||
|
||||
## 导入前
|
||||
|
||||
1. 目标库已 `php artisan migrate`(含插件 migration;`AppServiceProvider` 会加载 `plugins/*/database/migrations`)。
|
||||
2. **不要先跑完整 `db:seed`。** 演示种子占用 `users.id=1`、`categories.id=1`、`articles.id=1/2`,导入按同 ID **upsert 覆盖**,还可能留下演示站多出来的行。
|
||||
3. 角色表是空的:导入**不会**写 Spatie 角色。导入后要自己建 `admin` 并赋给旧站管理员(见文末)。
|
||||
4. 配好附件盘:开发 `ATTACHMENTS_DRIVER=local`;生产用 S3/R2 等(见 [deploy.md](./deploy.md))。
|
||||
5. 源库账号建议只读。
|
||||
|
||||
## 源库与附件目录
|
||||
|
||||
`.env`(连接名默认 `sablog`,见 `config/database.php`):
|
||||
|
||||
```env
|
||||
SABLOG_DB_DRIVER=mysql
|
||||
SABLOG_DB_HOST=127.0.0.1
|
||||
SABLOG_DB_PORT=3306
|
||||
SABLOG_DB_DATABASE=sablog
|
||||
SABLOG_DB_USERNAME=readonly
|
||||
SABLOG_DB_PASSWORD=
|
||||
SABLOG_DB_CHARSET=utf8mb4
|
||||
```
|
||||
|
||||
旧库若是 GBK:
|
||||
|
||||
```env
|
||||
SABLOG_DB_CHARSET=gbk
|
||||
```
|
||||
|
||||
命令里再加 `--encoding=gbk` 或 `--encoding=auto`(非合法 UTF-8 时按 GBK 转)。
|
||||
|
||||
附件目录必须是**绝对路径**,且相对路径与表字段 `filepath` 一致。例如库里是 `2020/01/foo.jpg`,则文件应在:
|
||||
|
||||
```text
|
||||
/data/sablog/attachments/2020/01/foo.jpg
|
||||
```
|
||||
|
||||
缩略图字段 `thumb_filepath` 同样按该根目录拼接;存在则一并上传。
|
||||
|
||||
## 两种正文模式
|
||||
|
||||
| `--mode` | 库内正文 | `content_format` | 附件引用 |
|
||||
|---|---|---|---|
|
||||
| `raw`(推荐先跑) | 保持 HTML | `html` | 原样 `[attach=123]` |
|
||||
| `markdown` | HTML → Markdown | `markdown` | 改成 `attach:123`(避免 `[]` 被 Markdown 吃掉) |
|
||||
|
||||
两种模式都**不把对象存储 URL 写进正文**。前台渲染再变成 `/attachment.php?id=123`。
|
||||
|
||||
不确定旧文 HTML 质量时先 `raw`,确认站点可访问后再决定是否用 `markdown` 重导(同 ID upsert,可重跑)。
|
||||
|
||||
## 命令
|
||||
|
||||
先连通、只计数(不写目标库、不上传):
|
||||
|
||||
```bash
|
||||
php artisan sablog:import --mode=raw --dry-run
|
||||
```
|
||||
|
||||
正式导入:
|
||||
|
||||
```bash
|
||||
php artisan sablog:import \
|
||||
--mode=raw \
|
||||
--connection=sablog \
|
||||
--prefix=sablog_ \
|
||||
--attachments=/绝对路径/sablog/attachments \
|
||||
--disk=attachments \
|
||||
--encoding=auto
|
||||
```
|
||||
|
||||
| 参数 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `--connection` | `sablog` | Laravel 连接名 |
|
||||
| `--prefix` | `sablog_` | 源表前缀 |
|
||||
| `--attachments` | 空 | 本地附件根目录;不传则附件记为 missing |
|
||||
| `--mode` | `raw` | `raw` \| `markdown` |
|
||||
| `--encoding` | `auto` | `utf8` \| `gbk` \| `auto` |
|
||||
| `--disk` | `attachments` | 目标 disk |
|
||||
| `--retry-failed` | 关 | 已有 `synced_at` 的附件默认跳过;打开则重试失败/缺失 |
|
||||
| `--dry-run` | 关 | 只读源库并打印计数 |
|
||||
|
||||
成功后打印一张表:`users` / `categories` / `articles` / `comments` / `tags` / `links` / `stylevars` / `attachments_ok` / `attachments_missing` / `attachments_failed` / 跳过的 trackback 等。源库与源文件不会被修改。
|
||||
|
||||
整次导入包在一个事务里(附件上传在事务内;失败会 warn 并继续记 missing/failed 行)。缺文件不会中断整次导入。
|
||||
|
||||
## 附件补传
|
||||
|
||||
第一次没带 `--attachments`、或路径不对导致 `attachments_missing`:
|
||||
|
||||
```bash
|
||||
php artisan sablog:import --mode=raw --attachments=/正确/路径 --retry-failed
|
||||
```
|
||||
|
||||
已成功(`synced_at` 有值)的附件默认不再上传。
|
||||
|
||||
## 导入后:登录与后台
|
||||
|
||||
旧站密码是 **MD5**。导入后:
|
||||
|
||||
- 前台 `/login.shtml` 用**用户名 + 旧密码**可登录;校验成功后升级为 bcrypt,并清空 `password_legacy`。
|
||||
- Filament `/admin` 用**邮箱**登录。导入用户 `email` 为空,且**没有** `admin` 角色,所以要补一步:
|
||||
|
||||
```bash
|
||||
php artisan tinker
|
||||
```
|
||||
|
||||
```php
|
||||
use App\Models\User;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
Role::findOrCreate('admin');
|
||||
Role::findOrCreate('editor');
|
||||
Role::findOrCreate('member');
|
||||
|
||||
$user = User::query()->where('username', '旧站管理员用户名')->first();
|
||||
$user->forceFill(['email' => 'you@example.com'])->save();
|
||||
$user->assignRole('admin');
|
||||
```
|
||||
|
||||
然后打开 `/admin`,邮箱 + **旧站密码**(或升级后的同一密码)。
|
||||
|
||||
AI 设置可单独灌,不必跑演示博客种子:
|
||||
|
||||
```bash
|
||||
php artisan db:seed --class=Database\\Seeders\\AiSettingsSeeder
|
||||
```
|
||||
|
||||
## 导入后检查
|
||||
|
||||
- 首页、`/show-{旧文章id}.shtml`、`/category-{旧分类id}.shtml`
|
||||
- 正文图是否经 `/attachment.php?id=` 能打开
|
||||
- 评论作者、友情链接、站点片段
|
||||
- `attachments_missing` / `attachments_failed` 是否可接受
|
||||
- 阅读密码文章:前台仍走密码墙(与单篇付费、会员可见互斥,见后台校验)
|
||||
|
||||
## 注意
|
||||
|
||||
- **幂等**:按原 ID upsert,可重复执行;附件成功过的默认跳过。
|
||||
- **ID 对齐是为了 SEO**:不要在导入后再批量改文章 ID。
|
||||
- 导入用户没有邮箱、没有角色;前台读者用用户名登录即可。
|
||||
- 插件付费/会员数据不在 sablog 里,导入后如需付费墙,在新后台按篇配置。
|
||||
- 夹具库仅供测试,不是完整 sablog 结构说明;以你线上表为准。缺表则该项计数为 0,不报错退出。
|
||||
@@ -0,0 +1,156 @@
|
||||
# 安装(本地开发)
|
||||
|
||||
把 LaraBlog 跑起来:前台、Filament 后台、演示数据。从 sablog 迁站请先看 [import.md](./import.md),**不要先灌演示数据**。上线见 [deploy.md](./deploy.md)。
|
||||
|
||||
## 环境
|
||||
|
||||
| 项 | 要求 |
|
||||
|---|---|
|
||||
| PHP | **8.2+**(`composer.json`) |
|
||||
| 扩展 | `mbstring`、`openssl`、`pdo`、`tokenizer`、`xml`、`ctype`、`json`、`fileinfo`、`gd`(封面/图片)、`zip` |
|
||||
| Composer | 2.x |
|
||||
| 数据库 | 开发可用 SQLite;也可用 MySQL / MariaDB |
|
||||
| 可选 | Redis(队列/缓存);Node.js 仅在改前端资源时需要 |
|
||||
| 可选 | `pcntl` + `posix`(本机跑 `workerman:ai`;没有就用 `queue:ai`) |
|
||||
|
||||
macOS 可用 Laravel Herd / Valet,指向仓库的 `public/`。也可用 `php artisan serve`。
|
||||
|
||||
## 1. 代码与依赖
|
||||
|
||||
```bash
|
||||
cd /path/to/larablog
|
||||
composer install
|
||||
cp .env.example .env
|
||||
php artisan key:generate
|
||||
```
|
||||
|
||||
## 2. 配置 `.env`
|
||||
|
||||
最少改这些:
|
||||
|
||||
```env
|
||||
APP_NAME=LaraBlog
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://larablog.test # 必须和浏览器访问的 origin 一致
|
||||
APP_LOCALE=zh_CN
|
||||
|
||||
# 开发默认 SQLite(文件需存在)
|
||||
DB_CONNECTION=sqlite
|
||||
# DB_DATABASE=/绝对路径/database/database.sqlite
|
||||
|
||||
# 开发附件落本地,不必配 S3
|
||||
ATTACHMENTS_DRIVER=local
|
||||
|
||||
QUEUE_CONNECTION=database
|
||||
CACHE_STORE=database
|
||||
SESSION_DRIVER=database
|
||||
|
||||
# 本机没有真实 LLM 时用 stub,避免后台点「AI 润色」去打外网
|
||||
AI_PROVIDER=stub
|
||||
```
|
||||
|
||||
SQLite 文件:
|
||||
|
||||
```bash
|
||||
mkdir -p database
|
||||
touch database/database.sqlite
|
||||
```
|
||||
|
||||
改用 MySQL 时:
|
||||
|
||||
```env
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=larablog
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
```
|
||||
|
||||
## 3. 初始化
|
||||
|
||||
```bash
|
||||
php artisan migrate
|
||||
php artisan db:seed
|
||||
php artisan plugins:sync
|
||||
php artisan migrate # 插件表(支付/会员等)随 discover 加载,再跑一遍即可
|
||||
php artisan themes:publish
|
||||
```
|
||||
|
||||
`db:seed` 会:
|
||||
|
||||
- 写入 AI 设置(来自 `.env` 的 `AI_*`)
|
||||
- 启用 `larablog/ai-comment-moderation`,并尝试启用 `payment` / `membership`
|
||||
- 创建演示分类、文章、友情链接
|
||||
- 创建后台账号
|
||||
|
||||
## 4. 启动
|
||||
|
||||
**Herd / nginx:** 站点根目录设为 `public/`,打开 `APP_URL`。
|
||||
|
||||
**内置服务器:**
|
||||
|
||||
```bash
|
||||
php artisan serve
|
||||
```
|
||||
|
||||
本地要排空队列(含 AI)可以另开终端:
|
||||
|
||||
```bash
|
||||
php artisan queue:work --tries=3
|
||||
# 或只处理 AI 队列(不会启动 Workerman):
|
||||
php artisan queue:ai
|
||||
```
|
||||
|
||||
改 Filament/Vite 资源时才需要 `npm install && npm run dev`。主题 CSS 走 `php artisan themes:publish` 拷到 `public/themes/`。
|
||||
|
||||
## 5. 入口与账号
|
||||
|
||||
| 入口 | 地址 |
|
||||
|---|---|
|
||||
| 前台 | `/`、`/show-1.shtml`、`/login.shtml` |
|
||||
| 后台 | `/admin` |
|
||||
| API | `/api/v1/meta`、`/api/v1/articles` |
|
||||
| OpenAPI | `/docs/api/openapi.yaml` |
|
||||
|
||||
演示管理员(`DemoBlogSeeder`):
|
||||
|
||||
- 邮箱:`admin@larablog.test`
|
||||
- 密码:`password`
|
||||
|
||||
登录后请立刻改密码。不要把这组账号用在公网。
|
||||
|
||||
## 6. 插件(可选)
|
||||
|
||||
```bash
|
||||
php artisan plugins:sync
|
||||
# 后台 → 插件 → 启用;或:
|
||||
php artisan plugins:sync --enable=larablog/payment,larablog/membership
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
依赖顺序:先 `larablog/payment`,再 `larablog/paid-content` / `larablog/membership`。说明见后台卡片「使用说明」,以及 `docs/plugins.md`。
|
||||
|
||||
## 7. 自检
|
||||
|
||||
```bash
|
||||
php artisan test
|
||||
php artisan route:list --path=shtml
|
||||
```
|
||||
|
||||
浏览器打开首页、一篇 `.shtml` 文章、`/admin`。本地附件地址形如 `/attachments-local/...`(由 Laravel 路由提供,不必 `storage:link`)。
|
||||
|
||||
## 常见问题
|
||||
|
||||
**500 / 空白页**
|
||||
`storage/`、`bootstrap/cache/` 对 PHP 进程可写;`APP_KEY` 已生成;`APP_DEBUG=true` 看 `storage/logs/laravel.log`。
|
||||
|
||||
**后台样式丢失**
|
||||
执行 `php artisan filament:upgrade` 与 `php artisan themes:publish`。
|
||||
|
||||
**点了 AI 润色没反应**
|
||||
`AI_PROVIDER=stub` 时也要有队列消费者;`QUEUE_CONNECTION=sync` 会在请求内执行(仅调试)。生产见 [deploy.md](./deploy.md)。
|
||||
|
||||
**准备导入旧站**
|
||||
不要用这份「演示种子」当生产数据。空库 `migrate` 后直接走 [import.md](./import.md)。
|
||||
Reference in New Issue
Block a user