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