style: format QuestionVariant.vue
This commit is contained in:
parent
9204349041
commit
22c2a19475
|
|
@ -81,11 +81,13 @@ const variantQuestions = computed(() => {
|
||||||
function extractOptions(text) {
|
function extractOptions(text) {
|
||||||
const options = [];
|
const options = [];
|
||||||
// 匹配题目内容中的选项 A. xxx B. xxx C. xxx D. xxx
|
// 匹配题目内容中的选项 A. xxx B. xxx C. xxx D. xxx
|
||||||
const contentMatch = text.match(/\*\*题目内容\*\*[::]\s*([\s\S]*?)(?=\*\*正确答案\*\*|$)/i);
|
const contentMatch = text.match(
|
||||||
|
/\*\*题目内容\*\*[::]\s*([\s\S]*?)(?=\*\*正确答案\*\*|$)/i
|
||||||
|
);
|
||||||
if (!contentMatch) return options;
|
if (!contentMatch) return options;
|
||||||
|
|
||||||
const contentBlock = contentMatch[1];
|
const contentBlock = contentMatch[1];
|
||||||
const lines = contentBlock.split('\n');
|
const lines = contentBlock.split("\n");
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const match = line.match(/^([A-D])[\..。::]\s*(.+)$/i);
|
const match = line.match(/^([A-D])[\..。::]\s*(.+)$/i);
|
||||||
|
|
@ -102,7 +104,10 @@ function extractOptions(text) {
|
||||||
|
|
||||||
// ── 提取字段值 ──
|
// ── 提取字段值 ──
|
||||||
function extractField(text, fieldName) {
|
function extractField(text, fieldName) {
|
||||||
const regex = new RegExp(`\\*\\*${fieldName}\\*\\*[::]\\s*([\\s\\S]*?)(?=\\n\\*\\*|$)`, "i");
|
const regex = new RegExp(
|
||||||
|
`\\*\\*${fieldName}\\*\\*[::]\\s*([\\s\\S]*?)(?=\\n\\*\\*|$)`,
|
||||||
|
"i"
|
||||||
|
);
|
||||||
const match = text.match(regex);
|
const match = text.match(regex);
|
||||||
return match ? match[1].trim() : "";
|
return match ? match[1].trim() : "";
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +120,7 @@ const buildRequestBody = () => {
|
||||||
{ role: "system", content: QUESTION_VARIANT_PROMPT },
|
{ role: "system", content: QUESTION_VARIANT_PROMPT },
|
||||||
{
|
{
|
||||||
role: "user",
|
role: "user",
|
||||||
content: `请分析以下试题,并生成 ${variantCount.value} 道变式题:\n\n${textInput.value}`
|
content: `请分析以下试题,并生成 ${variantCount.value} 道变式题:\n\n${textInput.value}`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
temperature: VARIANT_TEMPERATURE,
|
temperature: VARIANT_TEMPERATURE,
|
||||||
|
|
@ -221,11 +226,11 @@ const renderContent = (text) => {
|
||||||
// ── 难度颜色映射 ──
|
// ── 难度颜色映射 ──
|
||||||
const getDifficultyColor = (difficulty) => {
|
const getDifficultyColor = (difficulty) => {
|
||||||
const colors = {
|
const colors = {
|
||||||
"容易": "#10b981",
|
容易: "#10b981",
|
||||||
"较易": "#34d399",
|
较易: "#34d399",
|
||||||
"适中": "#f59e0b",
|
适中: "#f59e0b",
|
||||||
"较难": "#f97316",
|
较难: "#f97316",
|
||||||
"困难": "#ef4444",
|
困难: "#ef4444",
|
||||||
};
|
};
|
||||||
return colors[difficulty] || "#6366f1";
|
return colors[difficulty] || "#6366f1";
|
||||||
};
|
};
|
||||||
|
|
@ -243,7 +248,16 @@ onUnmounted(() => {
|
||||||
<!-- Nav Bar -->
|
<!-- Nav Bar -->
|
||||||
<div class="nav-bar">
|
<div class="nav-bar">
|
||||||
<button class="back-btn" @click="goBack">
|
<button class="back-btn" @click="goBack">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2.2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<polyline points="15 18 9 12 15 6" />
|
<polyline points="15 18 9 12 15 6" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>返回</span>
|
<span>返回</span>
|
||||||
|
|
@ -265,8 +279,19 @@ onUnmounted(() => {
|
||||||
<div class="input-card">
|
<div class="input-card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="header-icon">
|
<div class="header-icon">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
|
||||||
|
/>
|
||||||
<polyline points="14 2 14 8 20 8" />
|
<polyline points="14 2 14 8 20 8" />
|
||||||
<line x1="16" y1="13" x2="8" y2="13" />
|
<line x1="16" y1="13" x2="8" y2="13" />
|
||||||
<line x1="16" y1="17" x2="8" y2="17" />
|
<line x1="16" y1="17" x2="8" y2="17" />
|
||||||
|
|
@ -277,7 +302,13 @@ onUnmounted(() => {
|
||||||
|
|
||||||
<div class="input-content">
|
<div class="input-content">
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<button class="example-btn" @click="textInput = 'He ______ to school every day.\nA. go B. goes C. going D. went\n\n请选择正确答案。'">
|
<button
|
||||||
|
class="example-btn"
|
||||||
|
@click="
|
||||||
|
textInput =
|
||||||
|
'He ______ to school every day.\nA. go B. goes C. going D. went。'
|
||||||
|
"
|
||||||
|
>
|
||||||
示例试题
|
示例试题
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -296,9 +327,20 @@ onUnmounted(() => {
|
||||||
<div class="config-card">
|
<div class="config-card">
|
||||||
<div class="config-header">
|
<div class="config-header">
|
||||||
<div class="header-icon">
|
<div class="header-icon">
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<circle cx="12" cy="12" r="3" />
|
<circle cx="12" cy="12" r="3" />
|
||||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
<path
|
||||||
|
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="header-title">生成配置</h2>
|
<h2 class="header-title">生成配置</h2>
|
||||||
|
|
@ -331,16 +373,21 @@ onUnmounted(() => {
|
||||||
:disabled="!canGenerate"
|
:disabled="!canGenerate"
|
||||||
@click="startGeneration"
|
@click="startGeneration"
|
||||||
>
|
>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>生成变式题</span>
|
<span>生成变式题</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button v-else class="cancel-btn" @click="cancelGeneration">
|
||||||
v-else
|
|
||||||
class="cancel-btn"
|
|
||||||
@click="cancelGeneration"
|
|
||||||
>
|
|
||||||
<span class="btn-spinner"></span>
|
<span class="btn-spinner"></span>
|
||||||
<span>生成中,点击取消</span>
|
<span>生成中,点击取消</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -359,16 +406,30 @@ onUnmounted(() => {
|
||||||
<!-- Empty State -->
|
<!-- Empty State -->
|
||||||
<div v-if="status === 'idle'" class="empty-state">
|
<div v-if="status === 'idle'" class="empty-state">
|
||||||
<div class="empty-icon">
|
<div class="empty-icon">
|
||||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="empty-title">等待生成</p>
|
<p class="empty-title">等待生成</p>
|
||||||
<p class="empty-hint">在左侧输入试题内容,选择数量后点击「生成变式题」</p>
|
<p class="empty-hint">
|
||||||
|
在左侧输入试题内容,选择数量后点击「生成变式题」
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Generating State -->
|
<!-- Generating State -->
|
||||||
<div v-else-if="status === 'generating' && !rawContent" class="empty-state loading-state">
|
<div
|
||||||
|
v-else-if="status === 'generating' && !rawContent"
|
||||||
|
class="empty-state loading-state"
|
||||||
|
>
|
||||||
<div class="loading-spinner">
|
<div class="loading-spinner">
|
||||||
<div class="spinner-ring"></div>
|
<div class="spinner-ring"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -377,18 +438,35 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Result Area -->
|
<!-- Result Area -->
|
||||||
<div v-else-if="status === 'generating' || status === 'done'" class="result-area">
|
<div
|
||||||
|
v-else-if="status === 'generating' || status === 'done'"
|
||||||
|
class="result-area"
|
||||||
|
>
|
||||||
<div class="result-header">
|
<div class="result-header">
|
||||||
<div class="result-title-wrap">
|
<div class="result-title-wrap">
|
||||||
<div class="result-dot" :class="{ pulse: status === 'generating' }"></div>
|
<div
|
||||||
<span class="result-title">{{ status === "generating" ? "AI 正在生成..." : "生成完成" }}</span>
|
class="result-dot"
|
||||||
|
:class="{ pulse: status === 'generating' }"
|
||||||
|
></div>
|
||||||
|
<span class="result-title">{{
|
||||||
|
status === "generating" ? "AI 正在生成..." : "生成完成"
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Original Analysis -->
|
<!-- Original Analysis -->
|
||||||
<div v-if="originalAnalysis" class="analysis-card">
|
<div v-if="originalAnalysis" class="analysis-card">
|
||||||
<div class="analysis-header">
|
<div class="analysis-header">
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<circle cx="11" cy="11" r="8" />
|
<circle cx="11" cy="11" r="8" />
|
||||||
<path d="m21 21-4.35-4.35" />
|
<path d="m21 21-4.35-4.35" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
@ -401,17 +479,26 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
<div class="analysis-item" v-if="originalAnalysis.knowledge">
|
<div class="analysis-item" v-if="originalAnalysis.knowledge">
|
||||||
<span class="analysis-label">考查知识点</span>
|
<span class="analysis-label">考查知识点</span>
|
||||||
<span class="analysis-value">{{ originalAnalysis.knowledge }}</span>
|
<span class="analysis-value">{{
|
||||||
|
originalAnalysis.knowledge
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="analysis-item" v-if="originalAnalysis.difficulty">
|
<div class="analysis-item" v-if="originalAnalysis.difficulty">
|
||||||
<span class="analysis-label">难度等级</span>
|
<span class="analysis-label">难度等级</span>
|
||||||
<span class="analysis-value" :style="{ color: getDifficultyColor(originalAnalysis.difficulty) }">
|
<span
|
||||||
|
class="analysis-value"
|
||||||
|
:style="{
|
||||||
|
color: getDifficultyColor(originalAnalysis.difficulty),
|
||||||
|
}"
|
||||||
|
>
|
||||||
{{ originalAnalysis.difficulty }}
|
{{ originalAnalysis.difficulty }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="analysis-item" v-if="originalAnalysis.features">
|
<div class="analysis-item" v-if="originalAnalysis.features">
|
||||||
<span class="analysis-label">题目特点</span>
|
<span class="analysis-label">题目特点</span>
|
||||||
<span class="analysis-value">{{ originalAnalysis.features }}</span>
|
<span class="analysis-value">{{
|
||||||
|
originalAnalysis.features
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -419,14 +506,28 @@ onUnmounted(() => {
|
||||||
<!-- Variant Questions -->
|
<!-- Variant Questions -->
|
||||||
<div class="variants-section">
|
<div class="variants-section">
|
||||||
<div class="variants-header">
|
<div class="variants-header">
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
width="18"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
|
||||||
|
/>
|
||||||
<polyline points="14 2 14 8 20 8" />
|
<polyline points="14 2 14 8 20 8" />
|
||||||
<line x1="16" y1="13" x2="8" y2="13" />
|
<line x1="16" y1="13" x2="8" y2="13" />
|
||||||
<line x1="16" y1="17" x2="8" y2="17" />
|
<line x1="16" y1="17" x2="8" y2="17" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>变式题目</span>
|
<span>变式题目</span>
|
||||||
<span class="variant-count-badge" v-if="variantQuestions.length > 0">
|
<span
|
||||||
|
class="variant-count-badge"
|
||||||
|
v-if="variantQuestions.length > 0"
|
||||||
|
>
|
||||||
已生成 {{ variantQuestions.length }} 题
|
已生成 {{ variantQuestions.length }} 题
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -442,13 +543,17 @@ onUnmounted(() => {
|
||||||
<span class="number-badge">第 {{ question.index }} 题</span>
|
<span class="number-badge">第 {{ question.index }} 题</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="question-tags">
|
<div class="question-tags">
|
||||||
<span class="tag type-tag">{{ question.type || "未知题型" }}</span>
|
<span class="tag type-tag">{{
|
||||||
|
question.type || "未知题型"
|
||||||
|
}}</span>
|
||||||
<span
|
<span
|
||||||
class="tag difficulty-tag"
|
class="tag difficulty-tag"
|
||||||
:style="{
|
:style="{
|
||||||
backgroundColor: getDifficultyColor(question.difficulty) + '18',
|
backgroundColor:
|
||||||
|
getDifficultyColor(question.difficulty) + '18',
|
||||||
color: getDifficultyColor(question.difficulty),
|
color: getDifficultyColor(question.difficulty),
|
||||||
borderColor: getDifficultyColor(question.difficulty) + '40'
|
borderColor:
|
||||||
|
getDifficultyColor(question.difficulty) + '40',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ question.difficulty || "未知难度" }}
|
{{ question.difficulty || "未知难度" }}
|
||||||
|
|
@ -458,25 +563,47 @@ onUnmounted(() => {
|
||||||
|
|
||||||
<div class="question-body">
|
<div class="question-body">
|
||||||
<!-- 题目内容 -->
|
<!-- 题目内容 -->
|
||||||
<div class="question-section content-section" v-if="question.content">
|
<div
|
||||||
|
class="question-section content-section"
|
||||||
|
v-if="question.content"
|
||||||
|
>
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<circle cx="12" cy="12" r="10" />
|
<circle cx="12" cy="12" r="10" />
|
||||||
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
|
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
|
||||||
<line x1="12" y1="17" x2="12.01" y2="17" />
|
<line x1="12" y1="17" x2="12.01" y2="17" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>题目内容</span>
|
<span>题目内容</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-content content-text" v-html="renderContent(question.content)"></div>
|
<div
|
||||||
|
class="section-content content-text"
|
||||||
|
v-html="renderContent(question.content)"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 选项网格 -->
|
<!-- 选项网格 -->
|
||||||
<div v-if="question.options && question.options.length > 0" class="options-grid">
|
<div
|
||||||
|
v-if="question.options && question.options.length > 0"
|
||||||
|
class="options-grid"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="opt in question.options"
|
v-for="opt in question.options"
|
||||||
:key="opt.label"
|
:key="opt.label"
|
||||||
class="option-item"
|
class="option-item"
|
||||||
:class="{ 'correct-option': question.answer && question.answer.toUpperCase().includes(opt.label) }"
|
:class="{
|
||||||
|
'correct-option':
|
||||||
|
question.answer &&
|
||||||
|
question.answer.toUpperCase().includes(opt.label),
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<span class="option-label">{{ opt.label }}.</span>
|
<span class="option-label">{{ opt.label }}.</span>
|
||||||
<span class="option-text">{{ opt.content }}</span>
|
<span class="option-text">{{ opt.content }}</span>
|
||||||
|
|
@ -484,35 +611,76 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 正确答案 -->
|
<!-- 正确答案 -->
|
||||||
<div class="question-section answer-section" v-if="question.answer">
|
<div
|
||||||
|
class="question-section answer-section"
|
||||||
|
v-if="question.answer"
|
||||||
|
>
|
||||||
<div class="answer-row">
|
<div class="answer-row">
|
||||||
<div class="answer-icon">
|
<div class="answer-icon">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<polyline points="20 6 9 17 4 12" />
|
<polyline points="20 6 9 17 4 12" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span class="answer-label">正确答案</span>
|
<span class="answer-label">正确答案</span>
|
||||||
<span class="answer-value" v-html="renderContent(question.answer)"></span>
|
<span
|
||||||
|
class="answer-value"
|
||||||
|
v-html="renderContent(question.answer)"
|
||||||
|
></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 详细解析 -->
|
<!-- 详细解析 -->
|
||||||
<div class="question-section explanation-section" v-if="question.explanation">
|
<div
|
||||||
|
class="question-section explanation-section"
|
||||||
|
v-if="question.explanation"
|
||||||
|
>
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
||||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>详细解析</span>
|
<span>详细解析</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-content explanation-text" v-html="renderContent(question.explanation)"></div>
|
<div
|
||||||
|
class="section-content explanation-text"
|
||||||
|
v-html="renderContent(question.explanation)"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 考查知识点 -->
|
<!-- 考查知识点 -->
|
||||||
<div class="knowledge-section" v-if="question.knowledge">
|
<div class="knowledge-section" v-if="question.knowledge">
|
||||||
<div class="knowledge-icon">
|
<div class="knowledge-icon">
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
|
width="12"
|
||||||
|
height="12"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<polygon
|
||||||
|
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span class="knowledge-label">考查知识点</span>
|
<span class="knowledge-label">考查知识点</span>
|
||||||
|
|
@ -536,7 +704,16 @@ onUnmounted(() => {
|
||||||
<!-- Error State -->
|
<!-- Error State -->
|
||||||
<div v-else-if="status === 'error'" class="empty-state error-state">
|
<div v-else-if="status === 'error'" class="empty-state error-state">
|
||||||
<div class="empty-icon error-icon">
|
<div class="empty-icon error-icon">
|
||||||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round">
|
<svg
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
<circle cx="12" cy="12" r="10" />
|
<circle cx="12" cy="12" r="10" />
|
||||||
<line x1="12" y1="8" x2="12" y2="12" />
|
<line x1="12" y1="8" x2="12" y2="12" />
|
||||||
<line x1="12" y1="16" x2="12.01" y2="16" />
|
<line x1="12" y1="16" x2="12.01" y2="16" />
|
||||||
|
|
@ -718,7 +895,9 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
to { transform: rotate(360deg); }
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error Banner */
|
/* Error Banner */
|
||||||
|
|
@ -788,7 +967,11 @@ onUnmounted(() => {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(99, 102, 241, 0.2));
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(139, 92, 246, 0.2),
|
||||||
|
rgba(99, 102, 241, 0.2)
|
||||||
|
);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: #a78bfa;
|
color: #a78bfa;
|
||||||
}
|
}
|
||||||
|
|
@ -930,7 +1113,11 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.count-btn.active {
|
.count-btn.active {
|
||||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.3), rgba(99, 102, 241, 0.3));
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(139, 92, 246, 0.3),
|
||||||
|
rgba(99, 102, 241, 0.3)
|
||||||
|
);
|
||||||
border-color: rgba(139, 92, 246, 0.5);
|
border-color: rgba(139, 92, 246, 0.5);
|
||||||
color: #a78bfa;
|
color: #a78bfa;
|
||||||
}
|
}
|
||||||
|
|
@ -1051,8 +1238,15 @@ onUnmounted(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% { opacity: 1; transform: scale(1); }
|
0%,
|
||||||
50% { opacity: 0.5; transform: scale(1.2); }
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.5;
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-title {
|
.result-title {
|
||||||
|
|
@ -1165,7 +1359,11 @@ onUnmounted(() => {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.08), rgba(99, 102, 241, 0.05));
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(139, 92, 246, 0.08),
|
||||||
|
rgba(99, 102, 241, 0.05)
|
||||||
|
);
|
||||||
border-bottom: 1px solid var(--card-border);
|
border-bottom: 1px solid var(--card-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1179,7 +1377,11 @@ onUnmounted(() => {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(99, 102, 241, 0.1));
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(139, 92, 246, 0.15),
|
||||||
|
rgba(99, 102, 241, 0.1)
|
||||||
|
);
|
||||||
padding: 0.35rem 0.85rem;
|
padding: 0.35rem 0.85rem;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid rgba(139, 92, 246, 0.2);
|
border: 1px solid rgba(139, 92, 246, 0.2);
|
||||||
|
|
@ -1290,7 +1492,11 @@ onUnmounted(() => {
|
||||||
|
|
||||||
/* Answer Section */
|
/* Answer Section */
|
||||||
.answer-section {
|
.answer-section {
|
||||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.08), rgba(16, 185, 129, 0.04));
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(16, 185, 129, 0.08),
|
||||||
|
rgba(16, 185, 129, 0.04)
|
||||||
|
);
|
||||||
border-top: 1px solid rgba(16, 185, 129, 0.15);
|
border-top: 1px solid rgba(16, 185, 129, 0.15);
|
||||||
border-bottom: 1px solid rgba(16, 185, 129, 0.15);
|
border-bottom: 1px solid rgba(16, 185, 129, 0.15);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue