362 lines
16 KiB
Vue
362 lines
16 KiB
Vue
<template>
|
||
<div>
|
||
<query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
|
||
<dialog-detail ref="detail" />
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { UrlConfig } from '@/scripts/ConstDic';
|
||
import { listQuestionPage, deleteQuestion } from '@/api/questionBank.js';
|
||
import DialogDetail from './dialog-detail';
|
||
import { convertSheetToList } from '@/utils/runPlan';
|
||
import { getCompanyList } from '@/api/company';
|
||
import XLSX from 'xlsx';
|
||
|
||
export default {
|
||
components: {
|
||
DialogDetail
|
||
},
|
||
data() {
|
||
return {
|
||
companyList: [],
|
||
companyMap: {},
|
||
pagerConfig: {
|
||
pageSize: 'pageSize',
|
||
pageIndex: 'pageNum'
|
||
},
|
||
queryForm: {
|
||
reset: true,
|
||
labelWidth: '80px',
|
||
leftSpan: 16,
|
||
queryObject: {
|
||
type: {
|
||
type: 'select',
|
||
label: '类 型',
|
||
config: {
|
||
data: this.$ConstSelect.QuestionTypeList
|
||
}
|
||
},
|
||
topic: {
|
||
type: 'text',
|
||
label: '题 目'
|
||
},
|
||
companyId: {
|
||
type: 'select',
|
||
label: '单位',
|
||
config: {
|
||
data: []
|
||
}
|
||
}
|
||
}
|
||
},
|
||
queryList: {
|
||
query: listQuestionPage,
|
||
selectCheckShow: false,
|
||
indexShow: true,
|
||
columns: [
|
||
{
|
||
title: '题 目',
|
||
prop: 'topic'
|
||
},
|
||
{
|
||
title: '类 型',
|
||
prop: 'type',
|
||
type: 'tag',
|
||
width: '120',
|
||
columnValue: (row) => { return this.$ConstSelect.translate(row.type, 'QuestionTypeList'); },
|
||
tagType: (row) => {
|
||
return '';
|
||
}
|
||
},
|
||
{
|
||
title: '答 案',
|
||
prop: 'answer',
|
||
type: 'tagMore',
|
||
width: '200',
|
||
columnValue: (row) => { return this.answerTags(row); },
|
||
tagType: (row) => {
|
||
return '';
|
||
}
|
||
},
|
||
{
|
||
title: '单位',
|
||
prop: 'companyId',
|
||
width: '100',
|
||
type: 'tag',
|
||
columnValue: (row) => { return this.getCompanyName(row.companyId); },
|
||
tagType: (row) => { return ''; }
|
||
},
|
||
{
|
||
type: 'button',
|
||
title: '操 作',
|
||
width: '320',
|
||
buttons: [
|
||
{
|
||
name: '编辑',
|
||
handleClick: this.edit
|
||
},
|
||
{
|
||
name: '删 除',
|
||
handleClick: this.doDelete,
|
||
// showControl: (row) => { return row.createUserId == this.userId; },
|
||
type: 'danger'
|
||
},
|
||
{
|
||
name: '预 览',
|
||
handleClick: this.doDetail
|
||
}
|
||
]
|
||
}
|
||
],
|
||
actions: [
|
||
{ text: '添 加', handler: this.doCreate },
|
||
{ text: '导 入', fileType: 'file', handler: this.importQuestionBank },
|
||
{ text: '试卷规则管理', handler: this.questionsRuleManage},
|
||
{ text: '模板导出', handler: this.exportTemplate}
|
||
]
|
||
}
|
||
};
|
||
},
|
||
computed: {
|
||
userId() {
|
||
return this.$store.state.user.id;
|
||
}
|
||
},
|
||
mounted() {
|
||
this.companyList = [];
|
||
getCompanyList().then(resp => {
|
||
resp.data.forEach(item => {
|
||
this.queryForm.queryObject.companyId.config.data.push({ value: item.id, label: item.name });
|
||
this.companyMap[item.id] = item.name;
|
||
});
|
||
});
|
||
},
|
||
methods: {
|
||
doCreate() {
|
||
this.$router.push({path: `${UrlConfig.bank.questionCreate}`});
|
||
},
|
||
getCompanyName(companyId) {
|
||
return this.companyMap[companyId];
|
||
},
|
||
edit(index, row) {
|
||
this.$router.push({path: `${UrlConfig.bank.questionUpdate}/${row.id}`});
|
||
},
|
||
|
||
doDelete(index, row) {
|
||
this.$confirm('删除试题,是否继续?', '提 示', {
|
||
confirmButtonText: '确 定',
|
||
cancelButtonText: '取 消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
deleteQuestion(row.id).then(resp => {
|
||
this.reloadTable();
|
||
}).catch(error => {
|
||
this.$message.error(`删除试题失败: ${error.message}`);
|
||
});
|
||
}).catch( () => { });
|
||
},
|
||
|
||
doDetail(index, row) {
|
||
this.$refs.detail.doShow({index, row});
|
||
},
|
||
|
||
answerTags(row) {
|
||
const answer = [];
|
||
row.optionList.forEach((el, i) => {
|
||
switch (row.type) {
|
||
case 'select':
|
||
if (el.correct) {
|
||
answer.push(this.$asc2chart(i + 65));
|
||
}
|
||
break;
|
||
case 'judge':
|
||
if (el.correct) {
|
||
answer.push(el.content);
|
||
}
|
||
break;
|
||
case 'multi':
|
||
if (el.correct) {
|
||
answer.push(this.$asc2chart(i + 65));
|
||
}
|
||
break;
|
||
case 'fill':
|
||
answer.push(el.content);
|
||
break;
|
||
case 'answer':
|
||
answer.push(el.content);
|
||
break;
|
||
}
|
||
});
|
||
return answer;
|
||
},
|
||
|
||
reloadTable() {
|
||
this.queryList.reload();
|
||
},
|
||
handleImport(file) {
|
||
const questionTypeMap = {
|
||
'单选': 'select',
|
||
'多选': 'multi',
|
||
'判断': 'judge',
|
||
'填空': 'fill',
|
||
'问答': 'answer'
|
||
};
|
||
if (file) {
|
||
try {
|
||
setTimeout(() => {
|
||
const that = this;
|
||
const reader = new FileReader();
|
||
if (reader) {
|
||
reader.onload = function (e) {
|
||
let wb;
|
||
const data = e.target.result;
|
||
if (that.rABS) {
|
||
wb = XLSX.read(btoa(that.fixdata(data)), { // 手动转化
|
||
type: 'base64'
|
||
});
|
||
} else {
|
||
wb = XLSX.read(data, {
|
||
type: 'binary'
|
||
});
|
||
}
|
||
const questionList = [];
|
||
if (wb && wb.Sheets) {
|
||
for (const index in wb.Sheets) {
|
||
const dataList = convertSheetToList(wb.Sheets[index], true);
|
||
let questionTypeIndex;
|
||
let topicIndex;
|
||
let option1Index;
|
||
let option2Index;
|
||
let option3Index;
|
||
let option4Index;
|
||
let answerIndex;
|
||
dataList.forEach((item, index) => {
|
||
if (item[0] === '题型') {
|
||
questionTypeIndex = index;
|
||
} else if (item[0] === '题目') {
|
||
topicIndex = index;
|
||
} else if ( item[0] === '选项' && item[1] === 'A') {
|
||
option1Index = index;
|
||
} else if (!item[0] && item[1] === 'B') {
|
||
option2Index = index;
|
||
} else if (!item[0] && item[1] === 'C') {
|
||
option3Index = index;
|
||
} else if (!item[0] && item[1] === 'D') {
|
||
option4Index = index;
|
||
} else if (item[0] === '答案') {
|
||
answerIndex = index;
|
||
}
|
||
});
|
||
if (questionTypeIndex || questionTypeIndex === 0) {
|
||
dataList[questionTypeIndex].forEach((item, index) => {
|
||
if (item && item !== '题型') {
|
||
const param = {
|
||
type: questionTypeMap[item],
|
||
topic: dataList[topicIndex][index],
|
||
optionList: []
|
||
};
|
||
if (param.type === 'fill') {
|
||
const answer = dataList[answerIndex][index];
|
||
const answerList = answer.split('&&');
|
||
answerList && answerList.forEach(item => {
|
||
param.optionList.push({content: item, correct: true});
|
||
});
|
||
} else if (param.type === 'answer') {
|
||
param.optionList.push({content: dataList[answerIndex][index]});
|
||
} else {
|
||
param.optionList.push({ content:dataList[option1Index][index] || '正确', correct: dataList[answerIndex][index].includes('A') || dataList[answerIndex][index] == '√' });
|
||
param.optionList.push({ content:dataList[option2Index][index] || '错误', correct: dataList[answerIndex][index].includes('B') || dataList[answerIndex][index] == '×' });
|
||
if (dataList[option3Index][index]) {
|
||
param.optionList.push({content:dataList[option3Index][index], correct: dataList[answerIndex][index].includes('C')});
|
||
}
|
||
if (dataList[option4Index][index]) {
|
||
param.optionList.push({content:dataList[option4Index][index], correct: dataList[answerIndex][index].includes('D')});
|
||
}
|
||
}
|
||
param.id = questionList.length;
|
||
questionList.push(param);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
that.$store.dispatch('race/setPreTheoryData', questionList).then(() => {
|
||
that.$router.push({ path: `/system/preTheoryImport`});
|
||
}).catch((e) => {
|
||
that.$message.error('导入题库失败!');
|
||
});
|
||
}
|
||
};
|
||
if (that.rABS) {
|
||
reader.readAsArrayBuffer(file);
|
||
} else {
|
||
reader.readAsBinaryString(file);
|
||
}
|
||
}
|
||
}, 200);
|
||
} catch (e) {
|
||
this.$message.error('请根据下载模板导入题目!');
|
||
}
|
||
}
|
||
},
|
||
importQuestionBank() {
|
||
const obj = document.getElementById('queryFormFilesInput');
|
||
if (!obj.files) return;
|
||
const f = obj.files[0];
|
||
this.handleImport(f);
|
||
},
|
||
questionsRuleManage() {
|
||
this.$router.push({ path: `/system/questionsRuleManage`});
|
||
},
|
||
exportTemplate() {
|
||
const wb = XLSX.utils.book_new();
|
||
const data1 = [{A: '序号', B: '题型', C:'题目', D:'答案', E: '', F: '', G: '', H: ''}];
|
||
const data2 = [{A: '', B: '', C:'', D:'', E: 'A', F: 'B', G: 'C', H: 'D'}];
|
||
const data3 = [{A: '1', B: '判断', C:'题目一', D:'√', E: '', F: '', G: '', H: ''}];
|
||
const data4 = [{A: '2', B: '判断', C:'题目二', D:'×', E: '', F: '', G: '', H: ''}];
|
||
const data5 = [{A: '3', B: '单选', C:'题目三', D:'A', E: '选项A', F: '选项B', G: '选项C', H: '选项D'}];
|
||
const data6 = [{A: '4', B: '多选', C:'题目四', D:'ABCD', E: '选项A', F: '选项B', G: '选项C', H: '选项D'}];
|
||
// const data7 = [{A: '5', B: '填空', C:'题目五', D:'第一空答案&&第二空答案&&第三空答案', E: '', F: '', G: '', H: ''}];
|
||
// const data8 = [{A: '6', B: '问答', C:'题目六', D:'问答题答案', E: '', F: '', G: '', H: '问答题答案'}];
|
||
// const data = [...data1, ...data2, ...data3, ...data4, ...data5, ...data6, ...data7, ...data8];
|
||
const data = [...data1, ...data2, ...data3, ...data4, ...data5, ...data6];
|
||
const ws = XLSX.utils.json_to_sheet(data, {skipHeader:true});
|
||
ws['!merges'] = [
|
||
{
|
||
s: {c: 4, r: 0},
|
||
e: {c: 7, r: 0}
|
||
},
|
||
{
|
||
s: {c: 0, r: 0},
|
||
e: {c: 0, r: 1}
|
||
},
|
||
{
|
||
s: {c: 1, r: 0},
|
||
e: {c: 1, r: 1}
|
||
},
|
||
{
|
||
s: {c: 2, r: 0},
|
||
e: {c: 2, r: 1}
|
||
},
|
||
{
|
||
s: {c: 3, r: 0},
|
||
e: {c: 3, r: 1}
|
||
}
|
||
];
|
||
ws['!cols'] = [
|
||
{width: 10},
|
||
{width: 10},
|
||
{width: 50},
|
||
{width: 15},
|
||
{width: 15},
|
||
{width: 15},
|
||
{width: 15},
|
||
{width: 15}
|
||
];
|
||
XLSX.utils.book_append_sheet(wb, ws, 'file');
|
||
XLSX.writeFile(wb, '题库模板' + '.xlsx');
|
||
}
|
||
}
|
||
};
|
||
</script>
|