| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <?php
- namespace App\Services;
- use App\Http\Controllers\ExamPdfController;
- use App\Models\Paper;
- use App\Models\PaperQuestion;
- use App\Models\User;
- use Illuminate\Support\Facades\Auth;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Schema;
- use Illuminate\Support\Str;
- /**
- * 待入库题目加入组卷队列(不写 questions 表),生成临时试卷以走判卷 PDF 链路验版式
- */
- class QuestionsTemAssemblyService
- {
- public function tableExists(): bool
- {
- return Schema::hasTable('questions_tem_assembly_queue');
- }
- public function queueForUser(int $userId): array
- {
- if (! $this->tableExists() || ! Schema::hasTable('questions_tem')) {
- return [];
- }
- $rows = DB::table('questions_tem as q')
- ->join('questions_tem_assembly_queue as aq', 'q.id', '=', 'aq.questions_tem_id')
- ->where('aq.user_id', $userId)
- ->orderBy('aq.sort_order')
- ->orderBy('aq.id')
- ->select('q.*')
- ->get();
- return $rows->all();
- }
- public function add(int $userId, int $temId): void
- {
- if (! $this->tableExists() || ! Schema::hasTable('questions_tem')) {
- return;
- }
- if (! DB::table('questions_tem')->where('id', $temId)->exists()) {
- return;
- }
- if (DB::table('questions_tem_assembly_queue')
- ->where('user_id', $userId)
- ->where('questions_tem_id', $temId)
- ->exists()) {
- return;
- }
- $max = (int) DB::table('questions_tem_assembly_queue')->where('user_id', $userId)->max('sort_order');
- DB::table('questions_tem_assembly_queue')->insert([
- 'user_id' => $userId,
- 'questions_tem_id' => $temId,
- 'sort_order' => $max + 1,
- 'created_at' => now(),
- 'updated_at' => now(),
- ]);
- }
- public function remove(int $userId, int $temId): void
- {
- if (! $this->tableExists()) {
- return;
- }
- DB::table('questions_tem_assembly_queue')
- ->where('user_id', $userId)
- ->where('questions_tem_id', $temId)
- ->delete();
- }
- public function clear(int $userId): void
- {
- if (! $this->tableExists()) {
- return;
- }
- DB::table('questions_tem_assembly_queue')->where('user_id', $userId)->delete();
- }
- /**
- * 创建临时试卷并写入 paper_questions(question_bank_id 为负 tem id,判卷页会从 questions_tem 还原选项)
- */
- public function createTrialPaperForQueue(int $userId): ?string
- {
- $rows = $this->queueForUser($userId);
- if ($rows === []) {
- return null;
- }
- $user = User::query()->find($userId);
- $studentKey = (string) ($user?->username ?? 'preview');
- $teacherKey = (string) ($user?->username ?? 'preview');
- $paperId = 'TEMQ-'.Str::upper(Str::random(12));
- $pdf = app(ExamPdfController::class);
- $questionsData = $pdf->prepareQuestionsDataFromTemRows($rows);
- $grouped = $pdf->buildGroupedQuestionsForPaperBody($questionsData, null);
- $order = 1;
- $totalScore = 0.0;
- $flat = array_merge($grouped['choice'], $grouped['fill'], $grouped['answer']);
- usort($flat, fn ($a, $b) => ($a->question_number ?? 0) <=> ($b->question_number ?? 0));
- foreach ($flat as $obj) {
- $totalScore += (float) ($obj->score ?? 5);
- }
- Paper::query()->create([
- 'paper_id' => $paperId,
- 'student_id' => (string) $studentKey,
- 'teacher_id' => (string) $teacherKey,
- 'paper_name' => '待入库组卷验真',
- 'paper_type' => 0,
- 'total_questions' => count($flat),
- 'total_score' => $totalScore,
- 'status' => 'tem_preview',
- 'difficulty_category' => '中等',
- ]);
- foreach ($flat as $obj) {
- $type = (string) ($obj->question_type ?? 'answer');
- $stem = (string) ($obj->stem ?? $obj->content ?? '');
- $bankId = (int) ($obj->id ?? 0);
- PaperQuestion::query()->create([
- 'paper_id' => $paperId,
- 'question_bank_id' => $bankId,
- 'question_id' => 'tem-'.$order,
- 'knowledge_point' => (string) ($obj->kp_code ?? ''),
- 'question_type' => $type,
- 'question_text' => $stem,
- 'correct_answer' => (string) ($obj->answer ?? ''),
- 'solution' => (string) ($obj->solution ?? ''),
- 'difficulty' => (float) ($obj->difficulty ?? 0.5),
- 'score' => (float) ($obj->score ?? 5),
- 'question_number' => (int) ($obj->question_number ?? $order),
- ]);
- $order++;
- }
- return $paperId;
- }
- public static function currentUserId(): ?int
- {
- $u = Auth::user();
- if ($u instanceof User) {
- return (int) $u->id;
- }
- return null;
- }
- }
|