- 创建 SopTemplateResource 资源类 - 实现模板列表、创建、编辑、查看页面 - 添加步骤编辑器(Repeater 组件) - 支持富文本编辑步骤内容 - 支持拖拽排序步骤 - 添加状态筛选和分类筛选 - 显示步骤数统计
260 lines
11 KiB
PHP
260 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources;
|
|
|
|
use App\Filament\Resources\SopTemplateResource\Pages;
|
|
use App\Models\SopTemplate;
|
|
use Filament\Forms;
|
|
use Filament\Forms\Form;
|
|
use Filament\Resources\Resource;
|
|
use Filament\Tables;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class SopTemplateResource extends Resource
|
|
{
|
|
protected static ?string $model = SopTemplate::class;
|
|
|
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
|
|
|
protected static ?string $navigationLabel = 'SOP模板';
|
|
|
|
protected static ?string $modelLabel = 'SOP模板';
|
|
|
|
protected static ?string $pluralModelLabel = 'SOP模板';
|
|
|
|
protected static ?int $navigationSort = 4;
|
|
|
|
public static function form(Form $form): Form
|
|
{
|
|
return $form
|
|
->schema([
|
|
Forms\Components\Section::make('基本信息')
|
|
->schema([
|
|
Forms\Components\TextInput::make('name')
|
|
->label('模板名称')
|
|
->required()
|
|
->maxLength(255),
|
|
|
|
Forms\Components\Textarea::make('description')
|
|
->label('模板描述')
|
|
->rows(3)
|
|
->maxLength(65535),
|
|
|
|
Forms\Components\TextInput::make('category')
|
|
->label('分类')
|
|
->maxLength(100)
|
|
->placeholder('例如:安全操作、设备维护、质量检查'),
|
|
|
|
Forms\Components\TagsInput::make('tags')
|
|
->label('标签')
|
|
->placeholder('添加标签')
|
|
->separator(','),
|
|
])
|
|
->columns(2),
|
|
|
|
Forms\Components\Section::make('适用范围')
|
|
->schema([
|
|
Forms\Components\TagsInput::make('applicable_departments')
|
|
->label('适用部门')
|
|
->placeholder('添加部门')
|
|
->separator(','),
|
|
|
|
Forms\Components\TagsInput::make('applicable_positions')
|
|
->label('适用岗位')
|
|
->placeholder('添加岗位')
|
|
->separator(','),
|
|
])
|
|
->columns(2),
|
|
|
|
Forms\Components\Section::make('版本管理')
|
|
->schema([
|
|
Forms\Components\TextInput::make('version')
|
|
->label('版本号')
|
|
->default('1.0.0')
|
|
->required()
|
|
->maxLength(50),
|
|
|
|
Forms\Components\Select::make('status')
|
|
->label('状态')
|
|
->options([
|
|
'draft' => '草稿',
|
|
'published' => '已发布',
|
|
'archived' => '已归档',
|
|
])
|
|
->default('draft')
|
|
->required(),
|
|
])
|
|
->columns(2)
|
|
->visible(fn ($livewire) => $livewire instanceof Pages\EditSopTemplate),
|
|
|
|
// 步骤编辑器 - 只在编辑页面显示
|
|
Forms\Components\Section::make('操作步骤')
|
|
->schema([
|
|
Forms\Components\Repeater::make('steps')
|
|
->label('')
|
|
->relationship('steps')
|
|
->schema([
|
|
Forms\Components\TextInput::make('step_number')
|
|
->label('步骤序号')
|
|
->numeric()
|
|
->required()
|
|
->default(fn ($get) => $get('../../steps') ? count($get('../../steps')) + 1 : 1),
|
|
|
|
Forms\Components\TextInput::make('title')
|
|
->label('步骤标题')
|
|
->required()
|
|
->maxLength(255)
|
|
->columnSpanFull(),
|
|
|
|
Forms\Components\RichEditor::make('content')
|
|
->label('步骤内容')
|
|
->toolbarButtons([
|
|
'bold',
|
|
'italic',
|
|
'underline',
|
|
'strike',
|
|
'bulletList',
|
|
'orderedList',
|
|
'h2',
|
|
'h3',
|
|
'link',
|
|
'blockquote',
|
|
'codeBlock',
|
|
])
|
|
->columnSpanFull(),
|
|
|
|
Forms\Components\Toggle::make('is_required')
|
|
->label('是否必需')
|
|
->default(true),
|
|
|
|
Forms\Components\Hidden::make('sort_order')
|
|
->default(fn ($get) => $get('step_number')),
|
|
])
|
|
->columns(2)
|
|
->reorderable('sort_order')
|
|
->reorderableWithButtons()
|
|
->collapsible()
|
|
->itemLabel(fn (array $state): ?string => $state['title'] ?? '新步骤')
|
|
->addActionLabel('添加步骤')
|
|
->defaultItems(0)
|
|
->mutateRelationshipDataBeforeCreateUsing(function (array $data): array {
|
|
$data['sort_order'] = $data['step_number'];
|
|
return $data;
|
|
})
|
|
->mutateRelationshipDataBeforeSaveUsing(function (array $data): array {
|
|
$data['sort_order'] = $data['step_number'];
|
|
return $data;
|
|
}),
|
|
])
|
|
->visible(fn ($livewire) => $livewire instanceof Pages\EditSopTemplate),
|
|
]);
|
|
}
|
|
|
|
public static function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->columns([
|
|
Tables\Columns\TextColumn::make('name')
|
|
->label('模板名称')
|
|
->searchable()
|
|
->sortable(),
|
|
|
|
Tables\Columns\TextColumn::make('category')
|
|
->label('分类')
|
|
->searchable()
|
|
->sortable()
|
|
->badge()
|
|
->color('info'),
|
|
|
|
Tables\Columns\TextColumn::make('version')
|
|
->label('版本')
|
|
->sortable(),
|
|
|
|
Tables\Columns\TextColumn::make('status')
|
|
->label('状态')
|
|
->badge()
|
|
->color(fn (string $state): string => match ($state) {
|
|
'draft' => 'gray',
|
|
'published' => 'success',
|
|
'archived' => 'warning',
|
|
})
|
|
->formatStateUsing(fn (string $state): string => match ($state) {
|
|
'draft' => '草稿',
|
|
'published' => '已发布',
|
|
'archived' => '已归档',
|
|
default => $state,
|
|
}),
|
|
|
|
Tables\Columns\TextColumn::make('steps_count')
|
|
->label('步骤数')
|
|
->counts('steps')
|
|
->sortable(),
|
|
|
|
Tables\Columns\TextColumn::make('creator.name')
|
|
->label('创建人')
|
|
->sortable()
|
|
->toggleable(),
|
|
|
|
Tables\Columns\TextColumn::make('published_at')
|
|
->label('发布时间')
|
|
->dateTime('Y-m-d H:i')
|
|
->sortable()
|
|
->toggleable(),
|
|
|
|
Tables\Columns\TextColumn::make('created_at')
|
|
->label('创建时间')
|
|
->dateTime('Y-m-d H:i')
|
|
->sortable()
|
|
->toggleable(isToggledHiddenByDefault: true),
|
|
])
|
|
->filters([
|
|
Tables\Filters\SelectFilter::make('status')
|
|
->label('状态')
|
|
->options([
|
|
'draft' => '草稿',
|
|
'published' => '已发布',
|
|
'archived' => '已归档',
|
|
]),
|
|
|
|
Tables\Filters\SelectFilter::make('category')
|
|
->label('分类')
|
|
->options(function () {
|
|
return SopTemplate::query()
|
|
->whereNotNull('category')
|
|
->distinct()
|
|
->pluck('category', 'category')
|
|
->toArray();
|
|
}),
|
|
])
|
|
->actions([
|
|
Tables\Actions\ViewAction::make(),
|
|
Tables\Actions\EditAction::make(),
|
|
Tables\Actions\DeleteAction::make(),
|
|
])
|
|
->bulkActions([
|
|
Tables\Actions\BulkActionGroup::make([
|
|
Tables\Actions\DeleteBulkAction::make(),
|
|
]),
|
|
])
|
|
->defaultSort('created_at', 'desc');
|
|
}
|
|
|
|
public static function getRelations(): array
|
|
{
|
|
return [
|
|
//
|
|
];
|
|
}
|
|
|
|
public static function getPages(): array
|
|
{
|
|
return [
|
|
'index' => Pages\ListSopTemplates::route('/'),
|
|
'create' => Pages\CreateSopTemplate::route('/create'),
|
|
'view' => Pages\ViewSopTemplate::route('/{record}'),
|
|
'edit' => Pages\EditSopTemplate::route('/{record}/edit'),
|
|
];
|
|
}
|
|
}
|