| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- {% extends "layout.html" %}
- {% block page_title %}题目详情 - {{ q.question_code }}{% endblock %}
- {% block header_actions %}
- <div class="flex items-center gap-4">
- <div class="text-sm font-medium text-gray-500">第 {{ curr_num }} / {{ total }} 题</div>
- <div class="flex items-center gap-2">
- {% if prev_code %}
- <a href="/detail/{{ prev_code }}" class="p-2 hover:bg-gray-100 rounded-lg transition-colors">
- <i class="ri-arrow-left-line text-gray-600"></i>
- </a>
- {% endif %}
- {% if next_code %}
- <a href="/detail/{{ next_code }}" id="next-btn" class="p-2 hover:bg-gray-100 rounded-lg transition-colors">
- <i class="ri-arrow-right-line text-gray-600"></i>
- </a>
- {% endif %}
- </div>
- </div>
- {% endblock %}
- {% block content %}
- <div class="mb-8 no-print flex items-center justify-between">
- <div class="flex items-center gap-4">
- {% if kp_code %}
- <a href="/question_management?kp_code={{ kp_code }}" class="text-blue-600 font-medium hover:underline">← 返回列表</a>
- {% elif node_id %}
- <a href="/textbook/{{ node_id }}" class="text-blue-600 font-medium hover:underline">← 返回列表</a>
- <a href="/#textbook-{{ node_id }}" class="text-blue-600 font-medium hover:underline">← 返回教材库</a>
- {% else %}
- <a href="javascript:history.back()" class="text-blue-600 font-medium hover:underline">← 返回上一页</a>
- {% endif %}
- </div>
- {% if add_question_url %}
- <a href="{{ add_question_url }}" id="continue-add-btn" class="btn-apple bg-gradient-to-r from-blue-600 to-indigo-600 text-white hover:from-blue-700 hover:to-indigo-700 text-sm py-2 px-4 shadow-lg shadow-blue-200">
- ➕ 继续录题 <span class="text-xs opacity-75 ml-1">(R)</span>
- </a>
- {% endif %}
- </div>
- <div class="grid grid-cols-1 gap-8">
- <!-- 题目卡片 -->
- <div class="apple-card p-10">
- <div class="flex items-center justify-between mb-8">
- <div class="space-y-1">
- <span class="text-xs font-bold text-gray-400 uppercase tracking-widest">Question Details</span>
- <div class="flex items-center gap-3">
- <h2 class="text-2xl font-bold">{{ q.question_code }}</h2>
- {% if q.difficulty is not none %}
- {% set diff = q.difficulty %}
- {% if (diff | float) == 0.2 or (diff | string) == '0.2' %}
- <span class="px-3 py-1 rounded-full text-xs font-bold bg-green-100 text-green-700 border border-green-200">筑基</span>
- {% elif (diff | float) == 0.4 or (diff | string) == '0.4' %}
- <span class="px-3 py-1 rounded-full text-xs font-bold bg-yellow-100 text-yellow-700 border border-yellow-200">提分</span>
- {% elif (diff | float) == 0.7 or (diff | string) == '0.7' %}
- <span class="px-3 py-1 rounded-full text-xs font-bold bg-orange-100 text-orange-700 border border-orange-200">培优</span>
- {% endif %}
- {% endif %}
- </div>
- {% set pk = (q.get('id') or q.get('question_id') or q.get('pk_id') or q.get('qid')) %}
- {% if pk %}
- <div class="text-xs text-gray-400 font-mono">主键ID: {{ pk }}</div>
- {% endif %}
- </div>
- <div class="flex items-center space-x-4 no-print">
- <a href="/edit/{{ q.question_code }}" class="btn-apple bg-gradient-to-r from-blue-500 to-blue-600 text-white hover:from-blue-600 hover:to-blue-700 shadow-lg shadow-blue-200 flex items-center gap-2 px-4 py-2.5">
- <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
- </svg>
- <span>编辑题目</span>
- </a>
- <a href="/export_pdf_remote/{{ q.question_code }}" target="_blank" class="btn-apple bg-gradient-to-r from-slate-500 to-slate-600 text-white hover:from-slate-600 hover:to-slate-700 shadow-lg shadow-slate-200 flex items-center gap-2 px-4 py-2.5">
- <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/>
- </svg>
- <span>导出 PDF</span>
- </a>
- <button onclick="deleteQuestion('{{ q.question_code }}')" class="btn-apple bg-gradient-to-r from-red-500 to-red-600 text-white hover:from-red-600 hover:to-red-700 shadow-lg shadow-red-200 flex items-center gap-2 px-4 py-2.5">
- <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
- </svg>
- <span>删除题目</span>
- </button>
- </div>
- </div>
- <div class="space-y-12">
- <!-- 题干 -->
- <section>
- <h4 class="text-sm font-bold text-gray-400 mb-4 uppercase">题干</h4>
- <div id="stem-container" class="text-xl leading-relaxed text-gray-800 math-render bg-gray-50/50 rounded-xl p-6 border border-gray-100">
- {{ q.stem | safe }}
- </div>
- </section>
- <!-- 选项 -->
- {% if options %}
- <section>
- <h4 class="text-sm font-bold text-gray-400 mb-4 uppercase">选项</h4>
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
- {% for k, v in options %}
- <div class="p-4 rounded-xl border border-gray-100 bg-gray-50/50 flex items-start space-x-4">
- <span class="bg-white w-8 h-8 rounded-full flex items-center justify-center font-bold text-blue-600 shadow-sm border border-gray-100">{{ k }}</span>
- <div class="math-render pt-0.5">{{ v }}</div>
- </div>
- {% endfor %}
- </div>
- </section>
- {% endif %}
- <!-- 答案与解析 -->
- <section class="pt-8 border-t border-gray-100">
- <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
- <div>
- <h4 class="text-sm font-bold text-gray-400 mb-4 uppercase">正确答案</h4>
- <div class="text-lg font-bold text-green-600 bg-green-50 px-6 py-4 rounded-2xl inline-block math-render">
- {{ q.answer }}
- </div>
- </div>
- <div>
- <h4 class="text-sm font-bold text-gray-400 mb-4 uppercase">解析</h4>
- <div class="text-gray-600 leading-relaxed math-render">
- {{ q.solution | safe }}
- </div>
- </div>
- </div>
- </section>
- </div>
- </div>
- <!-- 审核控制台 (固定在底部) -->
- <div class="no-print fixed bottom-8 left-1/2 -translate-x-1/2 w-full max-w-2xl px-6">
- <div class="bg-white/90 backdrop-blur-2xl p-4 rounded-3xl shadow-2xl border border-white/20 flex items-center justify-between">
- <div class="flex items-center space-x-4 ml-2">
- <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center">
- <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
- </div>
- <div class="text-sm">
- <div class="font-bold">审核状态: {{ q.audit_reason or '待处理' }}</div>
- <div class="text-gray-400 text-xs">{{ q.kp_code }}</div>
- </div>
- </div>
- <div class="flex items-center space-x-3">
- <button onclick="postAudit('{{ q.question_code }}', '不合格')" class="btn-apple bg-red-50 text-red-600 hover:bg-red-100">❌ 判定不合格</button>
- <button onclick="postAudit('{{ q.question_code }}', '合格')" class="btn-apple bg-blue-600 text-white hover:bg-blue-700 shadow-xl shadow-blue-200">✅ 判定合格</button>
- </div>
- </div>
- </div>
- </div>
- <script>
- const QUESTION_CODE = "{{ q.question_code }}";
-
- // 键盘快捷键:Q 判定不合格,E 判定合格,R 继续录题
- document.addEventListener('keydown', function(e) {
- // 如果焦点在输入框、文本域等可输入元素上,不触发快捷键
- if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) {
- return;
- }
-
- // Q 键:判定不合格
- if (e.key === 'q' || e.key === 'Q') {
- e.preventDefault();
- postAudit(QUESTION_CODE, '不合格');
- }
-
- // E 键:判定合格
- if (e.key === 'e' || e.key === 'E') {
- e.preventDefault();
- postAudit(QUESTION_CODE, '合格');
- }
-
- // R 键:继续录题
- if ((e.key === 'r' || e.key === 'R') && document.getElementById('continue-add-btn')) {
- e.preventDefault();
- document.getElementById('continue-add-btn').click();
- }
- });
- // 优化题干显示:自动渲染数学公式
- function renderMathInStem() {
- const stemContainer = document.getElementById("stem-container");
- if (stemContainer && window.renderMathInElement) {
- try {
- window.renderMathInElement(stemContainer, {
- delimiters: [
- {left: "$$", right: "$$", display: true},
- {left: "$", right: "$", display: false},
- {left: "\\(", right: "\\)", display: false},
- {left: "\\[", right: "\\]", display: true}
- ],
- throwOnError: false
- });
- } catch (e) {
- // 渲染失败不阻塞功能
- console.warn("数学公式渲染失败:", e);
- }
- }
- }
- // 页面加载完成后自动渲染题干中的数学公式
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', renderMathInStem);
- } else {
- // DOM已经加载完成,立即执行
- renderMathInStem();
- }
- function deleteQuestion(questionCode) {
- if (!confirm(`确定要删除题目 ${questionCode} 吗?\n\n此操作不可恢复!`)) {
- return;
- }
- fetch(`/api/delete_question/${encodeURIComponent(questionCode)}`, {
- method: "POST",
- headers: {"Content-Type": "application/json"}
- }).then(r => r.json()).then(data => {
- if (!data || !data.success) {
- throw new Error((data && data.error) ? data.error : "未知错误");
- }
- // 优先跳转到下一题,没有则上一题,都没有则返回上一页
- if (data.next_code) {
- window.location.href = `/detail/${data.next_code}`;
- } else if (data.prev_code) {
- window.location.href = `/detail/${data.prev_code}`;
- } else if (data.kp_code) {
- window.location.href = `/questions/${data.kp_code}`;
- } else if (data.node_id) {
- window.location.href = `/textbook/${data.node_id}`;
- } else {
- window.history.back();
- }
- }).catch(err => {
- if (window.customAlert) {
- window.customAlert("删除失败:" + (err && err.message ? err.message : String(err)));
- } else {
- alert("删除失败:" + (err && err.message ? err.message : String(err)));
- }
- });
- }
- </script>
- {% endblock %}
|