|
|
@@ -9,6 +9,7 @@ use App\Services\QuestionBankService;
|
|
|
use App\Services\QuestionPayloadMapper;
|
|
|
use App\Services\TaskManager;
|
|
|
use App\Services\WrongQuestionPracticePlanService;
|
|
|
+use App\Support\AssembleType;
|
|
|
use Illuminate\Bus\Queueable;
|
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
|
@@ -54,7 +55,8 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
try {
|
|
|
$taskManager->updateTaskProgress($this->taskId, 5, '开始异步组卷...');
|
|
|
|
|
|
- $assembleType = (int) ($data['assemble_type'] ?? 4);
|
|
|
+ $requestedAssembleType = (int) ($data['assemble_type'] ?? 4);
|
|
|
+ $strategyAssembleType = AssembleType::toStrategyType($requestedAssembleType);
|
|
|
$difficultyCategory = $data['difficulty_category'] ?? 1;
|
|
|
$paperName = $data['paper_name'] ?? ('智能试卷_'.now()->format('Ymd_His'));
|
|
|
$mistakeIds = $data['mistake_ids'] ?? [];
|
|
|
@@ -68,16 +70,16 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
$explanationKpCodes = null;
|
|
|
$wrongQuestionPracticePlan = null;
|
|
|
|
|
|
- if (in_array($assembleType, [15, 16], true)) {
|
|
|
+ if (in_array($requestedAssembleType, [15, 16], true)) {
|
|
|
// assemble_type=15(错题再练):paper_ids 为题库 question_id,直组原错题。
|
|
|
// assemble_type=16(错题追练):paper_ids 仍为题库 question_id,但只用来生成知识点组卷计划。
|
|
|
$questionIdList = $this->normalizeBankQuestionIdsList($paperIds);
|
|
|
if ($questionIdList === []) {
|
|
|
- $taskManager->markTaskFailed($this->taskId, ($assembleType === 16 ? '错题追练' : '错题再练').'组卷需提供 paper_ids(题库题目 id)');
|
|
|
+ $taskManager->markTaskFailed($this->taskId, ($requestedAssembleType === 16 ? '错题追练' : '错题再练').'组卷需提供 paper_ids(题库题目 id)');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if ($assembleType === 16) {
|
|
|
+ if ($requestedAssembleType === 16) {
|
|
|
$wrongQuestionPracticePlan = $wrongQuestionPracticePlanService->build(
|
|
|
(string) $data['student_id'],
|
|
|
$questionIdList,
|
|
|
@@ -153,7 +155,7 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
}
|
|
|
} elseif (! empty($mistakeIds) || ! empty($mistakeQuestionIds)) {
|
|
|
// assemble_type=5 时 mistake_ids / mistake_question_ids 须严格归属该学生;其它类型走宽松解析。
|
|
|
- if ($assembleType === 5) {
|
|
|
+ if ($requestedAssembleType === 5) {
|
|
|
$strict = $this->resolveMistakeQuestionIdsStrictForStudent(
|
|
|
(string) $data['student_id'],
|
|
|
$mistakeIds,
|
|
|
@@ -187,17 +189,17 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
'student_id' => $data['student_id'],
|
|
|
'grade' => $data['grade'] ?? null,
|
|
|
'total_questions' => $data['total_questions'],
|
|
|
- 'kp_codes' => $assembleType === 3 ? null : ($data['kp_codes'] ?? null),
|
|
|
+ 'kp_codes' => $strategyAssembleType === 3 ? null : ($data['kp_codes'] ?? null),
|
|
|
'skills' => $data['skills'] ?? [],
|
|
|
'question_type_ratio' => $questionTypeRatio,
|
|
|
'difficulty_category' => $difficultyCategory,
|
|
|
- 'assemble_type' => $assembleType,
|
|
|
+ 'assemble_type' => $strategyAssembleType,
|
|
|
'exam_type' => $data['exam_type'] ?? 'general',
|
|
|
'paper_ids' => $paperIds,
|
|
|
'textbook_id' => $data['textbook_id'] ?? null,
|
|
|
'end_catalog_id' => $data['end_catalog_id'] ?? null,
|
|
|
'chapter_id_list' => $data['chapter_id_list'] ?? null,
|
|
|
- 'kp_code_list' => $assembleType === 3 ? null : ($data['kp_code_list'] ?? $data['kp_codes'] ?? []),
|
|
|
+ 'kp_code_list' => $strategyAssembleType === 3 ? null : ($data['kp_code_list'] ?? $data['kp_codes'] ?? []),
|
|
|
'practice_options' => $data['practice_options'] ?? null,
|
|
|
'mistake_options' => $data['mistake_options'] ?? null,
|
|
|
];
|
|
|
@@ -219,7 +221,8 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
'task_id' => $this->taskId,
|
|
|
'phase' => 'select_and_prepare_questions',
|
|
|
'elapsed_ms' => (int) round((microtime(true) - $phaseStartedAt) * 1000),
|
|
|
- 'assemble_type' => $assembleType,
|
|
|
+ 'assemble_type' => $requestedAssembleType,
|
|
|
+ 'strategy_assemble_type' => $strategyAssembleType,
|
|
|
'question_count' => count($questions),
|
|
|
]);
|
|
|
|
|
|
@@ -235,7 +238,12 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
$questions = $this->adjustQuestionScores($questions, $targetTotalScore);
|
|
|
$totalScore = array_sum(array_column($questions, 'score'));
|
|
|
|
|
|
- $finalAssembleType = ($result !== null && isset($result['assemble_type'])) ? $result['assemble_type'] : $assembleType;
|
|
|
+ $finalAssembleType = ($result !== null && isset($result['assemble_type']))
|
|
|
+ ? (int) $result['assemble_type']
|
|
|
+ : $requestedAssembleType;
|
|
|
+ if (in_array($requestedAssembleType, [11, 12, 13], true)) {
|
|
|
+ $finalAssembleType = $requestedAssembleType;
|
|
|
+ }
|
|
|
if ($finalAssembleType === 16) {
|
|
|
$difficultyCategory = $this->deriveDifficultyCategoryFromSelectedDistribution($questions);
|
|
|
}
|
|
|
@@ -268,7 +276,7 @@ class AssembleExamTaskJob implements ShouldQueue
|
|
|
|
|
|
$finalStats = $result['stats'] ?? [
|
|
|
'total_selected' => count($questions),
|
|
|
- 'mistake_based' => ! empty($mistakeIds) || ! empty($mistakeQuestionIds) || in_array($assembleType, [15, 16], true),
|
|
|
+ 'mistake_based' => ! empty($mistakeIds) || ! empty($mistakeQuestionIds) || in_array($requestedAssembleType, [15, 16], true),
|
|
|
];
|
|
|
if ($wrongQuestionPracticePlan !== null) {
|
|
|
$finalStats['wrong_question_practice_plan'] = $wrongQuestionPracticePlan;
|