| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- <?php
- namespace App\Filament\Resources\TextbookResource\Pages;
- use App\Filament\Resources\TextbookResource;
- use App\Models\SourcePaper;
- use App\Services\TextbookApiService;
- use Filament\Resources\Pages\ViewRecord;
- class ViewTextbook extends ViewRecord
- {
- protected static string $resource = TextbookResource::class;
- protected string $view = 'filament.resources.textbook-resource.view';
- public array $catalogTree = [];
- public array $linkedPapers = [];
- public array $catalogCoverage = [];
- public int $unlinkedPaperCount = 0;
- public function mount(int|string $record): void
- {
- $startedAt = microtime(true);
- parent::mount($record);
- $apiService = app(TextbookApiService::class);
- $catalogStartedAt = microtime(true);
- $this->catalogTree = $apiService->getTextbookCatalog((int) $this->record->id, 'tree');
- \Log::debug('ViewTextbook: catalog loaded', [
- 'record_id' => $this->record->id,
- 'elapsed_ms' => (int) ((microtime(true) - $catalogStartedAt) * 1000),
- 'node_count' => count($this->catalogTree),
- ]);
- $seriesName = $this->record->series->name ?? null;
- $linkedStartedAt = microtime(true);
- $this->linkedPapers = SourcePaper::query()
- ->when($seriesName, fn ($query) => $query->where('textbook_series', $seriesName))
- ->latest('updated_at')
- ->take(8)
- ->get()
- ->map(fn ($paper) => [
- 'id' => $paper->id,
- 'title' => $paper->title ?: $paper->full_title ?: '未命名卷子',
- 'chapter' => $paper->chapter,
- 'grade' => $paper->grade,
- 'term' => $paper->term,
- 'source_type' => $paper->source_type,
- 'updated_at' => $paper->updated_at,
- ])
- ->toArray();
- \Log::debug('ViewTextbook: linked papers loaded', [
- 'record_id' => $this->record->id,
- 'elapsed_ms' => (int) ((microtime(true) - $linkedStartedAt) * 1000),
- 'count' => count($this->linkedPapers),
- ]);
- // 用 SQL 聚合替代全量 get()->each(),避免教材关联卷子多时页面卡顿。
- $coverageStartedAt = microtime(true);
- $this->catalogCoverage = SourcePaper::query()
- ->where('textbook_id', $this->record->id)
- ->whereRaw("JSON_EXTRACT(meta, '$.catalog_node_id') IS NOT NULL")
- ->selectRaw("JSON_UNQUOTE(JSON_EXTRACT(meta, '$.catalog_node_id')) AS catalog_node_id, COUNT(*) AS aggregate_count")
- ->groupBy('catalog_node_id')
- ->pluck('aggregate_count', 'catalog_node_id')
- ->map(fn ($count) => (int) $count)
- ->all();
- $this->unlinkedPaperCount = SourcePaper::query()
- ->where('textbook_id', $this->record->id)
- ->where(function ($query) {
- $query
- ->whereNull('meta')
- ->orWhereRaw("JSON_EXTRACT(meta, '$.catalog_node_id') IS NULL");
- })
- ->count();
- \Log::debug('ViewTextbook: coverage computed', [
- 'record_id' => $this->record->id,
- 'elapsed_ms' => (int) ((microtime(true) - $coverageStartedAt) * 1000),
- 'coverage_nodes' => count($this->catalogCoverage),
- 'unlinked_count' => $this->unlinkedPaperCount,
- ]);
- \Log::debug('ViewTextbook: mount done', [
- 'record_id' => $this->record->id,
- 'total_elapsed_ms' => (int) ((microtime(true) - $startedAt) * 1000),
- ]);
- }
- }
|