recordId = (int) $record; if ($this->recordId <= 0) { abort(404); } // 从API获取教材数据 $apiService = app(TextbookApiService::class); $textbookData = $apiService->getTextbook($this->recordId); if (!$textbookData) { abort(404); } $this->data = $textbookData; $this->form->fill($this->data); } public function save(): void { // 必须用 form->getState():会触发临时文件落盘/春笋 URL、再执行 dehydrateStateUsing 得到逗号串。 // 直接读 $this->data 会跳过上述步骤,导致「保存无效」且新图不会上传。 $data = $this->form->getState(); $allowedFields = [ 'series_id', 'stage', 'grade', 'semester', 'naming_scheme', 'track', 'module_type', 'volume_no', 'legacy_code', 'curriculum_standard_year', 'curriculum_revision_year', 'approval_authority', 'approval_year', 'edition_label', 'official_title', 'aliases', 'isbn', 'status', 'sort_order', 'meta', ]; $updateData = []; foreach ($allowedFields as $field) { if (! array_key_exists($field, $data)) { continue; } $value = $data[$field]; if (is_array($value) || is_object($value)) { continue; } $updateData[$field] = $value; } try { $apiService = app(TextbookApiService::class); $response = $apiService->updateTextbook($this->recordId, $updateData); } catch (Throwable $e) { \Filament\Notifications\Notification::make() ->title('保存失败') ->body($e->getMessage()) ->danger() ->send(); return; } $row = $response['data'] ?? $response; if (! is_array($row)) { $row = []; } $this->data = array_merge($this->data, $row); $this->form->fill($this->data); \Filament\Notifications\Notification::make() ->title('教材更新成功') ->success() ->send(); } protected function getHeaderActions(): array { return [ Actions\Action::make('covers') ->label('管理配图') ->icon('heroicon-o-photo') ->url(fn (): string => static::$resource::getUrl('covers', ['record' => $this->recordId])), Actions\Action::make('back') ->label('返回列表') ->url(static::$resource::getUrl('index')) ->color('gray'), ]; } public function getTitle(): string { return '编辑教材'; } public function getView(): string { return 'filament.resources.textbook-resource.edit'; } public function form(\Filament\Schemas\Schema $schema): \Filament\Schemas\Schema { return $schema ->schema([ Section::make('基本信息') ->schema([ Forms\Components\Select::make('series_id') ->label('教材系列') ->options(function () { $apiService = app(TextbookApiService::class); $series = $apiService->getTextbookSeries(); $options = []; foreach ($series['data'] as $s) { $options[$s['id']] = $s['name'] ?? '未命名系列'; } return $options; }) ->required() ->searchable(), Forms\Components\Select::make('stage') ->label('学段') ->options([ 'primary' => '小学', 'junior' => '初中', 'senior' => '高中', ]) ->required() ->reactive(), Forms\Components\TextInput::make('grade') ->label('年级') ->numeric() ->helperText('例如:7表示七年级'), Forms\Components\Select::make('semester') ->label('学期') ->options([ 1 => '上学期', 2 => '下学期', ]) ->helperText('选择学期'), Forms\Components\TextInput::make('official_title') ->label('教材名称') ->required() ->maxLength(255), Forms\Components\TextInput::make('isbn') ->label('ISBN') ->maxLength(255), Forms\Components\Select::make('status') ->label('状态') ->options([ 'draft' => '草稿', 'published' => '已发布', 'archived' => '已归档', ]) ->required(), ]) ->columns(2), ]) ->statePath('data'); } }