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([ Select::make('naming_scheme') ->label('命名体系') ->options([ 'new' => '新体系', 'old' => '旧体系', ]) ->default('new') ->required(), Select::make('track') ->label('方向') ->options([ 'science' => '理科', 'liberal_arts' => '文科', ]) ->visible(fn ($get): bool => $get('stage') === 'senior'), Select::make('module_type') ->label('模块类型') ->options([ 'compulsory' => '必修', 'selective_compulsory' => '选择性必修', 'elective' => '选修', ]) ->visible(fn ($get): bool => $get('stage') === 'senior'), TextInput::make('volume_no') ->label('册次') ->numeric() ->minValue(1) ->maxValue(3) ->helperText('数字1-3,例:第一册填1'), TextInput::make('legacy_code') ->label('旧版代号') ->helperText('旧教材编号,如:上册-1'), TextInput::make('curriculum_standard_year') ->label('课程标准年份') ->numeric() ->minValue(2000) ->maxValue(2099), TextInput::make('curriculum_revision_year') ->label('课程修订年份') ->numeric() ->minValue(2000) ->maxValue(2099), TextInput::make('approval_authority') ->label('审批机构') ->default('教育部'), TextInput::make('approval_year') ->label('审批年份') ->numeric() ->minValue(2000) ->maxValue(2099), TextInput::make('edition_label') ->label('版本标识') ->helperText('如:第一版、第二版'), ]) ->columns(2), Section::make('封面上传') ->schema([ FileUpload::make('cover_path') ->label('封面图片') ->image() ->directory('textbook-covers'), ]), 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); } }