ordered()->get(); $mode = Setting::get('hero_mode', 'carousel'); return view('admin.hero-slides.index', compact('slides', 'mode')); } public function create(): View { return view('admin.hero-slides.form', ['slide' => null]); } public function store(Request $request): RedirectResponse { $data = $request->validate([ 'title' => ['required', 'string', 'max:120'], 'content' => ['nullable', 'string'], 'cta_text' => ['nullable', 'string', 'max:80'], 'cta_url' => ['nullable', 'string', 'max:255'], 'cta2_text' => ['nullable', 'string', 'max:80'], 'cta2_url' => ['nullable', 'string', 'max:255'], 'is_active' => ['boolean'], 'sort_order' => ['integer'], ]); $data['location'] = 'home'; $data['is_active'] = $request->boolean('is_active'); $data['sort_order'] = $data['sort_order'] ?? 0; HeroSlide::create($data); return redirect()->route('admin.hero-slides.index')->with('success', '轮播项已添加'); } public function edit(HeroSlide $hero_slide): View { return view('admin.hero-slides.form', ['slide' => $hero_slide]); } public function update(Request $request, HeroSlide $hero_slide): RedirectResponse { $data = $request->validate([ 'title' => ['required', 'string', 'max:120'], 'content' => ['nullable', 'string'], 'cta_text' => ['nullable', 'string', 'max:80'], 'cta_url' => ['nullable', 'string', 'max:255'], 'cta2_text' => ['nullable', 'string', 'max:80'], 'cta2_url' => ['nullable', 'string', 'max:255'], 'is_active' => ['boolean'], 'sort_order' => ['integer'], ]); $data['is_active'] = $request->boolean('is_active'); $data['sort_order'] = $data['sort_order'] ?? $hero_slide->sort_order; $hero_slide->update($data); return redirect()->route('admin.hero-slides.index')->with('success', '轮播项已更新'); } public function destroy(HeroSlide $hero_slide): RedirectResponse { $hero_slide->delete(); return redirect()->route('admin.hero-slides.index')->with('success', '轮播项已删除'); } /** * 上移 / 下移排序。 */ public function move(Request $request, HeroSlide $hero_slide): RedirectResponse { $direction = $request->input('direction'); if ($direction === 'up') { $sibling = HeroSlide::where('location', 'home')->ordered() ->where('sort_order', '<', $hero_slide->sort_order) ->orderByDesc('sort_order') ->first(); if ($sibling) { [$hero_slide->sort_order, $sibling->sort_order] = [$sibling->sort_order, $hero_slide->sort_order]; $hero_slide->save(); $sibling->save(); } } elseif ($direction === 'down') { $sibling = HeroSlide::where('location', 'home')->ordered() ->where('sort_order', '>', $hero_slide->sort_order) ->first(); if ($sibling) { [$hero_slide->sort_order, $sibling->sort_order] = [$sibling->sort_order, $hero_slide->sort_order]; $hero_slide->save(); $sibling->save(); } } return redirect()->route('admin.hero-slides.index'); } /** * 一键启用 / 停用。 */ public function toggle(HeroSlide $hero_slide): RedirectResponse { $hero_slide->update(['is_active' => ! $hero_slide->is_active]); return redirect()->route('admin.hero-slides.index'); } /** * 全局 Hero 显示模式:carousel(轮播)/ single(独立单图)。 */ public function setMode(Request $request): RedirectResponse { $data = $request->validate([ 'hero_mode' => ['required', 'in:carousel,single'], ]); Setting::set('hero_mode', $data['hero_mode'], 'appearance'); return redirect()->route('admin.hero-slides.index')->with('success', 'Hero 显示模式已更新'); } }