| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <?php
- namespace App\Filament\Resources\PreQuestionCandidateResource\Actions;
- use App\Models\MarkdownImport;
- use App\Models\PreQuestion;
- use App\Services\Storage\ChunsunUploader;
- use Filament\Actions\BulkAction;
- use Filament\Facades\Filament;
- use Illuminate\Database\Eloquent\Collection;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- class ConvertToPreQuestionsBulkAction extends BulkAction
- {
- public function getName(): string
- {
- return 'convert_to_pre_questions';
- }
- protected function setUp(): void
- {
- parent::setUp();
- $this->label('入库到筛选库');
- $this->color('primary');
- $this->icon('heroicon-o-arrow-down-tray');
- $this->requiresConfirmation();
- $this->modalHeading('入库到筛选库');
- $this->modalDescription('将选中的候选题转换为正式题目并上传图片到春笋云。此操作不可撤销。');
- $this->action(function (Collection $records) {
- $this->convertToPreQuestions($records);
- });
- }
- /**
- * 转换候选题为正式题目
- */
- private function convertToPreQuestions(Collection $records): void
- {
- try {
- DB::beginTransaction();
- $uploader = app(ChunsunUploader::class);
- $processedCount = 0;
- $errorCount = 0;
- foreach ($records as $record) {
- if (!$record->is_question_candidate) {
- continue; // 跳过非题目
- }
- try {
- // 处理图片上传
- $uploadedImages = [];
- if (!empty($record->images)) {
- $images = is_string($record->images) ? json_decode($record->images, true) : $record->images;
- $uploadedImages = $uploader->uploadImagesFromArray($images);
- }
- // 创建 pre_question 记录
- PreQuestion::create([
- 'candidate_id' => $record->id,
- 'import_id' => $record->import_id,
- 'sequence' => $record->sequence,
- 'index' => $record->index,
- 'raw_markdown' => $record->raw_markdown,
- 'stem' => $record->stem ?: $record->raw_markdown,
- 'options' => $record->options,
- 'images' => $uploadedImages,
- 'tables' => $record->tables,
- 'source' => $this->getSourceArray($record->import_id),
- ]);
- // 更新候选题状态
- $record->update([
- 'status' => 'accepted',
- ]);
- $processedCount++;
- } catch (\Exception $e) {
- Log::error('Failed to convert candidate to pre_question', [
- 'candidate_id' => $record->id,
- 'error' => $e->getMessage(),
- ]);
- $errorCount++;
- }
- }
- // 更新 markdown_imports 状态
- if ($records->isNotEmpty()) {
- $importId = $records->first()->import_id;
- $import = MarkdownImport::find($importId);
- if ($import) {
- $import->update([
- 'status' => 'completed',
- 'progress_stage' => MarkdownImport::STAGE_COMPLETED,
- 'progress_message' => "已入库 {$processedCount} 题",
- 'progress_current' => $processedCount,
- 'progress_total' => $processedCount,
- 'progress_updated_at' => now(),
- 'processing_finished_at' => now(),
- ]);
- }
- }
- DB::commit();
- // 显示结果
- if ($processedCount > 0) {
- Filament::notify('success', "成功入库 {$processedCount} 个题目");
- if ($errorCount > 0) {
- Filament::notify('warning', "其中 {$errorCount} 个题目入库失败,请查看日志");
- }
- } else {
- Filament::notify('warning', '没有找到可入库的题目');
- }
- } catch (\Exception $e) {
- DB::rollBack();
- Log::error('Batch convert failed', [
- 'error' => $e->getMessage(),
- ]);
- Filament::notify('danger', '入库失败:' . $e->getMessage());
- }
- }
- /**
- * 获取来源数组
- */
- private function getSourceArray(int $importId): array
- {
- $import = MarkdownImport::find($importId);
- if (!$import || !$import->source_name) {
- return ['Markdown导入'];
- }
- return [$import->source_name];
- }
- }
|