From b993a943859ac27029b596bb99a96ce8f33a6a6f Mon Sep 17 00:00:00 2001 From: cc <94575594@qq.com> Date: Wed, 25 Mar 2026 19:36:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=A2=98=E5=BA=93=E7=94=9F=E6=88=90):=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?=E6=95=99=E6=9D=90=E3=80=81=E7=9F=A5=E8=AF=86=E7=82=B9=E5=92=8C?= =?UTF-8?q?=E9=A2=98=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/QuestionGenerator.vue | 337 +++++++++++++++++++++++--------- 1 file changed, 248 insertions(+), 89 deletions(-) diff --git a/src/views/QuestionGenerator.vue b/src/views/QuestionGenerator.vue index b8c72ff..9980d8d 100644 --- a/src/views/QuestionGenerator.vue +++ b/src/views/QuestionGenerator.vue @@ -24,25 +24,81 @@ const rawContent = ref(""); const cancelTokenSource = ref(null); // ── 参数配置 ── -const questionType = ref("choice"); // 'choice' | 'fillBlank' | 'translation' | 'reading' const difficulty = ref("medium"); // 'easy' | 'medium' | 'hard' const questionCount = ref(5); -const topicInput = ref(""); + +// 新增维度:教材章节、知识点、题型 +const textbookChapter = ref(""); // 教材章节(预设) +const customTextbookChapter = ref(""); // 自定义教材章节输入 +const selectedKnowledgePoints = ref([]); // 选中的知识点 +const customKnowledgePoint = ref(""); // 自定义知识点输入 +const questionFormat = ref("单项选择"); // 题型(预设) +const customQuestionFormat = ref(""); // 自定义题型输入 // ── 配置选项 ── -const TYPE_OPTIONS = [ - { value: "choice", label: "选择题", desc: "单项选择题" }, - { value: "fillBlank", label: "填空题", desc: "根据语境填空" }, - { value: "translation", label: "翻译题", desc: "英汉互译" }, - { value: "reading", label: "阅读理解", desc: "阅读文章并回答问题" }, +const DIFFICULTY_OPTIONS = [ + { value: "very_easy", label: "容易", color: "#10b981" }, + { value: "easy", label: "较易", color: "#34d399" }, + { value: "medium", label: "适中", color: "#f59e0b" }, + { value: "hard", label: "较难", color: "#f97316" }, + { value: "very_hard", label: "困难", color: "#ef4444" }, ]; -const DIFFICULTY_OPTIONS = [ - { value: "easy", label: "简单", color: "#10b981" }, - { value: "medium", label: "中等", color: "#f59e0b" }, - { value: "hard", label: "困难", color: "#ef4444" }, +// 教材章节预设选项 +const CHAPTER_OPTIONS = [ + { value: "Starter Unit1 You and Me", label: "Starter Unit1 You and Me" }, + { value: "Starter Unit2 Keep Tidy", label: "Starter Unit2 Keep Tidy" }, + { value: "Starter Unit3 Welcome!", label: "Starter Unit3 Welcome!" }, + { value: "Unit 1 You and Me", label: "Unit 1 You and Me" }, + { value: "Unit 2 We're Family!", label: "Unit 2 We're Family!" }, + { value: "Unit 3 My School", label: "Unit 3 My School" }, ]; +// 知识点预设选项 +const KNOWLEDGE_POINT_OPTIONS = [ + { value: "语法", label: "语法" }, + { value: "词汇", label: "词汇" }, + { value: "冠词", label: "冠词" }, + { value: "不定冠词", label: "不定冠词" }, + { value: "定冠词", label: "定冠词" }, + { value: "名词", label: "名词" }, + { value: "动词", label: "动词" }, + { value: "形容词", label: "形容词" }, + { value: "代词", label: "代词" }, + { value: "介词", label: "介词" }, + { value: "时态", label: "时态" }, + { value: "一般现在时", label: "一般现在时" }, + { value: "现在进行时", label: "现在进行时" }, + { value: "一般过去时", label: "一般过去时" }, + { value: "句型结构", label: "句型结构" }, + { value: "阅读理解", label: "阅读理解" }, + { value: "写作", label: "写作" }, +]; + +// 题型预设选项 +const FORMAT_OPTIONS = [ + { value: "单项选择", label: "单项选择" }, + { value: "完形填空", label: "完形填空" }, + { value: "句型转换", label: "句型转换" }, + { value: "词汇运用", label: "词汇运用" }, + { value: "翻译句子", label: "翻译句子" }, + { value: "阅读理解", label: "阅读理解" }, + { value: "书面表达", label: "书面表达" }, + { value: "短文填空", label: "短文填空" }, + { value: "语法填空", label: "语法填空" }, + { value: "选词填空", label: "选词填空" }, +]; + +// 切换知识点选中状态 +const toggleKnowledgePoint = (value) => { + const index = selectedKnowledgePoints.value.indexOf(value); + if (index > -1) { + selectedKnowledgePoints.value.splice(index, 1); + } else { + selectedKnowledgePoints.value.push(value); + } +}; + // ── 解析试题内容 ── const parsedQuestions = computed(() => { const raw = rawContent.value; @@ -111,19 +167,30 @@ function extractOptions(text) { // ── 构建请求体 ── const buildRequestBody = () => { - const typeLabel = TYPE_OPTIONS.find((t) => t.value === questionType.value)?.label || "选择题"; const difficultyLabel = DIFFICULTY_OPTIONS.find((d) => d.value === difficulty.value)?.label || "中等"; - const userPrompt = `请生成 ${questionCount.value} 道${difficultyLabel}难度的英语${typeLabel}${ - topicInput.value ? `,主题为:${topicInput.value}` : "" - }。 + // 构建知识点字符串:预设选项 + 自定义输入 + const allKnowledgePoints = [ + ...selectedKnowledgePoints.value, + ...(customKnowledgePoint.value ? [customKnowledgePoint.value] : []), + ]; + const knowledgePointStr = allKnowledgePoints.length > 0 ? allKnowledgePoints.join("、") : ""; + + // 教材章节:优先使用自定义输入,否则使用预设选择 + const chapterStr = customTextbookChapter.value || textbookChapter.value || ""; + + // 题型:优先使用自定义输入,否则使用预设选择 + const formatStr = customQuestionFormat.value || questionFormat.value || ""; + + const userPrompt = `请生成 ${questionCount.value} 道${difficultyLabel}难度的英语试题。 要求: -1. 题目类型:${typeLabel} +1. 题型:${formatStr} 2. 难度等级:${difficultyLabel} 3. 题目数量:${questionCount.value} 道 -${topicInput.value ? `4. 主题/知识点:${topicInput.value}` : ""} +${chapterStr ? `4. 教材章节:${chapterStr}` : ""} +${knowledgePointStr ? `5. 知识点:${knowledgePointStr}` : ""} 请严格按照指定的输出格式生成试题。`; @@ -218,10 +285,14 @@ const resetAll = () => { }; const loadExample = () => { - questionType.value = "choice"; difficulty.value = "medium"; questionCount.value = 3; - topicInput.value = "一般现在时"; + textbookChapter.value = "Starter Unit2 Keep Tidy"; + customTextbookChapter.value = ""; + selectedKnowledgePoints.value = ["语法", "冠词", "不定冠词"]; + customKnowledgePoint.value = ""; + questionFormat.value = "句型转换"; + customQuestionFormat.value = ""; }; const goBack = () => router.back(); @@ -287,24 +358,6 @@ onUnmounted(() => {
- -
- -
- -
-
-
@@ -344,14 +397,77 @@ onUnmounted(() => {
- +
- + + +
+ + +
+ +
+ +
+ +
+ + +
+ + +
@@ -750,6 +866,27 @@ onUnmounted(() => { display: flex; flex-direction: column; gap: 1.5rem; + overflow-y: auto; + min-height: 0; +} + +.config-body::-webkit-scrollbar { + width: 6px; +} + +.config-body::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 3px; +} + +.config-body::-webkit-scrollbar-thumb { + background: rgba(16, 185, 129, 0.3); + border-radius: 3px; + transition: background 0.2s; +} + +.config-body::-webkit-scrollbar-thumb:hover { + background: rgba(16, 185, 129, 0.5); } .config-item { @@ -773,50 +910,6 @@ onUnmounted(() => { font-weight: 600; } -/* Type Selection */ -.type-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0.75rem; -} - -.type-btn { - display: flex; - flex-direction: column; - align-items: center; - gap: 0.25rem; - padding: 1rem; - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 12px; - cursor: pointer; - transition: all 0.2s; -} -.type-btn:hover:not(:disabled) { - background: rgba(16, 185, 129, 0.06); - border-color: rgba(16, 185, 129, 0.3); -} -.type-btn.active { - background: rgba(16, 185, 129, 0.12); - border-color: #10b981; -} -.type-btn:disabled { - opacity: 0.4; - cursor: not-allowed; -} -.type-label { - font-size: 0.95rem; - font-weight: 600; - color: var(--text-primary); -} -.type-desc { - font-size: 0.75rem; - color: var(--text-secondary); -} -.type-btn.active .type-label { - color: #10b981; -} - /* Difficulty Selection */ .difficulty-group { display: flex; @@ -858,6 +951,7 @@ onUnmounted(() => { outline: none; cursor: pointer; -webkit-appearance: none; + appearance: none; } .range-slider::-webkit-slider-thumb { -webkit-appearance: none; @@ -910,6 +1004,74 @@ onUnmounted(() => { cursor: not-allowed; } +/* Select Input */ +.select-input { + width: 100%; + padding: 0.875rem 1rem; + background: rgba(0, 0, 0, 0.2); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 10px; + color: var(--text-primary); + font-size: 0.9rem; + outline: none; + transition: border-color 0.2s, box-shadow 0.2s; + box-sizing: border-box; + cursor: pointer; + -webkit-appearance: none; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2310b981' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 1rem center; + padding-right: 2.5rem; +} +.select-input:focus { + border-color: rgba(16, 185, 129, 0.5); + box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1); +} +.select-input:disabled { + opacity: 0.4; + cursor: not-allowed; +} +.select-input option { + background: #1a1a2e; + color: var(--text-primary); +} + +/* Knowledge Points Grid */ +.knowledge-grid { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} +.knowledge-btn { + padding: 0.5rem 0.875rem; + background: rgba(255, 255, 255, 0.02); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 8px; + color: var(--text-secondary); + font-size: 0.8rem; + cursor: pointer; + transition: all 0.2s; +} +.knowledge-btn:hover:not(:disabled) { + background: rgba(16, 185, 129, 0.1); + border-color: rgba(16, 185, 129, 0.3); + color: #10b981; +} +.knowledge-btn.active { + background: rgba(16, 185, 129, 0.15); + border-color: #10b981; + color: #10b981; +} +.knowledge-btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.mt-2 { + margin-top: 0.75rem; +} + /* Example Button */ .example-btn { display: flex; @@ -1275,9 +1437,6 @@ onUnmounted(() => { .right-panel { padding: 1.25rem 1rem; } - .type-grid { - grid-template-columns: 1fr; - } .options-grid { grid-template-columns: 1fr; }