| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- <?php
- namespace App\Filament\Resources\TextbookResource\Schemas;
- use App\Filament\Resources\TextbookResource;
- use App\Services\TextbookApiService;
- use App\Services\TextbookCoverStorageService;
- use Filament\Forms\Components\FileUpload;
- use Filament\Forms\Components\Select;
- use Filament\Schemas\Components\Section;
- use Filament\Forms\Components\TextInput;
- use Filament\Forms\Components\Textarea;
- use Filament\Schemas\Schema;
- class TextbookFormSchema
- {
- public static function make(Schema $schema): Schema
- {
- return $schema
- ->schema([
- Section::make('基本信息')
- ->schema([
- Select::make('series_id')
- ->label('教材系列')
- ->options(function () {
- $series = app(TextbookApiService::class)->getTextbookSeries();
- $options = [];
- foreach ($series['data'] as $s) {
- $displayName = $s['name'] ?? '未命名系列';
- if (!empty($s['publisher'])) {
- $displayName .= ' (' . $s['publisher'] . ')';
- }
- $options[$s['id']] = $displayName;
- }
- return $options;
- })
- ->required()
- ->searchable()
- ->preload(),
- TextInput::make('official_title')
- ->label('教材名称')
- ->maxLength(512)
- ->helperText('教材名称(用户输入)'),
- TextInput::make('isbn')
- ->label('ISBN')
- ->maxLength(20),
- Textarea::make('aliases')
- ->label('别名')
- ->helperText('JSON 格式,如:["别名1", "别名2"]')
- ->formatStateUsing(fn ($state) => is_array($state) ? json_encode($state, JSON_UNESCAPED_UNICODE) : $state)
- ->dehydrateStateUsing(fn ($state) => is_string($state) ? json_decode($state, true) : $state)
- ->columnSpanFull(),
- ])
- ->columns(2),
- Section::make('学段/年级/学期')
- ->schema([
- Select::make('stage')
- ->label('学段')
- ->options([
- 'primary' => '小学',
- 'junior' => '初中',
- 'senior' => '高中',
- ])
- ->default('junior')
- ->required()
- ->reactive(),
- Select::make('schooling_system')
- ->label('学制')
- ->options([
- '63' => '六三学制',
- '54' => '五四学制',
- ])
- ->default('63')
- ->visible(fn ($get): bool => in_array($get('stage'), ['primary', 'junior'])),
- TextInput::make('grade')
- ->label('年级')
- ->numeric()
- ->minValue(1)
- ->maxValue(12)
- ->helperText('数字1-12,例:1年级填1'),
- Select::make('semester')
- ->label('学期')
- ->options([
- 1 => '上学期',
- 2 => '下学期',
- ])
- ->required(),
- ])
- ->columns(2),
- Section::make('封面上传')
- ->schema([
- FileUpload::make('cover_path')
- ->label('封面图片')
- ->image()
- ->directory('textbook-covers')
- ->saveUploadedFileUsing(function ($component, $file) {
- $uploader = app(TextbookCoverStorageService::class);
- $url = $uploader->uploadCover($file, null);
- if ($url) {
- return $url;
- }
- return $file->storePubliclyAs(
- $component->getDirectory(),
- $component->getUploadedFileNameForStorage($file),
- $component->getDiskName(),
- );
- }),
- ]),
- Section::make('发布与排序')
- ->schema([
- Select::make('status')
- ->label('状态')
- ->options([
- 'draft' => '草稿',
- 'published' => '已发布',
- 'archived' => '已归档',
- ])
- ->default('draft')
- ->required(),
- TextInput::make('sort_order')
- ->label('排序')
- ->numeric()
- ->default(0)
- ->helperText('数字越小排序越靠前'),
- Textarea::make('meta')
- ->label('扩展信息')
- ->helperText('JSON 格式')
- ->formatStateUsing(fn ($state) => is_array($state) ? json_encode($state, JSON_UNESCAPED_UNICODE) : $state)
- ->dehydrateStateUsing(fn ($state) => is_string($state) ? json_decode($state, true) : $state)
- ->columnSpanFull(),
- ])
- ->columns(2),
- ])
- ->columns(2);
- }
- }
|