From 1b1ba1b10b7838778632b54de7da8e5624c90dfc Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: Tue, 28 Apr 2026 10:37:21 +0800
Subject: [PATCH] 新增题目识别

---
 src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue |  139 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue b/src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
index 92a67f4..e5bbda5 100644
--- a/src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
+++ b/src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
@@ -56,7 +56,9 @@
 <!--                :value="item.name"-->
 <!--            />-->
 <!--          </el-select>-->
+
         </el-form-item>
+
         <el-form-item label="题目内容:" prop="title">
           <el-input v-model.trim="state.form.title" type="textarea" placeholder="请输入题目内容"></el-input>
         </el-form-item>
@@ -85,6 +87,18 @@
             </div>
           </el-checkbox-group>
           <el-input v-if="state.form.questionType === 4" v-model="state.form.answer" type="textarea" placeholder="请输入正确答案"></el-input>
+        </el-form-item>
+        <el-form-item label="快速粘贴识别:">
+          <div style="width: 100%;">
+            <el-input
+                v-model="pasteText"
+                type="textarea"
+                :rows="5"
+                placeholder="粘贴整段题目文本,自动识别题目、选项和答案"
+                style="width: 100%; margin-bottom: 10px;"
+            ></el-input>
+            <el-button type="primary" @click="handlePaste">粘贴并识别</el-button>
+          </div>
         </el-form-item>
         <el-form-item label="解析:" >
           <el-input type="textarea" v-model="state.optionItem.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input>
@@ -176,6 +190,7 @@
   hasMoreItems: null, // 是否还有更多选项
 
 })
+const pasteText = ref('')
 const reselect = reactive({
   name: 'bank1'
 })
@@ -203,6 +218,7 @@
 const delOption = (val) => {
   state.optionItem.items.splice(val,1)
   state.form.answer = ''
+  state.checkList = []
   console.log(" state.optionItem.items.", state.optionItem.items)
 }
 const openDialog = async (type, value) => {
@@ -281,6 +297,128 @@
   }
 }
 
+
+const handlePaste = () => {
+  const text = pasteText.value.trim()
+  if (!text) {
+    ElMessage.warning('请先粘贴题目文本')
+    return
+  }
+
+
+  const bracketAnswerReg = /[(\(]\s*([A-Z]+)\s*[)\)]/i;
+  const answerLineReg = /(?:答案|正确答案)[::]\s*([A-Z,,\s]+)/gi;
+  const boolAnswerReg = /(?:答案|正确答案)[::]\s*(是|否|正确|错误|对|错)/i;
+  // 🔥 关键:不限制行首行尾,全局匹配所有A. B. C. D选项,支持同行/换行
+  const optionMatchReg = /[A-Z][.、:]\s*([^A-Z\n]+)/g;
+
+  let answer = '';
+  let isBoolAnswer = false;
+  let boolAnswerContent = '';
+  let optionList = [];
+
+
+  const bracketAnsMatch = text.match(bracketAnswerReg);
+  if (bracketAnsMatch) {
+    answer = bracketAnsMatch[1].toUpperCase().replace(/\s/g, '');
+  }
+
+  const allAnswerLines = text.match(answerLineReg) || [];
+  if (allAnswerLines.length > 0) {
+    const lastAnswerLine = allAnswerLines[allAnswerLines.length - 1];
+    const ansMatch = lastAnswerLine.match(/(?:答案|正确答案)[::]\s*([A-Z,,\s]+)/i);
+    if (ansMatch) {
+      answer = ansMatch[1].replace(/\s/g, '').replace(/,/g, ',').toUpperCase();
+    }
+  }
+
+  const boolAnsMatch = text.match(boolAnswerReg);
+  if (boolAnsMatch) {
+    isBoolAnswer = true;
+    boolAnswerContent = boolAnsMatch[1];
+  }
+
+
+  const optionMatches = [];
+  let match;
+
+  while ((match = optionMatchReg.exec(text)) !== null) {
+    optionMatches.push({
+      prefix: match[0].match(/[A-Z]/)[0], // 提取选项字母
+      content: match[1].trim()
+    });
+  }
+
+  optionList = optionMatches.map(item => {
+    const cleanContent = item.content
+        .replace(/(?:答案|正确答案)[::].*/gi, '')
+        .trim()
+    return { content: cleanContent }
+  }).filter(item => item.content && !/^(答案|正确答案)/.test(item.content));
+
+
+  let questionText = text
+      .replace(optionMatchReg, '')
+      .replace(answerLineReg, '')
+      .replace(boolAnswerReg, '')
+      .replace(bracketAnswerReg, '()')
+      .replace(/^\d+[.、]\s*/, '')
+      .replace(/\s+[A-Z](?=\s|$)/g, '')
+      .replace(/\s+/g, ' ')
+      .trim();
+
+  if (!questionText) {
+    ElMessage.warning('未识别到题目内容');
+    return;
+  }
+
+
+  let questionType = 1;
+  if (
+      boolAnswerContent ||
+      (optionList.length === 2 &&
+          optionList.some(o => /是|正确|对/.test(o.content)) &&
+          optionList.some(o => /否|错误|错/.test(o.content))
+      )
+  ) {
+    questionType = 3;
+  } else if ((answer && answer.length > 1) || answer.includes(',')) {
+    questionType = 2;
+  }
+
+
+  state.form.questionType = questionType;
+  changeType();
+
+
+  state.form.title = questionText;
+
+
+  if (questionType !== 3) {
+    state.optionItem.items = optionList;
+  }
+
+
+  if (isBoolAnswer) {
+    const answerMap = { '是': 'A', '正确': 'A', '对': 'A', '否': 'B', '错误': 'B', '错': 'B' };
+    answer = answerMap[boolAnswerContent] || '';
+  }
+
+  state.checkList = [];
+  if (answer) {
+    if (questionType === 1 || questionType === 3) {
+      state.form.answer = answer;
+    } else if (questionType === 2) {
+      const ansArr = answer.split('').filter(i => i);
+      state.checkList = ansArr;
+      state.form.answer = ansArr.join(',');
+    }
+  } else {
+    ElMessage.info('未识别到答案,请手动补充');
+  }
+
+  ElMessage.success('识别完成');
+};
 
 const onSubmit = async () => {
   console.log(" state.form", state.form)
@@ -405,6 +543,7 @@
   state.bankPageSize = 10;
   state.bankList = []
   state.checkList = []
+  pasteText.value = ''
 }
 defineExpose({
   openDialog

--
Gitblit v1.9.2