feat: use xpier media library for uploads and markdown embeds
Store media:ID in post bodies instead of CDN URLs, and keep sablog attach tokens as a fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -79,6 +79,10 @@ WORKERMAN_TIMEOUT=60
|
||||
|
||||
# ---- 附件 S3 兼容存储(R2 / COS / OSS / MinIO),不配置则回退本地 public ----
|
||||
UPLOAD_DISK=uploads
|
||||
# New uploads/covers use xpier media library (keep sablog Spatie attachments as fallback)
|
||||
MEDIA_DISK=public
|
||||
MEDIA_DIRECTORY=media
|
||||
MEDIA_VISIBILITY=public
|
||||
S3_ACCESS_KEY=
|
||||
S3_SECRET_KEY=
|
||||
S3_REGION=auto
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-09-16
|
||||
|
||||
- Switched new attachments/covers to `xpier/filament-media-library`.
|
||||
- Markdown body now inserts `` (files: `[name](media:ID)`); URLs are resolved at render time. Legacy sablog attach tokens are unchanged.
|
||||
- Schema snapshot: `docs/database/mysql-schema-20260916-131822.sql`.
|
||||
|
||||
## 2026-09-07
|
||||
|
||||
- Synced this repository from Gitea to local Herd for development (`http://laralog.test`).
|
||||
- Local schema snapshot: `docs/database/schema-20260907-223917.sql`.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# LaraLog Features
|
||||
|
||||
Modern blog migrated from SaBlog-X: Filament admin, themes, plugins, sablog import, S3 attachments, Workerman AI queue.
|
||||
|
||||
## Local development
|
||||
|
||||
- Site: http://laralog.test
|
||||
- Admin: http://laralog.test/admin
|
||||
- Account: `admin@laralog.test` / `password`
|
||||
- Database: MySQL `laralog` (Herd, root / empty password)
|
||||
- Remote: `git@gitea.neatcn.com:gouki/laralog.git`
|
||||
|
||||
See `README.md` and `docs/` for install, import, plugins, and themes.
|
||||
|
||||
## Media library (xpier)
|
||||
|
||||
- Package: `xpier/filament-media-library` (admin Media Library + MediaPicker).
|
||||
- **Markdown body must store `` or `[name](media:ID)`**, never a CDN/object-storage URL. HTML uses `[media=ID]`.
|
||||
- Insert flow: pick a file → **Insert into body**. Cover uses `cover_media_id`.
|
||||
- Legacy sablog `[attach=ID]` / `{{attach:ID}}` still render from Spatie media.
|
||||
- Details: `docs/media.md`.
|
||||
@@ -10,17 +10,17 @@
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 组件 | 版本 | 说明 |
|
||||
|------|------|------|
|
||||
| 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 | 数据库 |
|
||||
| 组件 | 版本 | 说明 |
|
||||
| ----------------------- | ----- | ------------------------------------------------------------ |
|
||||
| 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 | 数据库 |
|
||||
|
||||
## 快速开始
|
||||
|
||||
@@ -74,8 +74,8 @@ S3_ACCESS_KEY=... S3_BUCKET=... S3_ENDPOINT=... php artisan attachments:sync-s3
|
||||
|
||||
- 目录:`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`(后台文章表单/表格注入)
|
||||
- `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` 后可用)
|
||||
@@ -85,7 +85,7 @@ S3_ACCESS_KEY=... S3_BUCKET=... S3_ENDPOINT=... php artisan attachments:sync-s3
|
||||
|
||||
- 每篇文章有 `content_format`(markdown / html),新文章默认 Markdown
|
||||
- 老数据导入标记为 html 原样保留;`content:convert` 批量转 Markdown
|
||||
- 附件短代码:HTML 内容用 `[attach=1]` / `[img=1]`,Markdown 内容用 `{{attach:1}}` / `{{img:1}}`(`[]` 是 Markdown 保留字符),渲染时统一解析
|
||||
- 附件短代码:新图 `` / `[name](media:ID)`;HTML `[media=ID]`。老附件 HTML `[attach=1]` / `[img=1]`,Markdown `{{attach:1}}` / `{{img:1}}`。不要把 CDN 地址写进正文(见 [docs/media.md](docs/media.md))。
|
||||
- 付费内容:`[paid]...[/paid]` 短代码,非会员/未解锁访客隐藏(会员插件)
|
||||
|
||||
## 异步处理(Workerman)
|
||||
@@ -98,8 +98,8 @@ 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)
|
||||
- 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` 照常可用(同一队列)
|
||||
@@ -107,6 +107,7 @@ php artisan workerman:serve stop
|
||||
## 外链中转(/go,内置插件)
|
||||
|
||||
内置插件 `neatstudio.link-tracker`(外链中转):
|
||||
|
||||
- 正文外链、评论正文 URL、评论作者网址、友链统一改写为 `/go/{hash}`:302 跳转 + **点击统计**、可**停用拦截**(返回 410)、隐藏真实链接、为未来广告位预留
|
||||
- 站内链接/相对路径/mailto/tel/锚点不中转;同一 URL 复用同一短码
|
||||
- 后台「管理 → 外链中转」可查看点击量、启停、删除
|
||||
@@ -128,25 +129,27 @@ php artisan workerman:serve stop
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
php artisan test # 84 个用例:迁移/老路由 301/主题/插件/会员支付流/AI 审核/商城购买
|
||||
php artisan test # Feature + Unit: import, legacy URLs, themes, plugins, membership, media:ID render
|
||||
```
|
||||
|
||||
## 开发者文档
|
||||
|
||||
| 文档 | 内容 |
|
||||
|------|------|
|
||||
| [docs/install.md](docs/install.md) | 安装指南(环境/配置/验收清单) |
|
||||
| [docs/import.md](docs/import.md) | Sablog 老数据导入(命令/映射/附件/301 兼容) |
|
||||
| [docs/deploy.md](docs/deploy.md) | 部署(nginx/systemd/workerman/cron/上线清单) |
|
||||
| [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/install.md](docs/install.md) | 安装指南(环境/配置/验收清单) |
|
||||
| [docs/import.md](docs/import.md) | Sablog 老数据导入(命令/映射/附件/301 兼容) |
|
||||
| [docs/deploy.md](docs/deploy.md) | 部署(nginx/systemd/workerman/cron/上线清单) |
|
||||
| [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/media.md](docs/media.md) | Media library + Markdown `media:ID` |
|
||||
| [docs/api.md](docs/api.md) | 对外 API(小程序/第三方) |
|
||||
|
||||
**上手示例**:
|
||||
|
||||
- 插件:`plugins/demo.hello-world/`(短代码 / 钩子 / 路由 / 后台页 / 迁移 / 表单注入,全演示)
|
||||
- 主题:`themes/demo/`(最小可运行主题,绿色系,覆盖 partials 即可换肤)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Blog\Services;
|
||||
|
||||
use App\Blog\Support\MarkdownMediaEmbed;
|
||||
use App\Models\Post;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use League\CommonMark\Environment\Environment;
|
||||
@@ -36,11 +37,15 @@ class PostContentRenderer
|
||||
*/
|
||||
public function render(Post $post): string
|
||||
{
|
||||
$embed = app(MarkdownMediaEmbed::class);
|
||||
$raw = (string) $post->content;
|
||||
|
||||
$content = $post->content_format === 'markdown'
|
||||
? $this->toHtml($post->content)
|
||||
: $post->content;
|
||||
? $this->toHtml($embed->expandMarkdown($raw))
|
||||
: $raw;
|
||||
|
||||
$html = $this->renderShortcodes($content, $post);
|
||||
$html = $embed->hydrateHtml($html);
|
||||
|
||||
// 插件钩子:付费内容过滤、AI 处理等
|
||||
$html = app(\App\Blog\Support\PluginManager::class)->applyFilters('post.rendered', $html, $post);
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Blog\Support;
|
||||
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
|
||||
/**
|
||||
* Markdown/HTML body must store library references, never CDN URLs.
|
||||
*
|
||||
* Markdown:  or [file.pdf](media:12)
|
||||
* HTML: [media=12]
|
||||
*/
|
||||
class MarkdownMediaEmbed
|
||||
{
|
||||
public const PROTOCOL = 'media:';
|
||||
|
||||
public function snippet(MediaLibrary $media, string $format = 'markdown'): string
|
||||
{
|
||||
$id = (int) $media->getKey();
|
||||
$isImage = $this->isImage($media);
|
||||
|
||||
if ($format === 'html') {
|
||||
return '[media='.$id.']';
|
||||
}
|
||||
|
||||
$label = $this->escapeMdLabel($this->label($media, $isImage));
|
||||
|
||||
return $isImage
|
||||
? ''
|
||||
: '['.$label.']('.self::PROTOCOL.$id.')';
|
||||
}
|
||||
|
||||
public function expandMarkdown(string $markdown): string
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/\]\(media:(\d+)\)/i',
|
||||
function (array $matches): string {
|
||||
$url = $this->publicUrl((int) $matches[1]);
|
||||
|
||||
return $url !== null ? ']('.$url.')' : $matches[0];
|
||||
},
|
||||
$markdown
|
||||
) ?? $markdown;
|
||||
}
|
||||
|
||||
public function hydrateHtml(string $html): string
|
||||
{
|
||||
$html = preg_replace_callback(
|
||||
'/\b(src|href)=([\'"])media:(\d+)\2/i',
|
||||
function (array $matches): string {
|
||||
$url = $this->publicUrl((int) $matches[3]);
|
||||
if ($url === null) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
return $matches[1].'='.$matches[2].$url.$matches[2];
|
||||
},
|
||||
$html
|
||||
) ?? $html;
|
||||
|
||||
return preg_replace_callback(
|
||||
'/\[media=(\d+)\]/i',
|
||||
function (array $matches): string {
|
||||
$id = (int) $matches[1];
|
||||
$media = $this->find($id);
|
||||
$url = $this->publicUrl($id);
|
||||
|
||||
if ($url === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($media && $this->isImage($media)) {
|
||||
return sprintf(
|
||||
'<img src="%s" alt="%s" loading="lazy" />',
|
||||
e($url),
|
||||
e($this->label($media, true))
|
||||
);
|
||||
}
|
||||
|
||||
$label = $media ? $this->label($media, false) : 'file-'.$id;
|
||||
|
||||
return sprintf('<a href="%s">%s</a>', e($url), e($label));
|
||||
},
|
||||
$html
|
||||
) ?? $html;
|
||||
}
|
||||
|
||||
public function find(int $id): ?MediaLibrary
|
||||
{
|
||||
try {
|
||||
return MediaLibrary::query()->find($id);
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function publicUrl(int $id): ?string
|
||||
{
|
||||
$media = $this->find($id);
|
||||
$url = $media?->url;
|
||||
|
||||
return filled($url) ? (string) $url : null;
|
||||
}
|
||||
|
||||
public function isImage(MediaLibrary $media): bool
|
||||
{
|
||||
if ($media->type === MediaLibrary::TYPE_IMAGE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_string($media->mime_type) && str_starts_with($media->mime_type, 'image/');
|
||||
}
|
||||
|
||||
protected function label(MediaLibrary $media, bool $isImage): string
|
||||
{
|
||||
if (filled($media->alt_text)) {
|
||||
return (string) $media->alt_text;
|
||||
}
|
||||
|
||||
$name = (string) ($media->original_name ?: basename((string) $media->path) ?: 'media-'.$media->getKey());
|
||||
|
||||
return $isImage ? (pathinfo($name, PATHINFO_FILENAME) ?: $name) : $name;
|
||||
}
|
||||
|
||||
protected function escapeMdLabel(string $label): string
|
||||
{
|
||||
return str_replace(['[', ']', '!'], ['\\[', '\\]', '\\!'], $label);
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Resources\Categories\Schemas;
|
||||
|
||||
use App\Support\MediaDisk;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Xpier\FilamentMediaLibrary\Components\MediaPicker;
|
||||
|
||||
class CategoryForm
|
||||
{
|
||||
@@ -43,12 +42,11 @@ class CategoryForm
|
||||
]),
|
||||
Section::make('封面')
|
||||
->schema([
|
||||
SpatieMediaLibraryFileUpload::make('cover')
|
||||
MediaPicker::make('cover_media_id')
|
||||
->label('封面图')
|
||||
->collection('cover')
|
||||
->image()
|
||||
->imageEditor()
|
||||
->disk(MediaDisk::name()),
|
||||
->module('articles')
|
||||
->mediaType('image')
|
||||
->relationship('coverMedia'),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ class MediaResource extends Resource
|
||||
|
||||
protected static ?string $pluralModelLabel = '媒体';
|
||||
|
||||
public static function shouldRegisterNavigation(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static ?string $model = Media::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
|
||||
|
||||
@@ -2,18 +2,23 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Filament\Resources\Posts\Schemas;
|
||||
|
||||
use App\Support\MediaDisk;
|
||||
use App\Blog\Support\MarkdownMediaEmbed;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\MarkdownEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Schemas\Components\Actions;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||
use Xpier\FilamentMediaLibrary\Components\MediaPicker;
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
|
||||
class PostForm
|
||||
{
|
||||
@@ -39,7 +44,8 @@ class PostForm
|
||||
'markdown' => 'Markdown',
|
||||
'html' => 'HTML',
|
||||
])
|
||||
->default('markdown'),
|
||||
->default('markdown')
|
||||
->live(),
|
||||
Select::make('status')
|
||||
->label('状态')
|
||||
->options([
|
||||
@@ -51,17 +57,49 @@ class PostForm
|
||||
MarkdownEditor::make('content')
|
||||
->label('正文')
|
||||
->required()
|
||||
->helperText('Markdown 插入图片用 ,文件用 [文件名](media:ID)。不要把 CDN / 对象存储地址写进正文。')
|
||||
->fileAttachments(false)
|
||||
->columnSpanFull(),
|
||||
MediaPicker::make('insert_media_id')
|
||||
->label('从媒体库插入正文')
|
||||
->module('articles')
|
||||
->mediaType(null)
|
||||
->dehydrated(false)
|
||||
->helperText('选好媒体后点「插入到正文」。Markdown 写入 media:ID 引用,渲染时再换成真实地址。')
|
||||
->columnSpanFull(),
|
||||
Actions::make([
|
||||
Action::make('insertSelectedMedia')
|
||||
->label('插入到正文')
|
||||
->action(function (Get $get, Set $set): void {
|
||||
$mediaId = $get('insert_media_id');
|
||||
$media = is_numeric($mediaId)
|
||||
? MediaLibrary::query()->find((int) $mediaId)
|
||||
: null;
|
||||
|
||||
if (! $media instanceof MediaLibrary) {
|
||||
Notification::make()->title('请先从媒体库选择文件')->warning()->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$snippet = app(MarkdownMediaEmbed::class)->snippet(
|
||||
$media,
|
||||
(string) ($get('content_format') ?: 'markdown')
|
||||
);
|
||||
$set('content', rtrim((string) $get('content'))."\n\n".$snippet."\n");
|
||||
$set('insert_media_id', null);
|
||||
Notification::make()->title('已写入正文引用')->success()->send();
|
||||
}),
|
||||
])->columnSpanFull(),
|
||||
]),
|
||||
\Filament\Schemas\Components\Section::make('封面与摘要')
|
||||
->columns(2)
|
||||
->schema([
|
||||
SpatieMediaLibraryFileUpload::make('cover')
|
||||
MediaPicker::make('cover_media_id')
|
||||
->label('封面图')
|
||||
->collection('cover')
|
||||
->image()
|
||||
->imageEditor()
|
||||
->disk(MediaDisk::name())
|
||||
->module('articles')
|
||||
->mediaType('image')
|
||||
->relationship('coverMedia')
|
||||
->columnSpanFull(),
|
||||
Textarea::make('excerpt')
|
||||
->label('摘要(留空自动截取)')
|
||||
|
||||
@@ -6,8 +6,10 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
class Category extends Model implements HasMedia
|
||||
@@ -21,6 +23,7 @@ class Category extends Model implements HasMedia
|
||||
'display_order',
|
||||
'post_count',
|
||||
'description',
|
||||
'cover_media_id',
|
||||
];
|
||||
|
||||
public function posts(): HasMany
|
||||
@@ -28,6 +31,21 @@ class Category extends Model implements HasMedia
|
||||
return $this->hasMany(Post::class);
|
||||
}
|
||||
|
||||
public function coverMedia(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(MediaLibrary::class, 'cover_media_id');
|
||||
}
|
||||
|
||||
public function coverImageUrl(): ?string
|
||||
{
|
||||
$libraryUrl = $this->coverMedia?->url;
|
||||
if (filled($libraryUrl)) {
|
||||
return (string) $libraryUrl;
|
||||
}
|
||||
|
||||
return $this->getFirstMedia('cover')?->getUrl();
|
||||
}
|
||||
|
||||
public function getUrlAttribute(): string
|
||||
{
|
||||
return route('category.show', $this->slug ?? $this->id);
|
||||
|
||||
+26
-2
@@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
use Spatie\Tags\HasTags;
|
||||
@@ -30,6 +31,7 @@ class Post extends Model implements HasMedia
|
||||
'content',
|
||||
'content_format',
|
||||
'keywords',
|
||||
'cover_media_id',
|
||||
'status',
|
||||
'is_sticky',
|
||||
'close_comment',
|
||||
@@ -57,6 +59,26 @@ class Post extends Model implements HasMedia
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function coverMedia(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(MediaLibrary::class, 'cover_media_id');
|
||||
}
|
||||
|
||||
public function coverImageUrl(?string $conversion = 'card'): ?string
|
||||
{
|
||||
$libraryUrl = $this->coverMedia?->url;
|
||||
if (filled($libraryUrl)) {
|
||||
return (string) $libraryUrl;
|
||||
}
|
||||
|
||||
$cover = $this->getFirstMedia('cover');
|
||||
if ($cover === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $cover->getUrl($conversion) ?: $cover->getUrl();
|
||||
}
|
||||
|
||||
public function comments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
@@ -133,8 +155,10 @@ class Post extends Model implements HasMedia
|
||||
|
||||
$text = strip_tags($this->content);
|
||||
// 付费块不进入摘要,避免付费内容泄漏到列表页/SEO meta
|
||||
$text = preg_replace('/\[paid\].*?\[\/paid\]/s', '', $text);
|
||||
$text = preg_replace('/\[[^\]]*\]/', '', $text);
|
||||
$text = preg_replace('/\[paid\].*?\[\/paid\]/s', '', $text) ?? $text;
|
||||
$text = preg_replace('/!\[([^\]]*)\]\((?:media|attach):\d+\)/i', '$1', $text) ?? $text;
|
||||
$text = preg_replace('/\[([^\]]*)\]\((?:media|attach):\d+\)/i', '$1', $text) ?? $text;
|
||||
$text = preg_replace('/\[[^\]]*\]/', '', $text) ?? $text;
|
||||
|
||||
return mb_substr($text, 0, 200);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
config([
|
||||
'filament-media-library.navigation_group' => '内容',
|
||||
]);
|
||||
|
||||
// 自动加载所有插件的迁移(插件目录下 database/migrations)
|
||||
foreach (glob(base_path('plugins/*/database/migrations')) ?: [] as $path) {
|
||||
$this->loadMigrationsFrom($path);
|
||||
|
||||
@@ -28,6 +28,7 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
use Xpier\FilamentMediaLibrary\Filament\MediaLibraryPlugin;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
{
|
||||
@@ -98,6 +99,10 @@ class AdminPanelProvider extends PanelProvider
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
])
|
||||
->plugins([
|
||||
MediaLibraryPlugin::make()
|
||||
->navigationGroup((string) config('filament-media-library.navigation_group', '内容')),
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
|
||||
+12
-2
@@ -3,7 +3,10 @@
|
||||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The skeleton application for the Laravel framework.",
|
||||
"keywords": ["laravel", "framework"],
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"framework"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
@@ -23,6 +26,7 @@
|
||||
"spatie/laravel-sitemap": "^8.0",
|
||||
"spatie/laravel-tags": "^4.0",
|
||||
"workerman/workerman": "^5.0",
|
||||
"xpier/filament-media-library": "^1.5",
|
||||
"yansongda/pay": "^3.7"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -104,5 +108,11 @@
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
"prefer-stable": true,
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/ffqa/xpier-filament-media-library.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Generated
+408
-1919
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasColumn('posts', 'cover_media_id')) {
|
||||
Schema::table('posts', function (Blueprint $table): void {
|
||||
$table->unsignedBigInteger('cover_media_id')->nullable()->after('keywords');
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasColumn('categories', 'cover_media_id')) {
|
||||
Schema::table('categories', function (Blueprint $table): void {
|
||||
$table->unsignedBigInteger('cover_media_id')->nullable()->after('description');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (Schema::hasColumn('posts', 'cover_media_id')) {
|
||||
Schema::table('posts', function (Blueprint $table): void {
|
||||
$table->dropColumn('cover_media_id');
|
||||
});
|
||||
}
|
||||
|
||||
if (Schema::hasColumn('categories', 'cover_media_id')) {
|
||||
Schema::table('categories', function (Blueprint $table): void {
|
||||
$table->dropColumn('cover_media_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('media_folders')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = now();
|
||||
$folders = [
|
||||
['code' => 'general', 'name' => 'General', 'sort' => 0],
|
||||
['code' => 'articles', 'name' => 'Articles', 'sort' => 1],
|
||||
['code' => 'banners', 'name' => 'Banners', 'sort' => 2],
|
||||
];
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
$exists = DB::table('media_folders')->where('code', $folder['code'])->exists();
|
||||
if ($exists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('media_folders')->insert([
|
||||
'parent_id' => null,
|
||||
'code' => $folder['code'],
|
||||
'name' => $folder['name'],
|
||||
'sort' => $folder['sort'],
|
||||
'is_active' => true,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (! Schema::hasTable('media_folders')) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('media_folders')
|
||||
->whereIn('code', ['general', 'articles', 'banners'])
|
||||
->whereNull('parent_id')
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,582 @@
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
DROP TABLE IF EXISTS `cache`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `cache_locks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache_locks` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`owner` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_locks_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `categories` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(120) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`cover_media_id` bigint unsigned DEFAULT NULL,
|
||||
`post_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `categories_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `comments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `comments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`post_id` bigint unsigned NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`author_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`author_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`author_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`content` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`ip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`ai_review` json DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comments_user_id_foreign` (`user_id`),
|
||||
KEY `comments_post_id_status_index` (`post_id`,`status`),
|
||||
KEY `comments_status_index` (`status`),
|
||||
CONSTRAINT `comments_post_id_foreign` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `failed_jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `failed_jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `hello_world_logs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `hello_world_logs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`comment_id` bigint unsigned DEFAULT NULL,
|
||||
`note` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `hello_world_logs_comment_id_foreign` (`comment_id`),
|
||||
CONSTRAINT `hello_world_logs_comment_id_foreign` FOREIGN KEY (`comment_id`) REFERENCES `comments` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `job_batches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `job_batches` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`total_jobs` int NOT NULL,
|
||||
`pending_jobs` int NOT NULL,
|
||||
`failed_jobs` int NOT NULL,
|
||||
`failed_job_ids` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`options` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
`cancelled_at` int DEFAULT NULL,
|
||||
`created_at` int NOT NULL,
|
||||
`finished_at` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`queue` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`attempts` tinyint unsigned NOT NULL,
|
||||
`reserved_at` int unsigned DEFAULT NULL,
|
||||
`available_at` int unsigned NOT NULL,
|
||||
`created_at` int unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `jobs_queue_index` (`queue`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `links`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `links` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`note` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`visible` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `market_packages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `market_packages` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`item_key` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`item_type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`payment_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `market_packages_item_key_item_type_unique` (`item_key`,`item_type`),
|
||||
KEY `market_packages_payment_id_foreign` (`payment_id`),
|
||||
KEY `market_packages_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `market_packages_payment_id_foreign` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `market_packages_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
`uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`collection_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`file_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`disk` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`conversions_disk` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`size` bigint unsigned NOT NULL,
|
||||
`manipulations` json NOT NULL,
|
||||
`custom_properties` json NOT NULL,
|
||||
`generated_conversions` json NOT NULL,
|
||||
`responsive_images` json NOT NULL,
|
||||
`order_column` int unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_uuid_unique` (`uuid`),
|
||||
KEY `media_model_type_model_id_index` (`model_type`,`model_id`),
|
||||
KEY `media_order_column_index` (`order_column`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media_folders`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media_folders` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`parent_id` bigint unsigned DEFAULT NULL,
|
||||
`code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`sort` int NOT NULL DEFAULT '0',
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_folders_code_unique` (`code`),
|
||||
KEY `media_folders_parent_id_foreign` (`parent_id`),
|
||||
CONSTRAINT `media_folders_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `media_folders` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media_library`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media_library` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`disk` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'public',
|
||||
`path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`original_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`extension` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`size` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`type` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'image',
|
||||
`source` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'admin',
|
||||
`folder` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`alt_text` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_properties` json DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_library_path_unique` (`path`),
|
||||
KEY `media_library_user_id_foreign` (`user_id`),
|
||||
KEY `media_library_type_index` (`type`),
|
||||
KEY `media_library_folder_index` (`folder`),
|
||||
KEY `media_library_source_index` (`source`),
|
||||
CONSTRAINT `media_library_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `membership_plans`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `membership_plans` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`duration_days` int unsigned NOT NULL DEFAULT '30',
|
||||
`permissions` json DEFAULT NULL,
|
||||
`active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`sort` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `membership_plans_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`batch` int NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_permissions_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_roles` (
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`role_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_roles_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `password_reset_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `password_reset_tokens` (
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `payments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `payments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`order_no` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`subject` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`amount` bigint unsigned NOT NULL,
|
||||
`channel` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'alipay',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`gateway_trade_no` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payload` json DEFAULT NULL,
|
||||
`paid_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`payable_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payable_id` bigint unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `payments_order_no_unique` (`order_no`),
|
||||
KEY `payments_user_id_status_index` (`user_id`,`status`),
|
||||
KEY `payments_payable_type_payable_id_index` (`payable_type`,`payable_id`),
|
||||
CONSTRAINT `payments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `permissions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `permissions_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `personal_access_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `personal_access_tokens` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`tokenable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`tokenable_id` bigint unsigned NOT NULL,
|
||||
`name` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`abilities` text COLLATE utf8mb4_unicode_ci,
|
||||
`last_used_at` timestamp NULL DEFAULT NULL,
|
||||
`expires_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `personal_access_tokens_token_unique` (`token`),
|
||||
KEY `personal_access_tokens_tokenable_type_tokenable_id_index` (`tokenable_type`,`tokenable_id`),
|
||||
KEY `personal_access_tokens_expires_at_index` (`expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `plugin_records`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `plugin_records` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`vendor` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`version` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `plugin_records_vendor_name_unique` (`vendor`,`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `posts`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `posts` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`category_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`excerpt` text COLLATE utf8mb4_unicode_ci,
|
||||
`content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`content_format` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'markdown',
|
||||
`keywords` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`cover_media_id` bigint unsigned DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published',
|
||||
`is_sticky` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`close_comment` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`read_password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`views` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`comment_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`meta` json DEFAULT NULL,
|
||||
`published_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `posts_slug_unique` (`slug`),
|
||||
KEY `posts_category_id_foreign` (`category_id`),
|
||||
KEY `posts_user_id_foreign` (`user_id`),
|
||||
KEY `posts_status_published_at_index` (`status`,`published_at`),
|
||||
KEY `posts_status_index` (`status`),
|
||||
KEY `posts_published_at_index` (`published_at`),
|
||||
CONSTRAINT `posts_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `posts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `redirects`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `redirects` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`hash` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`target_url` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`clicks` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`last_clicked_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `redirects_hash_unique` (`hash`),
|
||||
KEY `redirects_target_url_index` (`target_url`(191))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `role_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `role_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`role_id`),
|
||||
KEY `role_has_permissions_role_id_foreign` (`role_id`),
|
||||
CONSTRAINT `role_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `role_has_permissions_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `roles` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `roles_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`user_agent` text COLLATE utf8mb4_unicode_ci,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`last_activity` int NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sessions_user_id_index` (`user_id`),
|
||||
KEY `sessions_last_activity_index` (`last_activity`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `settings` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subscriptions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `subscriptions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`membership_plan_id` bigint unsigned DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`starts_at` timestamp NULL DEFAULT NULL,
|
||||
`ends_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `subscriptions_membership_plan_id_foreign` (`membership_plan_id`),
|
||||
KEY `subscriptions_user_id_status_index` (`user_id`,`status`),
|
||||
CONSTRAINT `subscriptions_membership_plan_id_foreign` FOREIGN KEY (`membership_plan_id`) REFERENCES `membership_plans` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `subscriptions_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `taggables`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `taggables` (
|
||||
`tag_id` bigint unsigned NOT NULL,
|
||||
`taggable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`taggable_id` bigint unsigned NOT NULL,
|
||||
UNIQUE KEY `taggables_tag_id_taggable_id_taggable_type_unique` (`tag_id`,`taggable_id`,`taggable_type`),
|
||||
KEY `taggables_taggable_type_taggable_id_index` (`taggable_type`,`taggable_id`),
|
||||
CONSTRAINT `taggables_tag_id_foreign` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `tags`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `tags` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` json NOT NULL,
|
||||
`slug` json NOT NULL,
|
||||
`type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`order_column` int DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email_verified_at` timestamp NULL DEFAULT NULL,
|
||||
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`legacy_md5` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logincount` int unsigned NOT NULL DEFAULT '0',
|
||||
`loginip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`regip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logintime` timestamp NULL DEFAULT NULL,
|
||||
`lastpost_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`),
|
||||
KEY `users_legacy_md5_index` (`legacy_md5`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2026_08_11_092446_create_permission_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2026_08_11_092448_create_media_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2026_08_11_092449_create_tag_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2026_08_11_100000_create_membership_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2026_08_11_100000_create_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2026_08_11_100001_create_categories_and_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2026_08_11_100002_create_comments_and_trackbacks_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2026_08_11_100003_create_links_and_settings_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2026_08_11_100004_add_blog_columns_to_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2026_08_11_100005_add_content_format_to_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2026_08_11_113537_create_personal_access_tokens_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2026_08_12_000000_create_hello_world_logs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2026_08_12_100000_add_payable_to_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2026_08_12_200000_create_market_packages_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2026_08_12_300000_add_description_to_categories_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2026_08_12_400000_create_redirects_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (20,'2026_08_15_000001_create_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (21,'2026_08_15_000002_create_media_folders_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (22,'2026_08_15_000003_add_soft_deletes_to_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (23,'2026_08_15_000004_add_custom_properties_to_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (24,'2026_09_16_000001_add_cover_media_id_to_posts_and_categories',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (25,'2026_09_16_000002_seed_default_media_folders',2);
|
||||
+25
-25
@@ -2,18 +2,18 @@
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 层 | 技术 | 说明 |
|
||||
|----|------|------|
|
||||
| 框架 | Laravel 12.65 | PHP ^8.2,`declare(strict_types=1)` 全量启用 |
|
||||
| 后台 | Filament 5.7 | admin panel,zh_CN,资源/页面/组件 |
|
||||
| 前台交互 | Livewire 4 | Filament 依赖 |
|
||||
| 数据库 | MySQL 8(生产)/ SQLite(测试 :memory:) | |
|
||||
| 缓存/队列 | database / redis | 队列默认 database,可切 redis |
|
||||
| Markdown | league/commonmark(GFM)+ html-to-markdown | 内容双格式 |
|
||||
| 附件 | S3 兼容(R2/COS/OSS)+ spatie/laravel-medialibrary | 零落盘 |
|
||||
| 异步 | Workerman 5 常驻(队列消费者 + WebSocket) | 复用 Laravel Queue Worker |
|
||||
| 支付 | yansongda/pay(支付宝/微信) | 沙箱模式内置 |
|
||||
| 权限 | spatie/laravel-permission | admin/editor/member |
|
||||
| 层 | 技术 | 说明 |
|
||||
| --------- | --------------------------------------------------------------------- | -------------------------------------------- |
|
||||
| 框架 | Laravel 12.65 | PHP ^8.2,`declare(strict_types=1)` 全量启用 |
|
||||
| 后台 | Filament 5.7 | admin panel,zh_CN,资源/页面/组件 |
|
||||
| 前台交互 | Livewire 4 | Filament 依赖 |
|
||||
| 数据库 | MySQL 8(生产)/ SQLite(测试 :memory:) | |
|
||||
| 缓存/队列 | database / redis | 队列默认 database,可切 redis |
|
||||
| Markdown | league/commonmark(GFM)+ html-to-markdown | 内容双格式 |
|
||||
| 附件 | xpier media library(新上传)+ Spatie medialibrary(sablog 导入兜底) | 正文存 `media:ID` / `attach:ID` |
|
||||
| 异步 | Workerman 5 常驻(队列消费者 + WebSocket) | 复用 Laravel Queue Worker |
|
||||
| 支付 | yansongda/pay(支付宝/微信) | 沙箱模式内置 |
|
||||
| 权限 | spatie/laravel-permission | admin/editor/member |
|
||||
|
||||
## 目录分层
|
||||
|
||||
@@ -37,7 +37,7 @@ plugins/ # 插件(plugin.json + ServiceProvider + 迁移/路由/
|
||||
|
||||
1. **内容双格式**:`posts.content_format`(markdown/html)。新文章默认 Markdown;老数据导入标记 html 原样保留,`content:convert` 可批量转 Markdown。渲染管线 `PostContentRenderer::render()` 统一输出 HTML,再经 `post.rendered` 过滤器(付费内容等)。
|
||||
|
||||
2. **附件短代码**:HTML 内容 `[attach=1]`/`[img=1]`;Markdown 内容用 `{{attach:1}}`/`{{img:1}}` 令牌(`[]` 是 Markdown 保留字符)。渲染时按**全局** legacy_attachmentid 解析,找不到媒体自动清理残留。
|
||||
2. **附件短代码**:新内容 Markdown 用 `` / `[name](media:ID)`,HTML 用 `[media=ID]`,渲染时换成媒体库 URL。老 sablog 仍用 `[attach=1]`/`[img=1]` 或 `{{attach:1}}`/`{{img:1}}`。不要把 CDN 地址写进正文。详见 [docs/media.md](media.md)。
|
||||
|
||||
3. **主题系统**:激活主题的 views 目录前置到全局视图路径(View Finder),主题覆盖同名视图、缺失回退默认视图。header 打开的容器由页面视图自闭合(避免 footer 错位)。资产开发期流式返回、生产 `theme:publish`。
|
||||
|
||||
@@ -56,21 +56,21 @@ plugins/ # 插件(plugin.json + ServiceProvider + 迁移/路由/
|
||||
- **本地**:Herd 托管 `laralog.test`(PHP 8.2 + MySQL 8);无 S3 时附件落本地 public
|
||||
- **测试**:PHPUnit,SQLite `:memory:`(`phpunit.xml`),`RefreshDatabase` + `seed()`;MySQL 专属 SQL(syncCounters)在 sqlite 兼容
|
||||
- **常用命令**:
|
||||
- `php artisan sablog:import --fresh --convert-markdown`(老库迁移)
|
||||
- `php artisan workerman:serve start|stop`
|
||||
- `php artisan test`
|
||||
- `php artisan theme:publish` / `content:convert --all` / `attachments:sync-s3`
|
||||
- `php artisan sablog:import --fresh --convert-markdown`(老库迁移)
|
||||
- `php artisan workerman:serve start|stop`
|
||||
- `php artisan test`
|
||||
- `php artisan theme:publish` / `content:convert --all` / `attachments:sync-s3`
|
||||
|
||||
## 配置速查
|
||||
|
||||
| 配置 | 说明 |
|
||||
|------|------|
|
||||
| `config/blog.php` | 站点/每页数/附件磁盘 |
|
||||
| `config/themes.php` | 主题目录/默认主题 |
|
||||
| `config/plugins.php` | 插件目录/内置启用列表 |
|
||||
| `config/workerman.php` | 消费者数/队列连接/队列名/重试 |
|
||||
| `config/media.php` | S3 配置(R2/COS/OSS)与 Multipart 阈值 |
|
||||
| `config/market.php` | 插件/主题市场远程源 |
|
||||
| 配置 | 说明 |
|
||||
| ---------------------- | -------------------------------------- |
|
||||
| `config/blog.php` | 站点/每页数/附件磁盘 |
|
||||
| `config/themes.php` | 主题目录/默认主题 |
|
||||
| `config/plugins.php` | 插件目录/内置启用列表 |
|
||||
| `config/workerman.php` | 消费者数/队列连接/队列名/重试 |
|
||||
| `config/media.php` | S3 配置(R2/COS/OSS)与 Multipart 阈值 |
|
||||
| `config/market.php` | 插件/主题市场远程源 |
|
||||
|
||||
## 已知边界
|
||||
|
||||
|
||||
@@ -0,0 +1,527 @@
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
DROP TABLE IF EXISTS `cache`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `cache_locks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache_locks` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`owner` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_locks_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `categories` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(120) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`post_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `categories_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `comments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `comments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`post_id` bigint unsigned NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`author_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`author_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`author_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`content` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`ip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`ai_review` json DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comments_user_id_foreign` (`user_id`),
|
||||
KEY `comments_post_id_status_index` (`post_id`,`status`),
|
||||
KEY `comments_status_index` (`status`),
|
||||
CONSTRAINT `comments_post_id_foreign` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `failed_jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `failed_jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `hello_world_logs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `hello_world_logs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`comment_id` bigint unsigned DEFAULT NULL,
|
||||
`note` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `hello_world_logs_comment_id_foreign` (`comment_id`),
|
||||
CONSTRAINT `hello_world_logs_comment_id_foreign` FOREIGN KEY (`comment_id`) REFERENCES `comments` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `job_batches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `job_batches` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`total_jobs` int NOT NULL,
|
||||
`pending_jobs` int NOT NULL,
|
||||
`failed_jobs` int NOT NULL,
|
||||
`failed_job_ids` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`options` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
`cancelled_at` int DEFAULT NULL,
|
||||
`created_at` int NOT NULL,
|
||||
`finished_at` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`queue` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`attempts` tinyint unsigned NOT NULL,
|
||||
`reserved_at` int unsigned DEFAULT NULL,
|
||||
`available_at` int unsigned NOT NULL,
|
||||
`created_at` int unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `jobs_queue_index` (`queue`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `links`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `links` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`note` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`visible` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `market_packages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `market_packages` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`item_key` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`item_type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`payment_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `market_packages_item_key_item_type_unique` (`item_key`,`item_type`),
|
||||
KEY `market_packages_payment_id_foreign` (`payment_id`),
|
||||
KEY `market_packages_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `market_packages_payment_id_foreign` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `market_packages_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
`uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`collection_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`file_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`disk` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`conversions_disk` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`size` bigint unsigned NOT NULL,
|
||||
`manipulations` json NOT NULL,
|
||||
`custom_properties` json NOT NULL,
|
||||
`generated_conversions` json NOT NULL,
|
||||
`responsive_images` json NOT NULL,
|
||||
`order_column` int unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_uuid_unique` (`uuid`),
|
||||
KEY `media_model_type_model_id_index` (`model_type`,`model_id`),
|
||||
KEY `media_order_column_index` (`order_column`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `membership_plans`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `membership_plans` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`duration_days` int unsigned NOT NULL DEFAULT '30',
|
||||
`permissions` json DEFAULT NULL,
|
||||
`active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`sort` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `membership_plans_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`batch` int NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_permissions_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_roles` (
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`role_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_roles_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `password_reset_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `password_reset_tokens` (
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `payments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `payments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`order_no` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`subject` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`amount` bigint unsigned NOT NULL,
|
||||
`channel` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'alipay',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`gateway_trade_no` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payload` json DEFAULT NULL,
|
||||
`paid_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`payable_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payable_id` bigint unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `payments_order_no_unique` (`order_no`),
|
||||
KEY `payments_user_id_status_index` (`user_id`,`status`),
|
||||
KEY `payments_payable_type_payable_id_index` (`payable_type`,`payable_id`),
|
||||
CONSTRAINT `payments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `permissions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `permissions_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `personal_access_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `personal_access_tokens` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`tokenable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`tokenable_id` bigint unsigned NOT NULL,
|
||||
`name` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`abilities` text COLLATE utf8mb4_unicode_ci,
|
||||
`last_used_at` timestamp NULL DEFAULT NULL,
|
||||
`expires_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `personal_access_tokens_token_unique` (`token`),
|
||||
KEY `personal_access_tokens_tokenable_type_tokenable_id_index` (`tokenable_type`,`tokenable_id`),
|
||||
KEY `personal_access_tokens_expires_at_index` (`expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `plugin_records`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `plugin_records` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`vendor` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`version` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `plugin_records_vendor_name_unique` (`vendor`,`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `posts`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `posts` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`category_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`excerpt` text COLLATE utf8mb4_unicode_ci,
|
||||
`content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`content_format` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'markdown',
|
||||
`keywords` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published',
|
||||
`is_sticky` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`close_comment` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`read_password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`views` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`comment_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`meta` json DEFAULT NULL,
|
||||
`published_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `posts_slug_unique` (`slug`),
|
||||
KEY `posts_category_id_foreign` (`category_id`),
|
||||
KEY `posts_user_id_foreign` (`user_id`),
|
||||
KEY `posts_status_published_at_index` (`status`,`published_at`),
|
||||
KEY `posts_status_index` (`status`),
|
||||
KEY `posts_published_at_index` (`published_at`),
|
||||
CONSTRAINT `posts_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `posts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `redirects`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `redirects` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`hash` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`target_url` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`clicks` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`last_clicked_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `redirects_hash_unique` (`hash`),
|
||||
KEY `redirects_target_url_index` (`target_url`(191))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `role_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `role_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`role_id`),
|
||||
KEY `role_has_permissions_role_id_foreign` (`role_id`),
|
||||
CONSTRAINT `role_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `role_has_permissions_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `roles` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `roles_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`user_agent` text COLLATE utf8mb4_unicode_ci,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`last_activity` int NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sessions_user_id_index` (`user_id`),
|
||||
KEY `sessions_last_activity_index` (`last_activity`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `settings` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subscriptions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `subscriptions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`membership_plan_id` bigint unsigned DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`starts_at` timestamp NULL DEFAULT NULL,
|
||||
`ends_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `subscriptions_membership_plan_id_foreign` (`membership_plan_id`),
|
||||
KEY `subscriptions_user_id_status_index` (`user_id`,`status`),
|
||||
CONSTRAINT `subscriptions_membership_plan_id_foreign` FOREIGN KEY (`membership_plan_id`) REFERENCES `membership_plans` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `subscriptions_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `taggables`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `taggables` (
|
||||
`tag_id` bigint unsigned NOT NULL,
|
||||
`taggable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`taggable_id` bigint unsigned NOT NULL,
|
||||
UNIQUE KEY `taggables_tag_id_taggable_id_taggable_type_unique` (`tag_id`,`taggable_id`,`taggable_type`),
|
||||
KEY `taggables_taggable_type_taggable_id_index` (`taggable_type`,`taggable_id`),
|
||||
CONSTRAINT `taggables_tag_id_foreign` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `tags`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `tags` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` json NOT NULL,
|
||||
`slug` json NOT NULL,
|
||||
`type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`order_column` int DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email_verified_at` timestamp NULL DEFAULT NULL,
|
||||
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`legacy_md5` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logincount` int unsigned NOT NULL DEFAULT '0',
|
||||
`loginip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`regip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logintime` timestamp NULL DEFAULT NULL,
|
||||
`lastpost_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`),
|
||||
KEY `users_legacy_md5_index` (`legacy_md5`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2026_08_11_092446_create_permission_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2026_08_11_092448_create_media_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2026_08_11_092449_create_tag_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2026_08_11_100000_create_membership_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2026_08_11_100000_create_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2026_08_11_100001_create_categories_and_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2026_08_11_100002_create_comments_and_trackbacks_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2026_08_11_100003_create_links_and_settings_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2026_08_11_100004_add_blog_columns_to_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2026_08_11_100005_add_content_format_to_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2026_08_11_113537_create_personal_access_tokens_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2026_08_12_000000_create_hello_world_logs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2026_08_12_100000_add_payable_to_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2026_08_12_200000_create_market_packages_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2026_08_12_300000_add_description_to_categories_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2026_08_12_400000_create_redirects_table',1);
|
||||
@@ -0,0 +1,582 @@
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
DROP TABLE IF EXISTS `cache`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `cache_locks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache_locks` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`owner` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expiration` int NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_locks_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `categories` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(120) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`cover_media_id` bigint unsigned DEFAULT NULL,
|
||||
`post_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `categories_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `comments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `comments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`post_id` bigint unsigned NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`author_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`author_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`author_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`content` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`ip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`ai_review` json DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `comments_user_id_foreign` (`user_id`),
|
||||
KEY `comments_post_id_status_index` (`post_id`,`status`),
|
||||
KEY `comments_status_index` (`status`),
|
||||
CONSTRAINT `comments_post_id_foreign` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `failed_jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `failed_jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `hello_world_logs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `hello_world_logs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`comment_id` bigint unsigned DEFAULT NULL,
|
||||
`note` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `hello_world_logs_comment_id_foreign` (`comment_id`),
|
||||
CONSTRAINT `hello_world_logs_comment_id_foreign` FOREIGN KEY (`comment_id`) REFERENCES `comments` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `job_batches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `job_batches` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`total_jobs` int NOT NULL,
|
||||
`pending_jobs` int NOT NULL,
|
||||
`failed_jobs` int NOT NULL,
|
||||
`failed_job_ids` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`options` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
`cancelled_at` int DEFAULT NULL,
|
||||
`created_at` int NOT NULL,
|
||||
`finished_at` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `jobs` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`queue` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`attempts` tinyint unsigned NOT NULL,
|
||||
`reserved_at` int unsigned DEFAULT NULL,
|
||||
`available_at` int unsigned NOT NULL,
|
||||
`created_at` int unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `jobs_queue_index` (`queue`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `links`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `links` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`note` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`display_order` tinyint NOT NULL DEFAULT '0',
|
||||
`visible` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `market_packages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `market_packages` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`item_key` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`item_type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`payment_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `market_packages_item_key_item_type_unique` (`item_key`,`item_type`),
|
||||
KEY `market_packages_payment_id_foreign` (`payment_id`),
|
||||
KEY `market_packages_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `market_packages_payment_id_foreign` FOREIGN KEY (`payment_id`) REFERENCES `payments` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `market_packages_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
`uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`collection_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`file_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`disk` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`conversions_disk` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`size` bigint unsigned NOT NULL,
|
||||
`manipulations` json NOT NULL,
|
||||
`custom_properties` json NOT NULL,
|
||||
`generated_conversions` json NOT NULL,
|
||||
`responsive_images` json NOT NULL,
|
||||
`order_column` int unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_uuid_unique` (`uuid`),
|
||||
KEY `media_model_type_model_id_index` (`model_type`,`model_id`),
|
||||
KEY `media_order_column_index` (`order_column`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media_folders`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media_folders` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`parent_id` bigint unsigned DEFAULT NULL,
|
||||
`code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`sort` int NOT NULL DEFAULT '0',
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_folders_code_unique` (`code`),
|
||||
KEY `media_folders_parent_id_foreign` (`parent_id`),
|
||||
CONSTRAINT `media_folders_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `media_folders` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `media_library`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `media_library` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`disk` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'public',
|
||||
`path` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`original_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`extension` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`size` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`type` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'image',
|
||||
`source` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'admin',
|
||||
`folder` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`alt_text` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_properties` json DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `media_library_path_unique` (`path`),
|
||||
KEY `media_library_user_id_foreign` (`user_id`),
|
||||
KEY `media_library_type_index` (`type`),
|
||||
KEY `media_library_folder_index` (`folder`),
|
||||
KEY `media_library_source_index` (`source`),
|
||||
CONSTRAINT `media_library_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `membership_plans`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `membership_plans` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` text COLLATE utf8mb4_unicode_ci,
|
||||
`price` bigint unsigned NOT NULL,
|
||||
`duration_days` int unsigned NOT NULL DEFAULT '30',
|
||||
`permissions` json DEFAULT NULL,
|
||||
`active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`sort` int unsigned NOT NULL DEFAULT '0',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `membership_plans_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`batch` int NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_permissions_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `model_has_roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `model_has_roles` (
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
`model_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`model_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`role_id`,`model_id`,`model_type`),
|
||||
KEY `model_has_roles_model_id_model_type_index` (`model_id`,`model_type`),
|
||||
CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `password_reset_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `password_reset_tokens` (
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `payments`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `payments` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`order_no` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`subject` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`amount` bigint unsigned NOT NULL,
|
||||
`channel` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'alipay',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending',
|
||||
`gateway_trade_no` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payload` json DEFAULT NULL,
|
||||
`paid_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`payable_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`payable_id` bigint unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `payments_order_no_unique` (`order_no`),
|
||||
KEY `payments_user_id_status_index` (`user_id`,`status`),
|
||||
KEY `payments_payable_type_payable_id_index` (`payable_type`,`payable_id`),
|
||||
CONSTRAINT `payments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `permissions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `permissions_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `personal_access_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `personal_access_tokens` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`tokenable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`tokenable_id` bigint unsigned NOT NULL,
|
||||
`name` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`abilities` text COLLATE utf8mb4_unicode_ci,
|
||||
`last_used_at` timestamp NULL DEFAULT NULL,
|
||||
`expires_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `personal_access_tokens_token_unique` (`token`),
|
||||
KEY `personal_access_tokens_tokenable_type_tokenable_id_index` (`tokenable_type`,`tokenable_id`),
|
||||
KEY `personal_access_tokens_expires_at_index` (`expires_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `plugin_records`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `plugin_records` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`vendor` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`name` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`version` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `plugin_records_vendor_name_unique` (`vendor`,`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `posts`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `posts` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`category_id` bigint unsigned DEFAULT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`slug` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`excerpt` text COLLATE utf8mb4_unicode_ci,
|
||||
`content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`content_format` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'markdown',
|
||||
`keywords` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`cover_media_id` bigint unsigned DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published',
|
||||
`is_sticky` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`close_comment` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`read_password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`views` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`comment_count` int unsigned NOT NULL DEFAULT '0',
|
||||
`meta` json DEFAULT NULL,
|
||||
`published_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `posts_slug_unique` (`slug`),
|
||||
KEY `posts_category_id_foreign` (`category_id`),
|
||||
KEY `posts_user_id_foreign` (`user_id`),
|
||||
KEY `posts_status_published_at_index` (`status`,`published_at`),
|
||||
KEY `posts_status_index` (`status`),
|
||||
KEY `posts_published_at_index` (`published_at`),
|
||||
CONSTRAINT `posts_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `posts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `redirects`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `redirects` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`hash` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`target_url` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`clicks` bigint unsigned NOT NULL DEFAULT '0',
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`last_clicked_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `redirects_hash_unique` (`hash`),
|
||||
KEY `redirects_target_url_index` (`target_url`(191))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `role_has_permissions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `role_has_permissions` (
|
||||
`permission_id` bigint unsigned NOT NULL,
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`permission_id`,`role_id`),
|
||||
KEY `role_has_permissions_role_id_foreign` (`role_id`),
|
||||
CONSTRAINT `role_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `role_has_permissions_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `roles`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `roles` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`guard_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `roles_name_guard_name_unique` (`name`,`guard_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`user_id` bigint unsigned DEFAULT NULL,
|
||||
`ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`user_agent` text COLLATE utf8mb4_unicode_ci,
|
||||
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`last_activity` int NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sessions_user_id_index` (`user_id`),
|
||||
KEY `sessions_last_activity_index` (`last_activity`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `settings` (
|
||||
`key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`value` text COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `subscriptions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `subscriptions` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint unsigned NOT NULL,
|
||||
`membership_plan_id` bigint unsigned DEFAULT NULL,
|
||||
`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
|
||||
`starts_at` timestamp NULL DEFAULT NULL,
|
||||
`ends_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `subscriptions_membership_plan_id_foreign` (`membership_plan_id`),
|
||||
KEY `subscriptions_user_id_status_index` (`user_id`,`status`),
|
||||
CONSTRAINT `subscriptions_membership_plan_id_foreign` FOREIGN KEY (`membership_plan_id`) REFERENCES `membership_plans` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `subscriptions_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `taggables`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `taggables` (
|
||||
`tag_id` bigint unsigned NOT NULL,
|
||||
`taggable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`taggable_id` bigint unsigned NOT NULL,
|
||||
UNIQUE KEY `taggables_tag_id_taggable_id_taggable_type_unique` (`tag_id`,`taggable_id`,`taggable_type`),
|
||||
KEY `taggables_taggable_type_taggable_id_index` (`taggable_type`,`taggable_id`),
|
||||
CONSTRAINT `taggables_tag_id_foreign` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `tags`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `tags` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` json NOT NULL,
|
||||
`slug` json NOT NULL,
|
||||
`type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`order_column` int DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`email_verified_at` timestamp NULL DEFAULT NULL,
|
||||
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`legacy_md5` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logincount` int unsigned NOT NULL DEFAULT '0',
|
||||
`loginip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`regip` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`logintime` timestamp NULL DEFAULT NULL,
|
||||
`lastpost_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`),
|
||||
KEY `users_legacy_md5_index` (`legacy_md5`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2026_08_11_092446_create_permission_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2026_08_11_092448_create_media_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2026_08_11_092449_create_tag_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2026_08_11_100000_create_membership_tables',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2026_08_11_100000_create_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2026_08_11_100001_create_categories_and_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2026_08_11_100002_create_comments_and_trackbacks_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2026_08_11_100003_create_links_and_settings_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2026_08_11_100004_add_blog_columns_to_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2026_08_11_100005_add_content_format_to_posts_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2026_08_11_113537_create_personal_access_tokens_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2026_08_12_000000_create_hello_world_logs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2026_08_12_100000_add_payable_to_payments_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2026_08_12_200000_create_market_packages_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2026_08_12_300000_add_description_to_categories_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2026_08_12_400000_create_redirects_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (20,'2026_08_15_000001_create_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (21,'2026_08_15_000002_create_media_folders_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (22,'2026_08_15_000003_add_soft_deletes_to_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (23,'2026_08_15_000004_add_custom_properties_to_media_library_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (24,'2026_09_16_000001_add_cover_media_id_to_posts_and_categories',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (25,'2026_09_16_000002_seed_default_media_folders',2);
|
||||
+32
-31
@@ -24,39 +24,40 @@ php artisan sablog:import \
|
||||
|
||||
### 参数说明
|
||||
|
||||
| 参数 | 默认 | 说明 |
|
||||
|------|------|------|
|
||||
| `--driver` | mysql | 老库驱动(测试可用 `sqlite`) |
|
||||
| `--host` / `--port` | 127.0.0.1 / 3306 | 老库地址 |
|
||||
| `--database` | (必填) | 老库名 |
|
||||
| `--username` / `--password` | root / 空 | 老库账号 |
|
||||
| `--prefix` | `sablog_` | 老表前缀(老站可能自定义过) |
|
||||
| `--attachments-dir` | — | 老附件目录,配合 `--sync-attachments` 用 |
|
||||
| `--sync-attachments` | 关 | 同步附件文件到新存储(本地中转或直接上 S3) |
|
||||
| `--convert-markdown` | 关 | 导入时把 HTML 正文转为 Markdown |
|
||||
| `--fresh` | 关 | 清空目标表后重新导入 |
|
||||
| 参数 | 默认 | 说明 |
|
||||
| --------------------------- | ---------------- | ------------------------------------------- |
|
||||
| `--driver` | mysql | 老库驱动(测试可用 `sqlite`) |
|
||||
| `--host` / `--port` | 127.0.0.1 / 3306 | 老库地址 |
|
||||
| `--database` | (必填) | 老库名 |
|
||||
| `--username` / `--password` | root / 空 | 老库账号 |
|
||||
| `--prefix` | `sablog_` | 老表前缀(老站可能自定义过) |
|
||||
| `--attachments-dir` | — | 老附件目录,配合 `--sync-attachments` 用 |
|
||||
| `--sync-attachments` | 关 | 同步附件文件到新存储(本地中转或直接上 S3) |
|
||||
| `--convert-markdown` | 关 | 导入时把 HTML 正文转为 Markdown |
|
||||
| `--fresh` | 关 | 清空目标表后重新导入 |
|
||||
|
||||
## 数据映射
|
||||
|
||||
| 老表 | 新表 | 说明 |
|
||||
|------|------|------|
|
||||
| `users` | `users` | **ID 保留**;老 MD5 密码进 `legacy_md5`,登录时自动升级为 bcrypt |
|
||||
| `articles` | `posts` | **articleid 保留为 id**;`[attach=xx]` 按内容格式处理(见下) |
|
||||
| `categories` | `categories` | cid 保留;导入后自动重算文章数 |
|
||||
| `comments` | `comments` | commentid 保留;visible 语义映射为状态 |
|
||||
| `links` | `links` | linkid 保留 |
|
||||
| `attachments` | medialibrary `media` | 文件 + `legacy_attachmentid` 映射(老 `[attach=xx]` 按此解析) |
|
||||
| `settings` | `settings` | 键值映射为站点设置(可在后台「博客设置」继续改) |
|
||||
| `tags` | spatie tags | 老 aids 文本解析为独立标签 + 关联 |
|
||||
| 老表 | 新表 | 说明 |
|
||||
| ------------- | -------------------- | ---------------------------------------------------------------- |
|
||||
| `users` | `users` | **ID 保留**;老 MD5 密码进 `legacy_md5`,登录时自动升级为 bcrypt |
|
||||
| `articles` | `posts` | **articleid 保留为 id**;`[attach=xx]` 按内容格式处理(见下) |
|
||||
| `categories` | `categories` | cid 保留;导入后自动重算文章数 |
|
||||
| `comments` | `comments` | commentid 保留;visible 语义映射为状态 |
|
||||
| `links` | `links` | linkid 保留 |
|
||||
| `attachments` | medialibrary `media` | 文件 + `legacy_attachmentid` 映射(老 `[attach=xx]` 按此解析) |
|
||||
| `settings` | `settings` | 键值映射为站点设置(可在后台「博客设置」继续改) |
|
||||
| `tags` | spatie tags | 老 aids 文本解析为独立标签 + 关联 |
|
||||
|
||||
**不迁移**:trackback/引用通告(垃圾来源,接口已关闭)、搜索缓存表、验证码(由 AI 审核 + 蜜罐 + 频控取代)。
|
||||
|
||||
## 附件短代码的处理
|
||||
|
||||
| 老内容 | 导入后 |
|
||||
|--------|--------|
|
||||
| HTML 正文 `[attach=12]` | 原样保留,**渲染时按 legacy id 解析**为附件链接/图片 |
|
||||
| Markdown 正文(--convert-markdown) | 自动转成 `{{attach:12}}` 令牌(`[]` 是 Markdown 保留字符) |
|
||||
| 老内容 | 导入后 |
|
||||
| ----------------------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| HTML 正文 `[attach=12]` | 原样保留,**渲染时按 legacy id 解析**为附件链接/图片 |
|
||||
| Markdown 正文(--convert-markdown) | 自动转成 `{{attach:12}}` 令牌(`[]` 是 Markdown 保留字符) |
|
||||
| 新写作(媒体库) | 写入 `` / `[name](media:ID)`,渲染时换成媒体库 URL(见 [media.md](media.md)) |
|
||||
|
||||
两种格式都能正常显示老附件,无需手工替换。
|
||||
|
||||
@@ -105,9 +106,9 @@ php artisan content:convert --all --dry-run # 先预览
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 报「找不到老表」 | 检查 `--prefix`(老站表前缀可能不是 `sablog_`)与老库名 |
|
||||
| 附件显示不出来 | 确认 `--attachments-dir` 路径正确;看 `attachments:sync-s3` 输出报告 |
|
||||
| 老密码登录失败 | 老库密码若是自定义加密(非 MD5),需要按 `User::verifyPassword` 扩展 |
|
||||
| 中文乱码 | 老库导出时用 utf8mb4;`--driver=sqlite` 只用于测试 |
|
||||
| 现象 | 处理 |
|
||||
| ---------------- | -------------------------------------------------------------------- |
|
||||
| 报「找不到老表」 | 检查 `--prefix`(老站表前缀可能不是 `sablog_`)与老库名 |
|
||||
| 附件显示不出来 | 确认 `--attachments-dir` 路径正确;看 `attachments:sync-s3` 输出报告 |
|
||||
| 老密码登录失败 | 老库密码若是自定义加密(非 MD5),需要按 `User::verifyPassword` 扩展 |
|
||||
| 中文乱码 | 老库导出时用 utf8mb4;`--driver=sqlite` 只用于测试 |
|
||||
|
||||
+15
-14
@@ -4,12 +4,12 @@
|
||||
|
||||
## 环境要求
|
||||
|
||||
| 组件 | 要求 |
|
||||
|------|------|
|
||||
| PHP | **8.2+**(需 pcntl 扩展用于 Workerman;GD/Imagick 用于缩略图) |
|
||||
| MySQL | **8.x** |
|
||||
| Composer | 2.x |
|
||||
| 可选 | Node.js(前台资源构建)、S3 兼容存储(R2/COS/OSS/MinIO)、OpenAI 兼容 LLM |
|
||||
| 组件 | 要求 |
|
||||
| -------- | ------------------------------------------------------------------------- |
|
||||
| PHP | **8.2+**(需 pcntl 扩展用于 Workerman;GD/Imagick 用于缩略图) |
|
||||
| MySQL | **8.x** |
|
||||
| Composer | 2.x |
|
||||
| 可选 | Node.js(前台资源构建)、S3 兼容存储(R2/COS/OSS/MinIO)、OpenAI 兼容 LLM |
|
||||
|
||||
## 1. 获取代码与依赖
|
||||
|
||||
@@ -33,6 +33,7 @@ DB_PASSWORD=
|
||||
|
||||
# 以下为可选能力(不配也能跑,见注释):
|
||||
# S3_* 附件存储(不配置回退本地 public)
|
||||
# MEDIA_DISK=public 新媒体库磁盘(正文写 media:ID,见 docs/media.md)
|
||||
# LLM_* AI 评论审核/润色
|
||||
# MARKET_* 插件/主题远程市场
|
||||
```
|
||||
@@ -84,11 +85,11 @@ php artisan queue:work --queue=default,ai
|
||||
|
||||
## 5. 常见问题
|
||||
|
||||
| 现象 | 处理 |
|
||||
|------|------|
|
||||
| 页面 500 / 空白 | `storage/`、`bootstrap/cache/` 目录需可写;`php artisan config:clear` |
|
||||
| 中文乱码 | 数据库/连接字符集 utf8mb4 |
|
||||
| 后台样式错乱 | `php artisan filament:assets`(重新发布后台资源) |
|
||||
| 文章编辑框太小 | 已内置加大样式;仍不够可调整 `app/Providers/AppServiceProvider.php` 中 `.fi-fo-markdown-editor` 的 min-height |
|
||||
| 附件上传失败 | 未配 S3 时走本地 public 磁盘;配 S3 后确认 `S3_*` 键与桶权限 |
|
||||
| 插件停用后功能消失 | 属预期:付费列/外链中转等由插件注入,后台「插件管理」重新启用即可 |
|
||||
| 现象 | 处理 |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------- |
|
||||
| 页面 500 / 空白 | `storage/`、`bootstrap/cache/` 目录需可写;`php artisan config:clear` |
|
||||
| 中文乱码 | 数据库/连接字符集 utf8mb4 |
|
||||
| 后台样式错乱 | `php artisan filament:assets`(重新发布后台资源) |
|
||||
| 文章编辑框太小 | 已内置加大样式;仍不够可调整 `app/Providers/AppServiceProvider.php` 中 `.fi-fo-markdown-editor` 的 min-height |
|
||||
| 附件上传失败 | 未配 S3 时走本地 public 磁盘;配 S3 后确认 `S3_*` 键与桶权限 |
|
||||
| 插件停用后功能消失 | 属预期:付费列/外链中转等由插件注入,后台「插件管理」重新启用即可 |
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# Media library (xpier)
|
||||
|
||||
New uploads, covers, and in-body images/files use `xpier/filament-media-library`. Sablog Spatie media / `attachments` rows stay for import and legacy shortcodes.
|
||||
|
||||
## Markdown body (do not paste CDN URLs)
|
||||
|
||||
The editor writes a **stable reference**. The public URL is resolved only when the page is rendered.
|
||||
|
||||
| Format | Image | File |
|
||||
| -------- | ------------------ | ----------------------- |
|
||||
| Markdown | `` | `[notes.pdf](media:12)` |
|
||||
| HTML | `[media=12]` | `[media=12]` |
|
||||
|
||||
Admin flow: pick a file in **Insert from media library**, then click **Insert into body**. That appends the snippet above. Do not copy object-storage / CDN addresses into the article.
|
||||
|
||||
Legacy sablog tokens are unchanged: `[attach=ID]`, `{{attach:ID}}`, ``.
|
||||
|
||||
## Admin
|
||||
|
||||
- Library: `/admin/media-library`
|
||||
- Folders: `/admin/media-folders` (defaults: `general`, `articles`, `banners`)
|
||||
- Cover: `MediaPicker` bound to `coverMedia` / `cover_media_id`
|
||||
|
||||
## Config
|
||||
|
||||
```env
|
||||
MEDIA_DISK=public
|
||||
MEDIA_DIRECTORY=media
|
||||
MEDIA_VISIBILITY=public
|
||||
```
|
||||
|
||||
Run `php artisan storage:link` when using the `public` disk locally.
|
||||
Generated
+2561
File diff suppressed because it is too large
Load Diff
@@ -32,5 +32,6 @@
|
||||
<env name="PULSE_ENABLED" value="false"/>
|
||||
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||
<env name="NIGHTWATCH_ENABLED" value="false"/>
|
||||
<env name="MEDIA_DISK" value="public"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
|
||||
@@ -84,8 +84,8 @@ class SeoMiddleware
|
||||
'mainEntityOfPage' => route('posts.show', $post->slug ?: $post->id),
|
||||
];
|
||||
|
||||
if ($cover = $post->getFirstMedia('cover')) {
|
||||
$data['image'] = [$cover->getUrl('card') ?: $cover->getUrl()];
|
||||
if ($cover = $post->coverImageUrl()) {
|
||||
$data['image'] = [$cover];
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
+7
-3
@@ -24,10 +24,14 @@ return new class extends Migration
|
||||
$table->string('status', 20)->default('active'); // active / disabled
|
||||
$table->timestamp('last_clicked_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// MySQL 5.7 不支持对 TEXT 建全值索引,用前缀索引
|
||||
$table->index([DB::raw('target_url(191)')], 'redirects_target_url_index');
|
||||
});
|
||||
|
||||
// MySQL 5.7 cannot index TEXT fully; SQLite does not support prefix indexes.
|
||||
if (Schema::getConnection()->getDriverName() === 'mysql') {
|
||||
Schema::table('redirects', function (Blueprint $table): void {
|
||||
$table->index([DB::raw('target_url(191)')], 'redirects_target_url_index');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
<main class="content">
|
||||
<h1 class="list-title">{{ $archiveTitle ?? ($category->name ?? '文章列表') }}</h1>
|
||||
|
||||
@if(isset($category) && ($category->description || $category->getFirstMedia('cover')))
|
||||
@if(isset($category) && ($category->description || $category->coverImageUrl()))
|
||||
<div class="category-intro">
|
||||
@if($cover = $category->getFirstMedia('cover'))
|
||||
<img src="{{ $cover->getUrl() }}" alt="{{ $category->name }}" class="category-cover">
|
||||
@if($url = $category->coverImageUrl())
|
||||
<img src="{{ $url }}" alt="{{ $category->name }}" class="category-cover">
|
||||
@endif
|
||||
<div>
|
||||
@if($category->description)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
@endphp
|
||||
|
||||
<div class="paywall" role="note" aria-label="付费内容">
|
||||
@if($cover = $post->getFirstMedia('cover'))
|
||||
@if($url = $post->coverImageUrl())
|
||||
<div class="paywall-cover">
|
||||
<img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}">
|
||||
<img src="{{ $url }}" alt="{{ $post->title }}">
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<article class="post-card {{ $post->is_sticky ? 'sticky' : '' }}">
|
||||
@if($cover = $post->getFirstMedia('cover'))
|
||||
@if($url = $post->coverImageUrl())
|
||||
<a href="{{ route('posts.show', $post->slug ?: $post->id) }}" class="post-cover">
|
||||
<img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}" loading="lazy">
|
||||
<img src="{{ $url }}" alt="{{ $post->title }}" loading="lazy">
|
||||
</a>
|
||||
@endif
|
||||
<h2 class="post-title">
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
</details>
|
||||
</nav>
|
||||
@endif
|
||||
@if($cover = $post->getFirstMedia('cover'))
|
||||
@if($url = $post->coverImageUrl())
|
||||
<div class="post-cover">
|
||||
<img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}">
|
||||
<img src="{{ $url }}" alt="{{ $post->title }}">
|
||||
</div>
|
||||
@endif
|
||||
<h1 class="post-title">{{ $post->title }}</h1>
|
||||
|
||||
@@ -50,6 +50,15 @@ class AdminPagesTest extends TestCase
|
||||
$this->actingAs($this->admin)->get('/admin/media')->assertOk();
|
||||
}
|
||||
|
||||
public function test_media_library_resource_loads(): void
|
||||
{
|
||||
$this->actingAs($this->admin)->get('/admin/media-library')->assertOk();
|
||||
$this->actingAs($this->admin)->get('/admin/media-folders')->assertOk();
|
||||
$this->actingAs($this->admin)->get('/admin/posts/create')
|
||||
->assertOk()
|
||||
->assertSee('media:ID', false);
|
||||
}
|
||||
|
||||
public function test_plugin_and_payment_pages_load(): void
|
||||
{
|
||||
$this->actingAs($this->admin)->get('/admin/plugins')->assertOk();
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Blog\Services\PostContentRenderer;
|
||||
use App\Models\Post;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
|
||||
class MarkdownMediaLibraryTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_markdown_body_renders_media_protocol_to_image_without_storing_url(): void
|
||||
{
|
||||
$media = $this->createLibraryImage(12, 'Hero shot');
|
||||
$post = Post::query()->create([
|
||||
'user_id' => User::factory()->create()->id,
|
||||
'title' => 'Media embed post',
|
||||
'slug' => 'media-embed-post',
|
||||
'content' => "Intro\n\n\n",
|
||||
'content_format' => 'markdown',
|
||||
'status' => 'published',
|
||||
'published_at' => now()->subMinute(),
|
||||
]);
|
||||
|
||||
$html = app(PostContentRenderer::class)->render($post);
|
||||
|
||||
$this->assertStringContainsString((string) $media->url, $html);
|
||||
$this->assertStringContainsString('<img', $html);
|
||||
$this->assertStringNotContainsString('media:'.$media->id, $html);
|
||||
$this->assertStringContainsString("", (string) $post->fresh()->content);
|
||||
}
|
||||
|
||||
public function test_html_body_hydrates_media_shortcode(): void
|
||||
{
|
||||
$media = $this->createLibraryImage(21, 'Inline');
|
||||
$post = Post::query()->create([
|
||||
'title' => 'HTML media post',
|
||||
'content' => '<p>see [media='.$media->id.']</p>',
|
||||
'content_format' => 'html',
|
||||
'status' => 'published',
|
||||
'published_at' => now()->subMinute(),
|
||||
]);
|
||||
|
||||
$html = app(PostContentRenderer::class)->render($post);
|
||||
|
||||
$this->assertStringContainsString((string) $media->url, $html);
|
||||
$this->assertStringNotContainsString('[media='.$media->id.']', $html);
|
||||
}
|
||||
|
||||
public function test_published_post_page_shows_library_image(): void
|
||||
{
|
||||
$media = $this->createLibraryImage(33, 'Cover art');
|
||||
$post = Post::query()->create([
|
||||
'title' => 'Visible media post',
|
||||
'slug' => 'visible-media-post',
|
||||
'content' => "",
|
||||
'content_format' => 'markdown',
|
||||
'status' => 'published',
|
||||
'published_at' => now()->subMinute(),
|
||||
'cover_media_id' => $media->id,
|
||||
]);
|
||||
|
||||
$this->get('/posts/'.$post->slug.'.shtml')
|
||||
->assertOk()
|
||||
->assertSee((string) $media->url, false)
|
||||
->assertDontSee('media:'.$media->id, false);
|
||||
|
||||
$this->assertSame((string) $media->url, $post->fresh()->coverImageUrl());
|
||||
}
|
||||
|
||||
public function test_missing_media_reference_does_not_crash_render(): void
|
||||
{
|
||||
$post = Post::query()->create([
|
||||
'title' => 'Broken media post',
|
||||
'content' => '',
|
||||
'content_format' => 'markdown',
|
||||
'status' => 'published',
|
||||
'published_at' => now()->subMinute(),
|
||||
]);
|
||||
|
||||
$html = app(PostContentRenderer::class)->render($post);
|
||||
|
||||
$this->assertIsString($html);
|
||||
$this->assertStringContainsString('media:99999', $html);
|
||||
}
|
||||
|
||||
private function createLibraryImage(int $id, string $alt): MediaLibrary
|
||||
{
|
||||
$media = new MediaLibrary;
|
||||
$media->forceFill([
|
||||
'id' => $id,
|
||||
'disk' => 'public',
|
||||
'path' => 'media/library/articles/image/test-'.$id.'.jpg',
|
||||
'original_name' => 'test-'.$id.'.jpg',
|
||||
'extension' => 'jpg',
|
||||
'mime_type' => 'image/jpeg',
|
||||
'size' => 128,
|
||||
'type' => MediaLibrary::TYPE_IMAGE,
|
||||
'source' => MediaLibrary::SOURCE_ADMIN,
|
||||
'folder' => 'articles',
|
||||
'alt_text' => $alt,
|
||||
]);
|
||||
$media->save();
|
||||
|
||||
return $media->fresh();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Blog\Support\MarkdownMediaEmbed;
|
||||
use Tests\TestCase;
|
||||
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
|
||||
|
||||
class MarkdownMediaEmbedTest extends TestCase
|
||||
{
|
||||
public function test_markdown_image_snippet_uses_media_protocol_not_url(): void
|
||||
{
|
||||
$media = new MediaLibrary([
|
||||
'alt_text' => 'Hero shot',
|
||||
'type' => MediaLibrary::TYPE_IMAGE,
|
||||
'mime_type' => 'image/jpeg',
|
||||
'original_name' => 'hero.jpg',
|
||||
'path' => 'media/library/articles/hero.jpg',
|
||||
]);
|
||||
$media->id = 12;
|
||||
|
||||
$snippet = app(MarkdownMediaEmbed::class)->snippet($media, 'markdown');
|
||||
|
||||
$this->assertSame('', $snippet);
|
||||
$this->assertStringNotContainsString('http', $snippet);
|
||||
$this->assertStringNotContainsString('/storage/', $snippet);
|
||||
}
|
||||
|
||||
public function test_markdown_file_snippet_is_a_link_reference(): void
|
||||
{
|
||||
$media = new MediaLibrary([
|
||||
'alt_text' => '',
|
||||
'type' => MediaLibrary::TYPE_FILE,
|
||||
'mime_type' => 'application/pdf',
|
||||
'original_name' => 'notes.pdf',
|
||||
'path' => 'media/library/articles/notes.pdf',
|
||||
]);
|
||||
$media->id = 8;
|
||||
|
||||
$this->assertSame('[notes.pdf](media:8)', app(MarkdownMediaEmbed::class)->snippet($media, 'markdown'));
|
||||
}
|
||||
|
||||
public function test_html_snippet_uses_shortcode(): void
|
||||
{
|
||||
$media = new MediaLibrary([
|
||||
'type' => MediaLibrary::TYPE_IMAGE,
|
||||
'mime_type' => 'image/png',
|
||||
'original_name' => 'pic.png',
|
||||
'path' => 'pic.png',
|
||||
]);
|
||||
$media->id = 3;
|
||||
|
||||
$this->assertSame('[media=3]', app(MarkdownMediaEmbed::class)->snippet($media, 'html'));
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
<main id="content">
|
||||
<h1 class="list-title">{{ $archiveTitle ?? ($category->name ?? '文章列表') }}</h1>
|
||||
|
||||
@if(isset($category) && ($category->description || $category->getFirstMedia('cover')))
|
||||
@if(isset($category) && ($category->description || $category->coverImageUrl()))
|
||||
<div class="category-intro">
|
||||
@if($cover = $category->getFirstMedia('cover'))
|
||||
<img src="{{ $cover->getUrl() }}" alt="{{ $category->name }}" class="category-cover">
|
||||
@if($url = $category->coverImageUrl())
|
||||
<img src="{{ $url }}" alt="{{ $category->name }}" class="category-cover">
|
||||
@endif
|
||||
<div>
|
||||
@if($category->description)
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
</details>
|
||||
</nav>
|
||||
@endif
|
||||
@if($cover = $post->getFirstMedia('cover'))
|
||||
<div class="post-cover"><img src="{{ $cover->getUrl('card') ?: $cover->getUrl() }}" alt="{{ $post->title }}"></div>
|
||||
@if($url = $post->coverImageUrl())
|
||||
<div class="post-cover"><img src="{{ $url }}" alt="{{ $post->title }}"></div>
|
||||
@endif
|
||||
<h1 class="post-title">{{ $post->title }}</h1>
|
||||
<div class="post-meta">
|
||||
|
||||
Reference in New Issue
Block a user