From 1d1105017812a10fe66b2e7c2f56ea31fd8fa45b Mon Sep 17 00:00:00 2001 From: cc <94575594@qq.com> Date: Thu, 26 Mar 2026 10:48:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=AF=95=E9=A2=98=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=99=A8):=20=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A7=8D=E7=AD=94?= =?UTF-8?q?=E9=A2=98=E5=BD=A2=E5=BC=8F=E5=92=8C=E8=AF=95=E9=A2=98=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/index.js | 43 +++++-- src/views/QuestionGenerator.vue | 210 ++++++++++++++++++++++++++++---- 2 files changed, 219 insertions(+), 34 deletions(-) diff --git a/src/config/index.js b/src/config/index.js index 881a35a..8954765 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -56,7 +56,9 @@ export const QUESTION_MAX_TOKENS = 4096; // 试题生成 System Prompt export const QUESTION_GENERATOR_PROMPT = `你是一位专业的英语试题出题专家。请根据用户指定的参数生成高质量的英语试题。 -输出格式要求: +【重要】必须严格按照用户指定的"答题形式"生成对应格式的试题: + +## 答题形式为"单选题"时的格式: ## 题目 [序号] **题目类型**:[类型] **难度等级**:[难度] @@ -71,15 +73,38 @@ D. [选项D内容] **解析**:[详细解析] **知识点**:[相关知识点] +## 答题形式为"填空题"时的格式: +## 题目 [序号] +**题目类型**:[类型] +**难度等级**:[难度] +**题目内容**: +[题目文本,用下划线_____标出需要填空的位置] +**正确答案**:[填空答案] +**解析**:[详细解析] +**知识点**:[相关知识点] + +## 答题形式为"写作题"时的格式: +## 题目 [序号] +**题目类型**:[类型] +**难度等级**:[难度] +**题目内容**: +[写作题目要求] +**参考范文**: +[一篇高质量的范文] +**解析**:[写作要点解析,包括文章结构、关键表达等] +**知识点**:[相关知识点] + 重要规则: -1. 所有题型都必须提供4个选项(A、B、C、D),即使是填空题、翻译题或阅读理解题 -2. 对于填空题:选项为不同的填空答案选项 -3. 对于翻译题:选项为不同的翻译版本 -4. 对于阅读理解题:选项为对问题的不同回答选项 -5. 题目质量要高,符合英语教学标准 -6. 答案准确无误 -7. 解析清晰易懂,有助于学生理解 -8. 知识点标注准确,便于分类学习`; +1. 【最高优先级】必须严格按照用户指定的答题形式(单选题/填空题/写作题)生成对应格式的试题 +2. 【严禁超纲】如果用户指定了"教材章节",所有试题内容必须严格限定在该章节的知识范围内,绝对禁止出现超出该章节的词汇、语法、句型等内容 +3. 【知识点约束】如果用户指定了"知识点",试题必须围绕该知识点出题,不得偏离 +4. 单选题:必须提供4个选项(A、B、C、D),答案为选项字母 +5. 填空题:不提供选项,用_____标出填空位置,答案为填空内容 +6. 写作题:提供写作要求和参考范文,不提供选项 +7. 题目质量要高,符合英语教学标准 +8. 答案准确无误 +9. 解析清晰易懂,有助于学生理解 +10. 知识点标注准确,便于分类学习`; // ── 文件上传限制 ── export const IMAGE_MAX_SIZE_MB = 10; diff --git a/src/views/QuestionGenerator.vue b/src/views/QuestionGenerator.vue index 9980d8d..0c887f4 100644 --- a/src/views/QuestionGenerator.vue +++ b/src/views/QuestionGenerator.vue @@ -34,6 +34,8 @@ const selectedKnowledgePoints = ref([]); // 选中的知识点 const customKnowledgePoint = ref(""); // 自定义知识点输入 const questionFormat = ref("单项选择"); // 题型(预设) const customQuestionFormat = ref(""); // 自定义题型输入 +const answerFormat = ref("单选题"); // 答题形式:单选题、填空题、写作题 +const examType = ref(""); // 试题类型 // ── 配置选项 ── const DIFFICULTY_OPTIONS = [ @@ -77,7 +79,6 @@ const KNOWLEDGE_POINT_OPTIONS = [ // 题型预设选项 const FORMAT_OPTIONS = [ - { value: "单项选择", label: "单项选择" }, { value: "完形填空", label: "完形填空" }, { value: "句型转换", label: "句型转换" }, { value: "词汇运用", label: "词汇运用" }, @@ -89,6 +90,20 @@ const FORMAT_OPTIONS = [ { value: "选词填空", label: "选词填空" }, ]; +// 答题形式选项 +const ANSWER_FORMAT_OPTIONS = [ + { value: "单选题", label: "单选题" }, + { value: "填空题", label: "填空题" }, + { value: "写作题", label: "写作题" }, +]; + +// 试题类型选项 +const EXAM_TYPE_OPTIONS = [ + { value: "中考", label: "中考" }, + { value: "单元同义句", label: "单元同义句" }, + { value: "高频考点", label: "高频考点" }, +]; + // 切换知识点选中状态 const toggleKnowledgePoint = (value) => { const index = selectedKnowledgePoints.value.indexOf(value); @@ -130,7 +145,10 @@ const parsedQuestions = computed(() => { }); function extractField(text, fieldName) { - const regex = new RegExp(`\\*\\*${fieldName}\\*\\*[::]\\s*([\\s\\S]*?)(?=\\*\\*|$)`, "i"); + const regex = new RegExp( + `\\*\\*${fieldName}\\*\\*[::]\\s*([\\s\\S]*?)(?=\\*\\*|$)`, + "i" + ); const match = text.match(regex); if (!match) return ""; @@ -142,15 +160,17 @@ function extractField(text, fieldName) { function extractOptions(text) { const options = []; - + // 先尝试提取"选项"字段的内容块 - const optionsBlockMatch = text.match(/\*\*选项\*\*[::]\s*([\s\S]*?)(?=\*\*正确答案\*\*|$)/i); - + const optionsBlockMatch = text.match( + /\*\*选项\*\*[::]\s*([\s\S]*?)(?=\*\*正确答案\*\*|$)/i + ); + if (optionsBlockMatch) { const optionsBlock = optionsBlockMatch[1]; - + // 在选项块中提取各个选项 - const lines = optionsBlock.split('\n'); + const lines = optionsBlock.split("\n"); for (const line of lines) { const match = line.match(/^([A-D])[\..。::]\s*(.+)$/i); if (match) { @@ -161,21 +181,23 @@ function extractOptions(text) { } } } - + return options; } // ── 构建请求体 ── const buildRequestBody = () => { const difficultyLabel = - DIFFICULTY_OPTIONS.find((d) => d.value === difficulty.value)?.label || "中等"; + DIFFICULTY_OPTIONS.find((d) => d.value === difficulty.value)?.label || + "中等"; // 构建知识点字符串:预设选项 + 自定义输入 const allKnowledgePoints = [ ...selectedKnowledgePoints.value, ...(customKnowledgePoint.value ? [customKnowledgePoint.value] : []), ]; - const knowledgePointStr = allKnowledgePoints.length > 0 ? allKnowledgePoints.join("、") : ""; + const knowledgePointStr = + allKnowledgePoints.length > 0 ? allKnowledgePoints.join("、") : ""; // 教材章节:优先使用自定义输入,否则使用预设选择 const chapterStr = customTextbookChapter.value || textbookChapter.value || ""; @@ -183,16 +205,30 @@ const buildRequestBody = () => { // 题型:优先使用自定义输入,否则使用预设选择 const formatStr = customQuestionFormat.value || questionFormat.value || ""; - const userPrompt = `请生成 ${questionCount.value} 道${difficultyLabel}难度的英语试题。 + // 构建教材章节约束提示 + const chapterConstraint = chapterStr + ? `\n\n【重要约束】教材章节为"${chapterStr}",所有试题内容必须严格限定在该章节的知识范围内: +- 仅使用该章节已学过的词汇、短语和表达方式 +- 仅考查该章节涉及的语法点和句型结构 +- 绝对禁止出现超出该章节范围的知识点 +- 如果试题类型为"中考",则按中考标准出题,但仍需体现该章节的核心内容` + : ""; + + const userPrompt = `请生成 ${ + questionCount.value + } 道${difficultyLabel}难度的英语试题。 要求: 1. 题型:${formatStr} -2. 难度等级:${difficultyLabel} -3. 题目数量:${questionCount.value} 道 -${chapterStr ? `4. 教材章节:${chapterStr}` : ""} -${knowledgePointStr ? `5. 知识点:${knowledgePointStr}` : ""} +2. 答题形式:${answerFormat.value} +3. 难度等级:${difficultyLabel} +4. 题目数量:${questionCount.value} 道 +${examType.value ? `5. 试题类型:${examType.value}` : ""} +${chapterStr ? `6. 教材章节:${chapterStr}` : ""} +${knowledgePointStr ? `7. 知识点:${knowledgePointStr}` : ""} +${chapterConstraint} -请严格按照指定的输出格式生成试题。`; +请严格按照指定的输出格式和答题形式生成试题。严禁出现超出指定范围的内容。`; return { model: QUESTION_MODEL, @@ -234,7 +270,11 @@ const filterThinkBlocks = (text) => { // ── 开始生成 ── const canGenerate = computed(() => { - return status.value !== "generating" && questionCount.value >= 1 && questionCount.value <= 20; + return ( + status.value !== "generating" && + questionCount.value >= 1 && + questionCount.value <= 20 + ); }); const startGeneration = async () => { @@ -273,7 +313,9 @@ const startGeneration = async () => { if (axios.isCancel(err)) return; console.error(err); errorMsg.value = - err?.response?.data?.error?.message || err.message || "请求失败,请稍后重试"; + err?.response?.data?.error?.message || + err.message || + "请求失败,请稍后重试"; status.value = "error"; }); }; @@ -287,6 +329,8 @@ const resetAll = () => { const loadExample = () => { difficulty.value = "medium"; questionCount.value = 3; + answerFormat.value = "单选题"; + examType.value = ""; textbookChapter.value = "Starter Unit2 Keep Tidy"; customTextbookChapter.value = ""; selectedKnowledgePoints.value = ["语法", "冠词", "不定冠词"]; @@ -397,6 +441,40 @@ onUnmounted(() => { + +