| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <?php
- namespace App\Console\Commands;
- use App\Services\QuestionQualityCheckService;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Schema;
- class RunQuestionQualityCheckCommand extends Command
- {
- protected $signature = 'question:qc
- {--table=question_tem : 待质检题目表名}
- {--kp= : 指定知识点,不传则按下学期题少 KP 筛选}
- {--limit=100 : 质检题目数量上限}
- {--textbook= : 教材 ID}
- {--semester=2 : 学期 1=上 2=下}
- {--dry-run : 仅输出筛选结果,不执行质检}';
- protected $description = '题目自动质检:从 question_tem 按下学期题少 KP 筛选题目并执行校验';
- public function handle(QuestionQualityCheckService $qcService): int
- {
- $table = $this->option('table');
- if (! Schema::hasTable($table)) {
- $this->error("表 {$table} 不存在,请先创建或指定正确表名");
- return 1;
- }
- $kp = $this->option('kp');
- $limit = (int) $this->option('limit');
- $dryRun = $this->option('dry-run');
- if ($kp) {
- $questions = DB::table($table)
- ->where('kp_code', $kp)
- ->limit($limit)
- ->get();
- } else {
- $kps = $qcService->getKpsWithFewQuestions(
- $this->option('textbook') ? (int) $this->option('textbook') : null,
- (int) $this->option('semester'),
- 20
- );
- if (empty($kps)) {
- $this->warn('未找到题少的 KP,请检查 textbooks、textbook_chapter_knowledge_relation 数据');
- return 0;
- }
- $this->info('按下学期题少 KP 筛选,前 5 个:');
- foreach (array_slice($kps, 0, 5) as $r) {
- $this->line(" {$r['kp_code']}: {$r['question_count']} 题");
- }
- $kpCodes = array_column($kps, 'kp_code');
- $questions = DB::table($table)
- ->whereIn('kp_code', $kpCodes)
- ->limit($limit)
- ->get();
- }
- $total = $questions->count();
- $this->info("待质检题目数: {$total}");
- if ($dryRun) {
- $this->info('[dry-run] 不执行质检');
- return 0;
- }
- $passed = 0;
- $failed = 0;
- $bar = $this->output->createProgressBar($total);
- $bar->start();
- foreach ($questions as $q) {
- $row = (array) $q;
- $mapped = $this->mapQuestionRow($row);
- $result = $qcService->runAutoCheck(
- $mapped,
- $row['id'] ?? null,
- null
- );
- if ($result['passed']) {
- $passed++;
- } else {
- $failed++;
- $this->newLine();
- $this->warn(" [{$row['id']}] " . implode(', ', $result['errors']));
- }
- $bar->advance();
- }
- $bar->finish();
- $this->newLine(2);
- $this->info("质检完成: 通过 {$passed},未通过 {$failed}");
- return 0;
- }
- /**
- * 将 question_tem 行映射为质检服务所需格式
- */
- private function mapQuestionRow(array $row): array
- {
- return [
- 'stem' => $row['stem'] ?? $row['content'] ?? '',
- 'answer' => $row['answer'] ?? $row['correct_answer'] ?? '',
- 'solution' => $row['solution'] ?? '',
- 'question_type' => $row['question_type'] ?? $row['tags'] ?? '',
- 'options' => is_string($row['options'] ?? null)
- ? json_decode($row['options'], true)
- : ($row['options'] ?? null),
- ];
- }
- }
|