Files
KnowledgeBase/app/Filament/Resources/GuideResource.php
2026-04-23 08:45:44 +08:00

248 lines
9.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\GuideResource\Pages;
use App\Models\Guide;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
class GuideResource extends Resource
{
protected static ?string $model = Guide::class;
protected static ?string $navigationIcon = 'heroicon-o-book-open';
protected static ?string $navigationLabel = '操作指引';
protected static ?string $modelLabel = '指引';
protected static ?string $pluralModelLabel = '指引';
protected static ?int $navigationSort = 3;
protected static ?string $navigationGroup = '业务管理';
public static function shouldRegisterNavigation(): bool
{
return auth()->user()?->can('guide.view') ?? false;
}
public static function getEloquentQuery(): Builder
{
$query = parent::getEloquentQuery();
$user = auth()->user();
if ($user && $user->hasStationRestriction()) {
$query->accessibleBy($user);
}
return $query;
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make('基本信息')
->schema([
Forms\Components\TextInput::make('name')
->label('指引名称')
->required()
->maxLength(255)
->placeholder('例如: 如何用光'),
Forms\Components\Select::make('category')
->label('分类')
->required()
->options([
'operation' => '操作指引',
'fault_handling' => '故障处理',
'training' => '培训教程',
'safety' => '安全规范',
'maintenance' => '维护保养',
])
->default('operation'),
Forms\Components\Select::make('status')
->label('状态')
->required()
->options([
'draft' => '草稿',
'published' => '已发布',
'archived' => '已归档',
])
->default('draft'),
Forms\Components\TagsInput::make('tags')
->label('标签')
->placeholder('输入标签后回车')
->helperText('用于分类和搜索的关键词标签'),
Forms\Components\Textarea::make('description')
->label('描述')
->maxLength(1000)
->placeholder('简要描述此指引的用途')
->columnSpanFull(),
])
->columns(2),
Forms\Components\Section::make('关联线站')
->schema([
Forms\Components\CheckboxList::make('stations')
->label('适用线站')
->relationship('stations', 'name')
->searchable()
->bulkToggleable()
->helperText('选择此指引适用的线站,未关联线站的指引为全局指引')
->columns(3),
])
->description('不关联任何线站则为全局指引,对所有终端可见'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->label('指引名称')
->searchable()
->sortable()
->weight('bold'),
Tables\Columns\TextColumn::make('category')
->label('分类')
->badge()
->formatStateUsing(fn(string $state): string => match ($state) {
'operation' => '操作指引',
'fault_handling' => '故障处理',
'training' => '培训教程',
'safety' => '安全规范',
'maintenance' => '维护保养',
default => $state,
})
->color(fn(string $state): string => match ($state) {
'operation' => 'primary',
'fault_handling' => 'danger',
'training' => 'info',
'safety' => 'warning',
'maintenance' => 'gray',
default => 'gray',
})
->sortable(),
Tables\Columns\TextColumn::make('status')
->label('状态')
->badge()
->formatStateUsing(fn(string $state): string => match ($state) {
'draft' => '草稿',
'published' => '已发布',
'archived' => '已归档',
default => $state,
})
->color(fn(string $state): string => match ($state) {
'draft' => 'gray',
'published' => 'success',
'archived' => 'warning',
default => 'gray',
})
->sortable(),
Tables\Columns\TextColumn::make('pages_count')
->label('页数')
->counts('pages')
->sortable(),
Tables\Columns\TextColumn::make('stations_count')
->label('关联线站')
->counts('stations')
->sortable()
->badge()
->color(fn(int $state): string => $state > 0 ? 'info' : 'success')
->formatStateUsing(fn(int $state): string => $state > 0 ? "{$state}" : '全局'),
Tables\Columns\TextColumn::make('created_at')
->label('创建时间')
->dateTime('Y-m-d H:i')
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\SelectFilter::make('category')
->label('分类')
->options([
'operation' => '操作指引',
'fault_handling' => '故障处理',
'training' => '培训教程',
'safety' => '安全规范',
'maintenance' => '维护保养',
]),
Tables\Filters\SelectFilter::make('status')
->label('状态')
->options([
'draft' => '草稿',
'published' => '已发布',
'archived' => '已归档',
]),
])
->actions([
Tables\Actions\EditAction::make()->label('编辑'),
Tables\Actions\Action::make('duplicate')
->label('复制')
->icon('heroicon-o-document-duplicate')
->color('info')
->requiresConfirmation()
->action(function (Guide $record) {
$newGuide = $record->replicate(['pages_count', 'stations_count']);
$newGuide->name = $record->name . ' (副本)';
$newGuide->created_by = auth()->id();
$newGuide->published_at = null;
$newGuide->save();
// 复制页面
$pageIdMap = [];
foreach ($record->pages as $page) {
$newPage = $page->replicate();
$newPage->guide_id = $newGuide->id;
$newPage->save();
$pageIdMap[$page->id] = $newPage->id;
}
// 复制边edges并更新页面 ID 映射
foreach ($record->edges as $edge) {
$newEdge = $edge->replicate();
$newEdge->guide_id = $newGuide->id;
$newEdge->from_page_id = $pageIdMap[$edge->from_page_id] ?? $edge->from_page_id;
$newEdge->to_page_id = $pageIdMap[$edge->to_page_id] ?? $edge->to_page_id;
$newEdge->save();
}
return redirect()->to(route('filament.admin.resources.guides.edit', ['record' => $newGuide]));
}),
Tables\Actions\DeleteAction::make()->label('删除'),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make()->label('批量删除'),
]),
])
->defaultSort('created_at', 'desc');
}
public static function getPages(): array
{
return [
'index' => Pages\ListGuides::route('/'),
'create' => Pages\CreateGuide::route('/create'),
'edit' => Pages\EditGuide::route('/{record}/edit'),
'manage-pages' => Pages\ManageGuidePages::route('/{record}/manage-pages'),
];
}
}