PromptManagement.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. namespace App\Filament\Pages;
  3. use App\Services\QuestionServiceApi;
  4. use BackedEnum;
  5. use Filament\Actions;
  6. use Filament\Notifications\Notification;
  7. use Filament\Pages\Page;
  8. use UnitEnum;
  9. use Livewire\Attributes\Computed;
  10. use Livewire\Attributes\On;
  11. class PromptManagement extends Page
  12. {
  13. protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-chat-bubble-left-right';
  14. protected static string|UnitEnum|null $navigationGroup = '题库系统';
  15. protected static ?string $navigationLabel = '提示词管理';
  16. protected static ?int $navigationSort = 3;
  17. protected ?string $heading = '提示词管理';
  18. protected string $view = 'filament.pages.prompt-management';
  19. public ?string $selectedType = null;
  20. public ?string $search = null;
  21. public int $currentPage = 1;
  22. public int $perPage = 10;
  23. public array $selectedPrompts = [];
  24. /**
  25. * 获取提示词列表
  26. */
  27. public function getPrompts(): array
  28. {
  29. $service = app(QuestionServiceApi::class);
  30. try {
  31. // 获取所有提示词
  32. $prompts = $service->listPrompts();
  33. // 筛选
  34. if ($this->selectedType) {
  35. $prompts = array_filter($prompts, fn($prompt) =>
  36. $prompt['template_type'] === $this->selectedType
  37. );
  38. }
  39. if ($this->search) {
  40. $searchTerm = strtolower($this->search);
  41. $prompts = array_filter($prompts, fn($prompt) =>
  42. str_contains(strtolower($prompt['template_name']), $searchTerm) ||
  43. str_contains(strtolower($prompt['description']), $searchTerm)
  44. );
  45. }
  46. // 分页
  47. $total = count($prompts);
  48. $offset = ($this->currentPage - 1) * $this->perPage;
  49. $paginated = array_slice($prompts, $offset, $this->perPage);
  50. return [
  51. 'data' => $paginated,
  52. 'meta' => [
  53. 'page' => $this->currentPage,
  54. 'per_page' => $this->perPage,
  55. 'total' => $total,
  56. 'total_pages' => (int) ceil($total / $this->perPage),
  57. ]
  58. ];
  59. } catch (\Exception $e) {
  60. \Log::error('Failed to fetch prompts: ' . $e->getMessage());
  61. return ['data' => [], 'meta' => ['total' => 0]];
  62. }
  63. }
  64. /**
  65. * 获取提示词类型统计
  66. */
  67. public function getTypeStats(): array
  68. {
  69. $service = app(QuestionServiceApi::class);
  70. try {
  71. $prompts = $service->listPrompts();
  72. $stats = [];
  73. foreach ($prompts as $prompt) {
  74. $type = $prompt['template_type'];
  75. if (!isset($stats[$type])) {
  76. $stats[$type] = 0;
  77. }
  78. $stats[$type]++;
  79. }
  80. return $stats;
  81. } catch (\Exception $e) {
  82. \Log::error('Failed to fetch prompt stats: ' . $e->getMessage());
  83. return [];
  84. }
  85. }
  86. /**
  87. * 获取所有类型选项
  88. */
  89. public function getTypeOptions(): array
  90. {
  91. return [
  92. '题目生成' => '题目生成',
  93. '掌握度评估' => '掌握度评估',
  94. '技能熟练度' => '技能熟练度',
  95. '质量审核' => '质量审核',
  96. ];
  97. }
  98. /**
  99. * 筛选更新
  100. */
  101. public function updatedSelectedType(): void
  102. {
  103. $this->currentPage = 1;
  104. }
  105. public function updatedSearch(): void
  106. {
  107. $this->currentPage = 1;
  108. }
  109. public function updatedPerPage(): void
  110. {
  111. $this->currentPage = 1;
  112. }
  113. /**
  114. * 跳转到指定页
  115. */
  116. public function gotoPage(int $page): void
  117. {
  118. $this->currentPage = $page;
  119. }
  120. /**
  121. * 上一页
  122. */
  123. public function previousPage(): void
  124. {
  125. if ($this->currentPage > 1) {
  126. $this->currentPage--;
  127. }
  128. }
  129. /**
  130. * 下一页
  131. */
  132. public function nextPage(): void
  133. {
  134. $totalPages = $this->prompts['meta']['total_pages'] ?? 1;
  135. if ($this->currentPage < $totalPages) {
  136. $this->currentPage++;
  137. }
  138. }
  139. /**
  140. * 创建新提示词
  141. */
  142. #[On('create-prompt')]
  143. public function createPrompt(): void
  144. {
  145. Notification::make()
  146. ->title('创建提示词')
  147. ->body('打开创建表单')
  148. ->info()
  149. ->send();
  150. }
  151. /**
  152. * 编辑提示词
  153. */
  154. #[On('edit-prompt')]
  155. public function editPrompt(array $prompt): void
  156. {
  157. Notification::make()
  158. ->title('编辑提示词:' . $prompt['template_name'])
  159. ->body('打开编辑表单')
  160. ->info()
  161. ->send();
  162. }
  163. /**
  164. * 删除提示词
  165. */
  166. #[On('delete-prompt')]
  167. public function deletePrompt(string $promptName): void
  168. {
  169. Notification::make()
  170. ->title('删除提示词:' . $promptName)
  171. ->body('此操作不可恢复')
  172. ->danger()
  173. ->send();
  174. }
  175. /**
  176. * 启用/禁用提示词
  177. */
  178. #[On('toggle-prompt')]
  179. public function togglePrompt(string $promptName, bool $isActive): void
  180. {
  181. $status = $isActive ? '禁用' : '启用';
  182. Notification::make()
  183. ->title($status . '提示词:' . $promptName)
  184. ->success()
  185. ->send();
  186. }
  187. /**
  188. * 复制提示词
  189. */
  190. #[On('duplicate-prompt')]
  191. public function duplicatePrompt(array $prompt): void
  192. {
  193. Notification::make()
  194. ->title('复制提示词:' . $prompt['template_name'])
  195. ->success()
  196. ->send();
  197. }
  198. /**
  199. * 刷新数据
  200. */
  201. #[On('refresh-prompts')]
  202. public function refreshPrompts(): void
  203. {
  204. Notification::make()
  205. ->title('数据已刷新')
  206. ->success()
  207. ->send();
  208. }
  209. /**
  210. * 头部操作
  211. */
  212. protected function getHeaderActions(): array
  213. {
  214. return [
  215. Actions\Action::make('create')
  216. ->label('新建提示词')
  217. ->icon('heroicon-m-plus')
  218. ->color('success')
  219. ->action('createPrompt'),
  220. Actions\Action::make('refresh')
  221. ->label('刷新')
  222. ->icon('heroicon-m-arrow-path')
  223. ->color('warning')
  224. ->action('refreshPrompts'),
  225. ];
  226. }
  227. }