# 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
**状态**:✅ 完全符合规范