多体系建设信息化条统-前端
zhouwx
5 days ago 1b1ba1b10b7838778632b54de7da8e5624c90dfc
新增题目识别
1 files modified
139 ■■■■■ changed files
src/views/work/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue 139 ●●●●● patch | view | raw | blame | history
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