# Filament + Livewire 规范开发说明 ## ✅ 已按照规范完成的修改 ### 1. PHP 类型声明(QuestionManagement.php) #### ✅ 正确的类型注解 ```php use BackedEnum; use UnitEnum; // 导航图标(必须是 BackedEnum|string|null) protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-rectangle-stack'; // 导航组(必须是 UnitEnum|string|null) protected static string|UnitEnum|null $navigationGroup = '题库系统'; // 导航标签 protected static ?string $navigationLabel = '题库管理'; // 导航排序 protected static ?int $navigationSort = 2; ``` #### ❌ 错误的类型注解(已修复) ```php // 错误:使用了 ?string protected static ?string $navigationGroup = '题库系统'; // 正确:使用 string|UnitEnum|null protected static string|UnitEnum|null $navigationGroup = '题库系统'; ``` ### 2. Livewire 3 特性使用 #### ✅ Compute 属性(替代原有属性) ```php use Livewire\Attributes\Computed; /** * 计算属性:从 API 获取题目列表 */ #[Computed] public function questions(): array { $service = app(QuestionServiceApi::class); // ... 逻辑 return $response['data'] ?? []; } /** * 计算属性:分页信息 */ #[Computed] public function meta(): array { // ... 逻辑 return $response['meta'] ?? []; } /** * 计算属性:统计数据 */ #[Computed] public function statistics(): array { // ... 逻辑 return $service->getStatistics(); } ``` #### ✅ 事件监听器 ```php use Livewire\Attributes\On; /** * 刷新数据 */ #[On('refresh-data')] public function refreshData(): void { $this->resetCache(); // ... } /** * AI 生成题目 */ #[On('ai-generate')] public function aiGenerate(): void { // ... } ``` #### ✅ 响应式更新 ```php /** * 搜索更新处理 */ public function updatedSearch(): void { $this->currentPage = 1; } /** * 知识点筛选更新处理 */ public function updatedSelectedKpCode(): void { $this->currentPage = 1; } ``` ### 3. 视图层规范(question-management.blade.php) #### ✅ Livewire 指令使用 **双向绑定**: ```blade {{-- 搜索框 --}} {{-- 知识点筛选 --}} {{-- 难度筛选 --}} {{-- 每页数量 --}} ``` **点击事件**: ```blade {{-- AI 生成题目按钮 --}} AI 生成题目 {{-- 刷新按钮 --}} 刷新 {{-- 上一页 --}} {{-- 下一页 --}} ``` **加载状态**: ```blade {{-- 表格加载状态 --}}
{{-- 加载指示器 --}}
加载中...
``` #### ✅ Compute 属性调用 ```blade {{-- 调用 compute 属性 --}} {{ $this->questions }} {{-- 统计数据 --}} {{ $this->statistics['total'] ?? 0 }} {{ $this->statistics['by_difficulty']['0.3'] ?? 0 }} {{-- 分页信息 --}} {{ $this->meta['total'] ?? 0 }} {{ $this->meta['total_pages'] ?? 0 }} {{-- 调用方法 --}} @foreach($this->getPages() as $page) {{ $page }} @endforeach ``` ### 4. Filament 组件使用 #### ✅ 正确的组件调用 ```blade {{-- 页面容器 --}} {{-- 区块组件 --}} {{-- 输入框组件 --}} {{-- 按钮组件 --}} AI 生成题目 ``` ### 5. 分页实现规范 #### ✅ 分页属性 ```php public int $currentPage = 1; public int $perPage = 25; ``` #### ✅ 分页方法 ```php /** * 跳转到指定页 */ public function gotoPage(int $page): void { $this->currentPage = $page; } /** * 上一页 */ public function previousPage(): void { if ($this->currentPage > 1) { $this->currentPage--; } } /** * 下一页 */ public function nextPage(): void { if ($this->currentPage < ($this->meta['total_pages'] ?? 1)) { $this->currentPage++; } } /** * 获取页码数组(用于分页器) */ public function getPages(): array { $totalPages = $this->meta['total_pages'] ?? 1; $currentPage = $this->currentPage; $pages = []; $start = max(1, $currentPage - 2); $end = min($totalPages, $currentPage + 2); for ($i = $start; $i <= $end; $i++) { $pages[] = $i; } return $pages; } ``` #### ✅ 分页视图 ```blade {{-- 分页按钮 --}} @foreach($this->getPages() as $page) @endforeach ``` ### 6. API 客户端规范 #### ✅ 服务类设计 ```php class QuestionServiceApi { public function __construct( protected string $baseUrl = '', protected int $timeout = 10, protected int $cacheTtl = 300, ) { // 初始化 } /** * 获取所有题目(分页) */ public function listQuestions(int $page = 1, int $perPage = 50, array $filters = []): array { // 实现 } /** * 语义搜索题目 */ public function searchQuestions(string $query, int $limit = 20): array { // 实现 } /** * 获取题目统计信息 */ public function getStatistics(): array { // 实现 } } ``` #### ✅ 错误处理 ```php try { $response = $this->request('GET', '/questions', $query); return $response; } catch (\Exception $e) { \Log::error('Failed to fetch questions: ' . $e->getMessage()); return ['data' => [], 'meta' => []]; } ``` #### ✅ 缓存机制 ```php return Cache::remember( $cacheKey, now()->addSeconds($this->cacheTtl), function () use ($page, $perPage, $filters): array { // API 调用逻辑 } ); ``` ## 🎯 最佳实践总结 ### ✅ 已实现的功能 1. **✅ 正确的类型声明** - navigationIcon: `string|BackedEnum|null` - navigationGroup: `string|UnitEnum|null` - navigationLabel: `?string` 2. **✅ Livewire 3 特性** - Compute 属性(替代原有属性) - 事件监听器(`#[On]`) - 响应式更新(`updated*` 方法) - 双向绑定(`wire:model`) - 点击事件(`wire:click`) 3. **✅ Filament 组件** - 使用官方组件 - 正确的事件分发(`$dispatch`) - 加载状态指示 4. **✅ 分页实现** - 自定义分页逻辑 - 上一页/下一页 - 页码跳转 - 动态页码显示 5. **✅ 性能优化** - 缓存机制 - 防抖搜索(300ms) - 计算属性缓存 6. **✅ 错误处理** - 异常捕获 - 日志记录 - 用户友好提示 ### 📋 编码规范检查清单 - [ ] 使用正确的类型注解 - [ ] 使用 Livewire 3 特性 - [ ] 使用 Compute 属性替代原有属性 - [ ] 使用 `#[On]` 装饰器处理事件 - [ ] 使用 `wire:model.live` 实现双向绑定 - [ ] 使用 `wire:click` 处理点击事件 - [ ] 使用 `wire:loading` 显示加载状态 - [ ] 使用 Filament 官方组件 - [ ] 实现防抖搜索 - [ ] 添加错误处理 - [ ] 添加日志记录 - [ ] 使用缓存优化性能 - [ ] 遵循 PSR-12 编码规范 - [ ] 添加 PHPDoc 注释 ## 🚀 使用方法 ### 启动服务 ```bash cd /Volumes/T9/code/math/apis/KnowledgeServic && docker compose up -d cd /Volumes/T9/code/math/apis/QuestionBankService && docker compose up -d cd /Volumes/T9/code/math/apis/FilamentAdmin && herd serve ``` ### 访问后台 ``` URL: http://filament-admin.test/admin 导航:题库系统 → 题库管理 ``` ### 功能说明 1. **实时搜索**:输入关键词即时筛选结果 2. **多维筛选**:按知识点、难度、每页数量筛选 3. **分页浏览**:支持上一页/下一页/页码跳转 4. **统计展示**:显示题目总数和各难度分布 5. **加载状态**:实时显示数据加载进度 6. **操作按钮**:AI 生成、刷新、搜索等功能 ## 📚 参考资料 - [Filament 3 文档](https://filamentphp.com/docs) - [Livewire 3 文档](https://livewire.laravel.com/docs) - [Filament Pages](https://filamentphp.com/docs/panels/pages) - [Livewire Attributes](https://livewire.laravel.com/docs/attributes) ## ✨ 总结 严格按照 Filament 3 和 Livewire 3 规范开发的 QuestionManagement 功能现已完全符合标准,包括: 1. ✅ 正确的 PHP 类型声明 2. ✅ 规范的 Livewire 特性使用 3. ✅ 完善的交互体验 4. ✅ 高效的性能表现 5. ✅ 清晰的代码结构 可以立即使用! --- **创建日期**:2025-11-15 **版本**:v2.0 **状态**:✅ 完全符合规范