|
|
@@ -64,11 +64,13 @@
|
|
|
<el-alert title="Excel格式要求" type="info" :closable="false" show-icon>
|
|
|
<template slot="default">
|
|
|
<p><strong>Excel格式要求:</strong></p>
|
|
|
- <p>• 第一行必须是标题行:题目类型、题目、选项A、选项B、选项C、选项D、选项E、选项F、正确答案、解析、分数</p>
|
|
|
+ <p>• 第一行必须是标题行,支持以下列名:题目类型、题目、选项A~F(或答案A~F)、正确答案、解析、分数</p>
|
|
|
+ <p>• 列顺序可以任意排列,系统会自动识别各列</p>
|
|
|
<p>• 题目类型:单选题、多选题、判断题、填空题、问答题</p>
|
|
|
<p>• 正确答案:单选题填选项字母(A/B/C/D/E/F),多选题用逗号分隔(A,B),判断题填对/错,填空题填答案,问答题可留空</p>
|
|
|
<p>• 分数:每道题的分值,建议单选题2-5分,多选题5-10分,判断题1-2分,填空题3-8分,问答题10-20分</p>
|
|
|
<p>• 支持富文本格式</p>
|
|
|
+ <p><strong>示例标题行:</strong>题目类型、题目、解析、正确答案、答案A、答案B、答案C、答案D、分数、答案E、答案F</p>
|
|
|
</template>
|
|
|
</el-alert>
|
|
|
</div>
|
|
|
@@ -267,20 +269,53 @@ export default {
|
|
|
|
|
|
if (allData.length < 2) return this.$message.error("Excel 数据行数不足");
|
|
|
|
|
|
+ // 读取第一行作为标题,动态匹配列索引
|
|
|
+ const headers = allData[0];
|
|
|
+ const getColumnIndex = (searchKeywords) => {
|
|
|
+ const index = headers.findIndex(header =>
|
|
|
+ searchKeywords.some(keyword =>
|
|
|
+ String(header).trim().includes(keyword)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return index >= 0 ? index : -1;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 动态获取列索引
|
|
|
+ const colIndices = {
|
|
|
+ topic_type: getColumnIndex(['题目类型', '题型']),
|
|
|
+ topic_name: getColumnIndex(['题目', '题目内容']),
|
|
|
+ answer_A: getColumnIndex(['选项A', '答案A', '选项 A', '答案 A']),
|
|
|
+ answer_B: getColumnIndex(['选项B', '答案B', '选项 B', '答案 B']),
|
|
|
+ answer_C: getColumnIndex(['选项C', '答案C', '选项 C', '答案 C']),
|
|
|
+ answer_D: getColumnIndex(['选项D', '答案D', '选项 D', '答案 D']),
|
|
|
+ answer_E: getColumnIndex(['选项E', '答案E', '选项 E', '答案 E']),
|
|
|
+ answer_F: getColumnIndex(['选项F', '答案F', '选项 F', '答案 F']),
|
|
|
+ correct_answer: getColumnIndex(['正确答案', '标准答案', '答案']),
|
|
|
+ topic_analysis: getColumnIndex(['解析', '题目解析', '答案解析']),
|
|
|
+ score: getColumnIndex(['分数', '分值', '得分'])
|
|
|
+ };
|
|
|
+
|
|
|
+ // 验证必要的列是否存在
|
|
|
+ const requiredColumns = ['topic_type', 'topic_name', 'correct_answer'];
|
|
|
+ const missingColumns = requiredColumns.filter(key => colIndices[key] === -1);
|
|
|
+ if (missingColumns.length > 0) {
|
|
|
+ return this.$message.error(`缺少必要的列:${missingColumns.join('、')}`);
|
|
|
+ }
|
|
|
+
|
|
|
const rows = allData.slice(1).filter(r => r.some(c => c !== ""));
|
|
|
this.previewData = rows.map((r, index) => ({
|
|
|
_id: index,
|
|
|
- topic_type: r[0] || "",
|
|
|
- topic_name: r[1] || "",
|
|
|
- answer_A: r[2] || "",
|
|
|
- answer_B: r[3] || "",
|
|
|
- answer_C: r[4] || "",
|
|
|
- answer_D: r[5] || "",
|
|
|
- answer_E: r[6] || "",
|
|
|
- answer_F: r[7] || "",
|
|
|
- correct_answer: r[8] || "",
|
|
|
- topic_analysis: r[9] || "",
|
|
|
- score: Number(r[10]) || 0,
|
|
|
+ topic_type: colIndices.topic_type >= 0 ? (r[colIndices.topic_type] || "") : "",
|
|
|
+ topic_name: colIndices.topic_name >= 0 ? (r[colIndices.topic_name] || "") : "",
|
|
|
+ answer_A: colIndices.answer_A >= 0 ? (r[colIndices.answer_A] || "") : "",
|
|
|
+ answer_B: colIndices.answer_B >= 0 ? (r[colIndices.answer_B] || "") : "",
|
|
|
+ answer_C: colIndices.answer_C >= 0 ? (r[colIndices.answer_C] || "") : "",
|
|
|
+ answer_D: colIndices.answer_D >= 0 ? (r[colIndices.answer_D] || "") : "",
|
|
|
+ answer_E: colIndices.answer_E >= 0 ? (r[colIndices.answer_E] || "") : "",
|
|
|
+ answer_F: colIndices.answer_F >= 0 ? (r[colIndices.answer_F] || "") : "",
|
|
|
+ correct_answer: colIndices.correct_answer >= 0 ? (r[colIndices.correct_answer] || "") : "",
|
|
|
+ topic_analysis: colIndices.topic_analysis >= 0 ? (r[colIndices.topic_analysis] || "") : "",
|
|
|
+ score: colIndices.score >= 0 ? (Number(r[colIndices.score]) || 0) : 0,
|
|
|
show_type: 1, // 导入的数据固定为文本类型
|
|
|
answer_type: 2, // 导入的数据固定为不可提交图片答案
|
|
|
topic_image_id: "", // 默认空值
|