diff --git a/app/Filament/Resources/GuideResource/Pages/ManageGuidePages.php b/app/Filament/Resources/GuideResource/Pages/ManageGuidePages.php index fc5ca18..37a7520 100644 --- a/app/Filament/Resources/GuideResource/Pages/ManageGuidePages.php +++ b/app/Filament/Resources/GuideResource/Pages/ManageGuidePages.php @@ -110,7 +110,7 @@ class ManageGuidePages extends Page $this->nodes = $pages->map(fn(GuidePage $p) => [ 'id' => $p->id, 'title' => $p->title, - 'html_url' => $p->html_url, + 'uri' => $p->uri, 'is_entry' => !isset($hasIncoming[$p->id]), 'options' => $p->options ?? [], 'x' => $positions[$p->id]['x'] ?? 50, @@ -207,7 +207,7 @@ class ManageGuidePages extends Page $page = $this->getRecord()->pages()->findOrFail($arguments['id']); $form->fill([ 'title' => $page->title, - 'html_url' => $page->html_url, + 'content' => $page->content, 'options' => $page->options ?? [], ]); }) @@ -261,11 +261,13 @@ class ManageGuidePages extends Page ->required() ->maxLength(255), - Forms\Components\TextInput::make('html_url') - ->label('HTML页面URL') + Forms\Components\RichEditor::make('content') + ->label('页面内容') ->required() - ->url() - ->maxLength(500), + ->fileAttachmentsDisk('public') + ->fileAttachmentsDirectory('guide-pages') + ->fileAttachmentsVisibility('public') + ->columnSpanFull(), Forms\Components\TagsInput::make('options') ->label('分支选项') diff --git a/app/Http/Controllers/Api/TerminalApiController.php b/app/Http/Controllers/Api/TerminalApiController.php index 2d2e933..63755a8 100644 --- a/app/Http/Controllers/Api/TerminalApiController.php +++ b/app/Http/Controllers/Api/TerminalApiController.php @@ -139,7 +139,7 @@ class TerminalApiController extends Controller $pagesMap[$page->id] = [ 'id' => $page->id, 'title' => $page->title, - 'html_url' => $page->html_url, + 'uri' => $page->uri, 'next' => $next, ]; } diff --git a/app/Models/GuidePage.php b/app/Models/GuidePage.php index 582f9cc..a398ffc 100644 --- a/app/Models/GuidePage.php +++ b/app/Models/GuidePage.php @@ -9,7 +9,7 @@ class GuidePage extends Model protected $fillable = [ 'guide_id', 'title', - 'html_url', + 'content', 'options', ]; @@ -25,6 +25,11 @@ class GuidePage extends Model }); } + public function getUriAttribute(): string + { + return route('guides.pages.show', $this->id); + } + public function guide() { return $this->belongsTo(Guide::class); diff --git a/database/migrations/2026_04_15_000001_replace_html_url_with_content_on_guide_pages.php b/database/migrations/2026_04_15_000001_replace_html_url_with_content_on_guide_pages.php new file mode 100644 index 0000000..e371477 --- /dev/null +++ b/database/migrations/2026_04_15_000001_replace_html_url_with_content_on_guide_pages.php @@ -0,0 +1,24 @@ +dropColumn('html_url'); + $table->longText('content')->nullable()->after('title')->comment('富文本正文HTML'); + }); + } + + public function down(): void + { + Schema::table('guide_pages', function (Blueprint $table) { + $table->dropColumn('content'); + $table->string('html_url', 500)->after('title')->comment('HTML页面链接'); + }); + } +}; diff --git a/database/seeders/GuideSeeder.php b/database/seeders/GuideSeeder.php index 00c52e5..70ea2a6 100644 --- a/database/seeders/GuideSeeder.php +++ b/database/seeders/GuideSeeder.php @@ -11,8 +11,6 @@ use Illuminate\Database\Seeder; class GuideSeeder extends Seeder { - private const BASE_URL = 'https://ssrf.9z.work/guides'; - /** * Run the database seeds. */ @@ -46,6 +44,11 @@ class GuideSeeder extends Seeder $this->command->info(' - 关联线站数量: ' . $stations->count()); } + private function placeholder(string $title): string + { + return '
本步骤说明待补充。管理员可在 Filament 后台使用富文本编辑器完善「' . e($title) . '」的操作指引。
'; + } + private function createHowToUseBeamGuide(User $admin): Guide { $this->command->info('创建指引: 如何用光...'); @@ -60,49 +63,47 @@ class GuideSeeder extends Seeder 'published_at' => now(), ]); - $baseUrl = self::BASE_URL . '/how-to-use-beam'; - $step1 = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '打开光子光闸 PS1', - 'html_url' => "{$baseUrl}/step-1.html", + 'content' => $this->placeholder('打开光子光闸 PS1'), ]); $step2 = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '搜索光学棚屋', - 'html_url' => "{$baseUrl}/step-2.html", + 'content' => $this->placeholder('搜索光学棚屋'), 'options' => ['前门12', '后门'], ]); $step3a = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '前门12路径 - 检查设备状态', - 'html_url' => "{$baseUrl}/step-3a.html", + 'content' => $this->placeholder('前门12路径 - 检查设备状态'), ]); $step3b = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '后门路径 - 安全确认', - 'html_url' => "{$baseUrl}/step-3b.html", + 'content' => $this->placeholder('后门路径 - 安全确认'), ]); $step4a = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '前门12路径 - 打开实验站光闸', - 'html_url' => "{$baseUrl}/step-4a.html", + 'content' => $this->placeholder('前门12路径 - 打开实验站光闸'), ]); $step4b = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '后门路径 - 设备检查', - 'html_url' => "{$baseUrl}/step-4b.html", + 'content' => $this->placeholder('后门路径 - 设备检查'), ]); $step5 = GuidePage::create([ 'guide_id' => $guide->id, 'title' => '完成', - 'html_url' => "{$baseUrl}/step-5.html", + 'content' => $this->placeholder('完成'), ]); // step1 → step2 (sequential) @@ -185,21 +186,20 @@ class GuideSeeder extends Seeder 'published_at' => now(), ]); - $baseUrl = self::BASE_URL . '/vacuum-valve-issue'; $steps = [ - ['title' => '检查真空度', 'file' => 'step-1.html'], - ['title' => '检查联锁状态', 'file' => 'step-2.html'], - ['title' => '尝试手动复位', 'file' => 'step-3.html'], - ['title' => '检查气动系统', 'file' => 'step-4.html'], - ['title' => '联系维护人员', 'file' => 'step-5.html'], + '检查真空度', + '检查联锁状态', + '尝试手动复位', + '检查气动系统', + '联系维护人员', ]; $pages = []; - foreach ($steps as $i => $step) { + foreach ($steps as $title) { $pages[] = GuidePage::create([ 'guide_id' => $guide->id, - 'title' => $step['title'], - 'html_url' => "{$baseUrl}/{$step['file']}", + 'title' => $title, + 'content' => $this->placeholder($title), ]); } @@ -231,21 +231,20 @@ class GuideSeeder extends Seeder 'published_at' => now(), ]); - $baseUrl = self::BASE_URL . '/water-leak-alarm'; $steps = [ - ['title' => '确认报警位置', 'file' => 'step-1.html'], - ['title' => '搜索光学棚屋', 'file' => 'step-2.html'], - ['title' => '定位并处理漏水点', 'file' => 'step-3.html'], - ['title' => '复位报警', 'file' => 'step-4.html'], - ['title' => '完成', 'file' => 'step-5.html'], + '确认报警位置', + '搜索光学棚屋', + '定位并处理漏水点', + '复位报警', + '完成', ]; $pages = []; - foreach ($steps as $i => $step) { + foreach ($steps as $title) { $pages[] = GuidePage::create([ 'guide_id' => $guide->id, - 'title' => $step['title'], - 'html_url' => "{$baseUrl}/{$step['file']}", + 'title' => $title, + 'content' => $this->placeholder($title), ]); } diff --git a/resources/views/filament/resources/guide/manage-pages.blade.php b/resources/views/filament/resources/guide/manage-pages.blade.php index 49a3d90..ba217e6 100644 --- a/resources/views/filament/resources/guide/manage-pages.blade.php +++ b/resources/views/filament/resources/guide/manage-pages.blade.php @@ -88,17 +88,20 @@ padding-top: 6px; } - .df-node-actions button { + .df-node-actions button, + .df-node-actions a { font-size: 11px; color: #6b7280; cursor: pointer; background: none; border: none; padding: 2px 0; + text-decoration: none; transition: color 0.15s; } - .df-node-actions button:hover { + .df-node-actions button:hover, + .df-node-actions a:hover { color: #3b82f6; } @@ -256,11 +259,12 @@ const html = ` `; diff --git a/resources/views/guides/page.blade.php b/resources/views/guides/page.blade.php new file mode 100644 index 0000000..9d08fac --- /dev/null +++ b/resources/views/guides/page.blade.php @@ -0,0 +1,71 @@ + + + + + +