parent
d79c0d0cbb
commit
b015e22c1a
15 changed files with 969 additions and 3857 deletions
@ -1,715 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<el-drawer title="自动选题" :visible.sync="quesVisible" size="1200px" :close-on-click-modal="false" |
|
||||||
custom-class="ques-dia" @closed="closeDia"> |
|
||||||
<div class="overflow"> |
|
||||||
<h6 class="page-name">难度设置</h6> |
|
||||||
<div class="tool"> |
|
||||||
<ul class="filter"> |
|
||||||
<li style="margin-right: 10px"> |
|
||||||
<label>试卷难度</label> |
|
||||||
<el-select v-model="difficult" placeholder="请选择试卷难度" @change="difficultChange"> |
|
||||||
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<el-tooltip placement="top"> |
|
||||||
<div class="diff-text" slot="content"> |
|
||||||
<p>基础题:难度系数0.2</p> |
|
||||||
<p>普通题:难度系数0.4</p> |
|
||||||
<p>较难题:难度系数0.6</p> |
|
||||||
<p>困难题:难度系数0.8</p> |
|
||||||
<p>(1)<span class="em">题型难度系数</span>=对应题型所有试题的难度系数之和/总试题数</p> |
|
||||||
<p>(2)<span class="em">试卷总难度系数</span>=所有试题的难度系数之和/总试题数</p> |
|
||||||
<p>(3)<span class="em">难度系数评价</span>:</p> |
|
||||||
<div class="coe"> |
|
||||||
<p>简单:系数 <=0.3</p> |
|
||||||
<p>普通:0.3<系数<=0.4</p> |
|
||||||
<p>较难:0.4<系数<0.5</p> |
|
||||||
<p>困难:系数>=0.5</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<i class="el-icon-question" style="font-size: 16px;color: #8f8f8f;cursor: pointer;"></i> |
|
||||||
</el-tooltip> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-table :data="list" stripe header-align="center" row-key="libraryId"> |
|
||||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
|
||||||
<el-table-column label="大题" align="center" min-width="100"> |
|
||||||
<template slot-scope="scope">第{{ arabicToChinese(scope.$index + 1) }}大题</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column prop="name" label="题型" align="center" min-width="90"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<p v-if="scope.row.questionType">{{ questionTypes.find(e => e.id === scope.row.questionType).name }}</p> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column prop="questionNum" label="目标题数" align="center" min-width="80"></el-table-column> |
|
||||||
<el-table-column label="基础(道题)" align="center" width="90"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input v-model.number="scope.row.basicDifficulty" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="普通(道题)" align="center" width="90"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input v-model.number="scope.row.normalDifficulty" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="较难(道题)" align="center" width="90"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input v-model.number="scope.row.hardDifficulty" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="难(道题)" align="center" width="90"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input v-model.number="scope.row.veryHardDifficulty" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="难度随机(道题)" align="center" width="100"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input v-model.number="scope.row.randomDifficulty" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
|
|
||||||
<h6 class="page-name m-t-20">知识点设置</h6> |
|
||||||
<div class="wrap"> |
|
||||||
<!-- 题库 --> |
|
||||||
<div class="item"> |
|
||||||
<p class="total m-b-10">题库</p> |
|
||||||
<ul class="filter"> |
|
||||||
<li class="m-b-10"> |
|
||||||
<label>题库分类</label> |
|
||||||
<el-cascader style="width: 240px;" placeholder="请选择题库分类" v-model="quesBankTypeVal" |
|
||||||
:options="quesBankTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable |
|
||||||
@change="initQuesBank"></el-cascader> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" clearable /> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
|
|
||||||
<template v-if="quesBanks.length"> |
|
||||||
<div class="line"> |
|
||||||
<span class="serial first">序号</span> |
|
||||||
<span>题库名称</span> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="able-check lines"> |
|
||||||
<div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]" |
|
||||||
@click="questionBankClick(item)"> |
|
||||||
<span class="serial first">{{ i + 1 }}</span> |
|
||||||
<p class="stem" :title="item.questionBankName">{{ item.questionBankName }}</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<div v-else class="empty"> |
|
||||||
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
|
||||||
<p>暂无数据</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<!-- 知识点 --> |
|
||||||
<div class="item"> |
|
||||||
<p class="total m-b-10">知识点</p> |
|
||||||
<ul class="filter"> |
|
||||||
<li class="m-b-10"> |
|
||||||
<label>知识点框架</label> |
|
||||||
<el-cascader style="width: 240px;" placeholder="请选择知识点分类" v-model="knowledgeTypeVal" |
|
||||||
:options="knowledgeTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable |
|
||||||
@change="getKnowledge"></el-cascader> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<el-input placeholder="请输入知识点名称" prefix-icon="el-icon-search" v-model="knowledgeKeyword" clearable /> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
|
|
||||||
<template v-if="knowledges.length"> |
|
||||||
<div class="line"> |
|
||||||
<el-checkbox v-model="knowledgeCheck" @change="knowledgeAllCheckChange"></el-checkbox> |
|
||||||
<span class="serial">序号</span> |
|
||||||
<span>知识点名称</span> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="lines"> |
|
||||||
<div v-for="(item, i) in knowledges" :key="i" class="line"> |
|
||||||
<el-checkbox v-model="item.check" :disabled="item.disabled" |
|
||||||
@change="val => knowledgeChange(val, item)"></el-checkbox> |
|
||||||
<span class="serial">{{ i + 1 }}</span> |
|
||||||
<p class="stem" :title="item.name">{{ item.name }}</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<div v-else class="empty"> |
|
||||||
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
|
||||||
<p>暂无数据</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<!-- 已选知识点 --> |
|
||||||
<div class="item"> |
|
||||||
<div class="flex j-between a-center m-b-20"> |
|
||||||
<p class="total m-b-10">已选知识点({{ allKnowledges.length }}个)</p> |
|
||||||
<p class="clear" @click="clearChecked"> |
|
||||||
<i class="el-icon-delete m-r-5"></i> |
|
||||||
清空 |
|
||||||
</p> |
|
||||||
</div> |
|
||||||
|
|
||||||
<template v-for="(item, i) in checked"> |
|
||||||
<div :key="i" class="j-between m-b-10"> |
|
||||||
<div class="flex a-center"> |
|
||||||
题库:{{ item.quesBank.questionBankName }} |
|
||||||
<i class="el-icon-delete action-icon m-l-10" @click="delQuesBank(i)"></i> |
|
||||||
</div> |
|
||||||
<div class="knowledges"> |
|
||||||
<el-tag v-for="(tag, j) in item.knowledges" :key="tag.name" class="m-r-8 m-b-8" closable |
|
||||||
@close="delKnowledge(i, j, item, tag)">{{ tag.name }}</el-tag> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<h6 class="page-name m-t-20">年份设置</h6> |
|
||||||
<div class="years flex"> |
|
||||||
<el-checkbox style="margin-right: 20px" v-model="yearAll" @change="yearAllChange">全选</el-checkbox> |
|
||||||
<el-checkbox-group v-model="yearCheck" @change="yearChange"> |
|
||||||
<el-checkbox v-for="(item, i) in years" :key="i" :label="item"></el-checkbox> |
|
||||||
</el-checkbox-group> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="btns"> |
|
||||||
<el-button @click="quesVisible = false">取消</el-button> |
|
||||||
<el-button type="primary" :loading="submiting" @click="submit">自动选题</el-button> |
|
||||||
</div> |
|
||||||
</el-drawer> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<script> |
|
||||||
import Setting from '@/setting' |
|
||||||
import Util from '@/libs/util' |
|
||||||
import QuesConst from '@/const/ques' |
|
||||||
import TestPaperConst from '@/const/testPaper' |
|
||||||
import _ from 'lodash' |
|
||||||
import Decimal from 'decimal.js' |
|
||||||
export default { |
|
||||||
props: ['visible'], |
|
||||||
data () { |
|
||||||
return { |
|
||||||
arabicToChinese: Util.arabicToChinese, |
|
||||||
difficults: TestPaperConst.difficults, |
|
||||||
questionTypes: QuesConst.questionTypes, |
|
||||||
quesVisible: false, |
|
||||||
difficult: '', |
|
||||||
searchTimer: null, |
|
||||||
|
|
||||||
curQuesBank: {}, |
|
||||||
quesBankTypeVal: [], |
|
||||||
quesBankTypes: [], |
|
||||||
quesBankKeyword: '', |
|
||||||
|
|
||||||
quesBanks: [], |
|
||||||
pageQuesBank: 1, |
|
||||||
pageSizeQuesBank: 10, |
|
||||||
totalQuesBank: 0, |
|
||||||
|
|
||||||
knowledgeKeyword: '', |
|
||||||
knowledgeTypeVal: [], |
|
||||||
knowledgeTypes: [], |
|
||||||
knowledgeCheck: false, |
|
||||||
knowledges: [], |
|
||||||
pageKn: 1, |
|
||||||
pageSizeKn: 10, |
|
||||||
totalKn: 0, |
|
||||||
|
|
||||||
checkedKeyword: '', |
|
||||||
checked: [], |
|
||||||
list: [], |
|
||||||
years: ['暂无年份', '2024', '2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '更早'], |
|
||||||
yearAll: true, |
|
||||||
yearCheck: [], |
|
||||||
submiting: false, |
|
||||||
loaded: 0, |
|
||||||
}; |
|
||||||
}, |
|
||||||
computed: { |
|
||||||
allKnowledges () { |
|
||||||
const result = [] |
|
||||||
this.checked.map(e => { |
|
||||||
result.push(...e.knowledges) |
|
||||||
}) |
|
||||||
return result |
|
||||||
}, |
|
||||||
}, |
|
||||||
watch: { |
|
||||||
'quesBankKeyword': function (val) { |
|
||||||
clearTimeout(this.searchTimer) |
|
||||||
this.searchTimer = setTimeout(this.initQuesBank, 500) |
|
||||||
}, |
|
||||||
'knowledgeKeyword': function (val) { |
|
||||||
clearTimeout(this.searchTimer) |
|
||||||
this.searchTimer = setTimeout(this.getKnowledge, 500) |
|
||||||
}, |
|
||||||
visible () { |
|
||||||
this.quesVisible = this.visible |
|
||||||
this.visible && this.init() |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
|
|
||||||
}, |
|
||||||
methods: { |
|
||||||
// 初始化 |
|
||||||
init () { |
|
||||||
this.handleQuesList() |
|
||||||
if (!this.loaded) { |
|
||||||
this.loaded = 1 |
|
||||||
this.yearCheck = this.years |
|
||||||
this.getQuesBankType() |
|
||||||
this.initQuesBank() |
|
||||||
this.difficult = this.$parent.form.difficult |
|
||||||
this.difficult && this.difficultChange(this.difficult) |
|
||||||
} |
|
||||||
}, |
|
||||||
// 获取题库分类 |
|
||||||
async getQuesBankType () { |
|
||||||
try { |
|
||||||
const { data } = await this.$post(this.api.getAllQuestionBankCategories, { |
|
||||||
createSource: 1, |
|
||||||
status: 1, |
|
||||||
}) |
|
||||||
this.handleList(data) |
|
||||||
this.quesBankTypes = data |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 获取题库 |
|
||||||
async getQuesBank () { |
|
||||||
try { |
|
||||||
const type = this.quesBankTypeVal |
|
||||||
const res = await this.$post(this.api.questionBankList, { |
|
||||||
status: 1, |
|
||||||
pageNum: 1, |
|
||||||
pageSize: 1000, |
|
||||||
questionCategoryId: type.length ? type[type.length - 1] : '', |
|
||||||
name: this.quesBankKeyword |
|
||||||
}) |
|
||||||
this.quesBanks = res.message.records |
|
||||||
this.totalQuesBank = res.message.total |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
initQuesBank () { |
|
||||||
this.curQuesBank = {} |
|
||||||
this.pageQuesBank = 1 |
|
||||||
this.getQuesBank() |
|
||||||
}, |
|
||||||
// 切换页码 |
|
||||||
currentChangeQuesBank (val) { |
|
||||||
this.pageQuesBank = val |
|
||||||
this.getQuesBank() |
|
||||||
}, |
|
||||||
// 题目多选回调 |
|
||||||
questionBankClick (item) { |
|
||||||
this.curQuesBank = item |
|
||||||
this.knowledgeCheck = false |
|
||||||
this.getKnowledgeType() |
|
||||||
this.getKnowledge() |
|
||||||
}, |
|
||||||
|
|
||||||
// 处理树形 |
|
||||||
handleList (list) { |
|
||||||
list.map(e => { |
|
||||||
if (e.children && e.children.length) { |
|
||||||
this.handleList(e.children) |
|
||||||
} else { |
|
||||||
delete e.children |
|
||||||
} |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 获取知识点分类 |
|
||||||
async getKnowledgeType () { |
|
||||||
try { |
|
||||||
const { data } = await this.$post(this.api.classificationTreeStructure, { |
|
||||||
createSource: 1, |
|
||||||
questionBankId: this.curQuesBank.id, |
|
||||||
}) |
|
||||||
this.handleList(data) |
|
||||||
this.knowledgeTypes = data |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 获取知识点 |
|
||||||
async getKnowledge () { |
|
||||||
try { |
|
||||||
const { id } = this.curQuesBank |
|
||||||
if (id) { |
|
||||||
const type = this.knowledgeTypeVal |
|
||||||
const res = await this.$post(this.api.knowledgeHierarchyList, { |
|
||||||
pageNum: 1, |
|
||||||
pageSize: 1000, |
|
||||||
questionBankId: id, |
|
||||||
knowledgePointCategoryId: type.length ? type[type.length - 1] : '', |
|
||||||
name: this.knowledgeKeyword, |
|
||||||
}) |
|
||||||
const list = res.message.records |
|
||||||
const { allKnowledges } = this |
|
||||||
list.map(e => { |
|
||||||
e.check = !!allKnowledges.find(n => n.id === e.id) |
|
||||||
}) |
|
||||||
this.knowledges = list |
|
||||||
} |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 切换页码 |
|
||||||
currentChangeKn (val) { |
|
||||||
this.pageKn = val |
|
||||||
this.getKnowledge() |
|
||||||
}, |
|
||||||
// 知识点全选回调 |
|
||||||
knowledgeAllCheckChange (val) { |
|
||||||
this.knowledges.map(e => { |
|
||||||
e.check = val |
|
||||||
this.knowledgeChange(val, e) |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 知识点勾选回调 |
|
||||||
knowledgeChange (checked, data) { |
|
||||||
const checkQues = this.curQuesBank |
|
||||||
const index = this.checked.findIndex(e => e.quesBank.id === checkQues.id) |
|
||||||
// 已选中的题库数组里有该题库,则往该题库的知识点数组里 |
|
||||||
if (index !== -1) { |
|
||||||
const ques = this.checked[index] |
|
||||||
const i = ques.knowledges.findIndex(e => e.id === data.id) |
|
||||||
if (checked && i === -1) { |
|
||||||
ques.knowledges.push(data) |
|
||||||
} else if (!checked && i >= 0) { |
|
||||||
ques.knowledges.splice(i, 1) |
|
||||||
} |
|
||||||
ques.knowledges.length || this.checked.splice(index, 1) |
|
||||||
} else { |
|
||||||
this.checked.push({ |
|
||||||
quesBank: checkQues, |
|
||||||
knowledges: [data] |
|
||||||
}) |
|
||||||
} |
|
||||||
}, |
|
||||||
// 处理大纲列表 |
|
||||||
handleQuesList () { |
|
||||||
this.list = _.cloneDeep(this.$parent.form.paperOutline) |
|
||||||
}, |
|
||||||
// 清空已选 |
|
||||||
async clearChecked () { |
|
||||||
try { |
|
||||||
await this.$confirm(`确认要清空吗?`, '提示', { |
|
||||||
confirmButtonText: '确定', |
|
||||||
cancelButtonText: '取消', |
|
||||||
type: 'warning', |
|
||||||
closeOnClickModal: false, |
|
||||||
}) |
|
||||||
this.knowledges.map(e => e.check = false) |
|
||||||
this.checked = [] |
|
||||||
this.knowledgeCheck = false |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 删除题库 |
|
||||||
async delQuesBank (i) { |
|
||||||
try { |
|
||||||
await this.$confirm(`确认要移除吗?`, '提示', { |
|
||||||
confirmButtonText: '确定', |
|
||||||
cancelButtonText: '取消', |
|
||||||
type: 'warning', |
|
||||||
closeOnClickModal: false, |
|
||||||
}) |
|
||||||
const k = this.knowledges |
|
||||||
this.checked[i].knowledges.map(e => { |
|
||||||
const cur = k.findIndex(n => n.id === e.id) |
|
||||||
if (cur !== -1) k[cur].check = false |
|
||||||
}) |
|
||||||
this.checked.splice(i, 1) |
|
||||||
this.knowledgeCheck = false |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 删除知识点 |
|
||||||
delKnowledge (i, j, item, k) { |
|
||||||
const cur = this.knowledges.findIndex(e => e.id === k.id) |
|
||||||
if (cur !== -1) this.knowledges[cur].check = false |
|
||||||
item.knowledges.splice(j, 1) |
|
||||||
item.knowledges.length || this.checked.splice(i, 1) // 知识点清空了则把该题库删除 |
|
||||||
this.knowledgeCheck = false |
|
||||||
}, |
|
||||||
|
|
||||||
|
|
||||||
// 试卷难度选择回调 |
|
||||||
difficultChange (val) { |
|
||||||
const difficultyWeights = [0.2, 0.4, 0.6, 0.8] |
|
||||||
const names = ['basicDifficulty', 'normalDifficulty', 'hardDifficulty', 'veryHardDifficulty'] |
|
||||||
// 遍历题型数组 |
|
||||||
this.list.forEach(e => { |
|
||||||
const total = e.questionNum |
|
||||||
|
|
||||||
let already = 0 // 已经分配的数量 |
|
||||||
if (val === 1) { |
|
||||||
this.$set(e, 'basicDifficulty', Math.floor(total * 0.7)) |
|
||||||
this.$set(e, 'normalDifficulty', Math.floor(total * 0.3)) |
|
||||||
this.$set(e, 'hardDifficulty', 0) |
|
||||||
this.$set(e, 'veryHardDifficulty', 0) |
|
||||||
} else if (val === 2) { |
|
||||||
this.$set(e, 'basicDifficulty', Math.floor(total * 0.45)) |
|
||||||
this.$set(e, 'normalDifficulty', Math.floor(total * 0.55)) |
|
||||||
this.$set(e, 'hardDifficulty', 0) |
|
||||||
this.$set(e, 'veryHardDifficulty', 0) |
|
||||||
} else if (val === 3) { |
|
||||||
this.$set(e, 'basicDifficulty', Math.floor(total * 0.3)) |
|
||||||
this.$set(e, 'normalDifficulty', Math.floor(total * 0.3)) |
|
||||||
this.$set(e, 'hardDifficulty', Math.floor(total * 0.4)) |
|
||||||
this.$set(e, 'veryHardDifficulty', 0) |
|
||||||
} else if (val === 4) { |
|
||||||
this.$set(e, 'basicDifficulty', Math.floor(total * 0.1)) |
|
||||||
this.$set(e, 'normalDifficulty', Math.floor(total * 0.1)) |
|
||||||
this.$set(e, 'hardDifficulty', Math.floor(total * 0.3)) |
|
||||||
this.$set(e, 'veryHardDifficulty', Math.floor(total * 0.5)) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
already = Decimal(already).add(e.basicDifficulty).add(e.normalDifficulty).add(e.hardDifficulty).add(e.veryHardDifficulty).toNumber() |
|
||||||
// 如果按比例分配还没分配完 |
|
||||||
while (total > already) { |
|
||||||
e[names[val - 1]]++ |
|
||||||
already++ |
|
||||||
} |
|
||||||
this.$set(e, 'randomDifficulty', 0) |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 年份全选回调 |
|
||||||
yearAllChange (val) { |
|
||||||
this.yearCheck = val ? this.years : [] |
|
||||||
}, |
|
||||||
// 年份选择回调 |
|
||||||
yearChange (val) { |
|
||||||
this.yearAll = val.length === 11 |
|
||||||
}, |
|
||||||
// 提交 |
|
||||||
async submit () { |
|
||||||
if (this.submiting) return false |
|
||||||
const { list } = this |
|
||||||
let invalid = 0 |
|
||||||
let totalCount = 0 |
|
||||||
for (const i in list) { |
|
||||||
const e = list[i] |
|
||||||
const name = `第${Util.arabicToChinese(+i + 1)}大题` |
|
||||||
if (!e.questionType) { |
|
||||||
Util.warningMsg(`${name}请先选择题型`) |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
if (!e.questionNum || isNaN(e.questionNum) || e.questionNum <= 0) { |
|
||||||
Util.warningMsg(`${name}的目标题数请输入正整数`) |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
let total = Decimal(e.basicDifficulty || 0).add(e.normalDifficulty || 0).add(e.hardDifficulty || 0).add(e.veryHardDifficulty || 0).toNumber() // 先算前4个难度的题数 |
|
||||||
if (total) { // 前面4个空有填1个,则清空随机 |
|
||||||
this.$set(e, 'randomDifficulty', 0) |
|
||||||
} else { |
|
||||||
total = +e.randomDifficulty || 0 |
|
||||||
} |
|
||||||
|
|
||||||
if (total > e.questionNum) { |
|
||||||
Util.warningMsg(`${name}的小题总数大于目标题数,请重新输入`) |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
e.count = total |
|
||||||
totalCount = Decimal(totalCount).add(total).toNumber() |
|
||||||
} |
|
||||||
if (invalid) return false |
|
||||||
if (!totalCount) return Util.warningMsg(`请填写难度题数`) |
|
||||||
this.submiting = true |
|
||||||
const k = this.allKnowledges.map(e => e.id) |
|
||||||
|
|
||||||
const years = [] |
|
||||||
this.yearCheck.map(e => { |
|
||||||
if (e === '暂无年份') { |
|
||||||
years.push('') |
|
||||||
} else if (e === '更早') { |
|
||||||
// 选的是更早则直接传1990~2005所有年份 |
|
||||||
for (let i = 1990; i < 2006; i++) { |
|
||||||
years.push(i) |
|
||||||
} |
|
||||||
} else { |
|
||||||
years.push(+e) |
|
||||||
} |
|
||||||
}) |
|
||||||
list.map(e => { |
|
||||||
e.givenYears = years |
|
||||||
e.knowledgePointsIds = k |
|
||||||
}) |
|
||||||
try { |
|
||||||
const res = await this.$post(this.api.selectQuestionsByTypeAndDifficulty, list) |
|
||||||
|
|
||||||
let invalid = 0 |
|
||||||
let hasQues = 0 |
|
||||||
list.map((e, i) => { |
|
||||||
if (+e.count !== res.list[i].questions.length) invalid = 1 |
|
||||||
if (e.examQuestions.length) hasQues = 1 |
|
||||||
e.score = 0 |
|
||||||
}) |
|
||||||
|
|
||||||
// 3种情况提示不一样 |
|
||||||
const tips = invalid && hasQues ? |
|
||||||
'此操作会清空当前试卷已添加的试题,并且满足自动选题设置的试题数量不足,确定要继续自动选题吗?' : |
|
||||||
invalid && !hasQues ? |
|
||||||
'满足自动选题设置的试题数量不足,确认要继续自动选题吗?' : |
|
||||||
!invalid && hasQues ? '此操作会清空当前试卷已添加的试题,是否确定要继续自动选题吗?' : |
|
||||||
'' |
|
||||||
|
|
||||||
if (tips) { |
|
||||||
await this.$confirm(tips, '提示', { |
|
||||||
confirmButtonText: '确定', |
|
||||||
cancelButtonText: '取消', |
|
||||||
type: 'warning', |
|
||||||
closeOnClickModal: false, |
|
||||||
}) |
|
||||||
} |
|
||||||
list.map((e, i) => { |
|
||||||
res.list[i].questions.map((e, i) => { |
|
||||||
e.questionId = e.id |
|
||||||
e.serialNumber = i + 1 |
|
||||||
e.originSort = i + 1 |
|
||||||
this.$parent.handleQuesInfo(e) |
|
||||||
}) |
|
||||||
this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions |
|
||||||
}) |
|
||||||
this.quesVisible = false |
|
||||||
this.$parent.calcDifficult() |
|
||||||
this.submiting = false |
|
||||||
} catch (e) { |
|
||||||
this.submiting = false |
|
||||||
} |
|
||||||
}, |
|
||||||
// 弹框关闭回调 |
|
||||||
closeDia () { |
|
||||||
this.$emit('update:visible', false) |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
/deep/.ques-dia { |
|
||||||
.el-drawer__header { |
|
||||||
margin-bottom: 20px; |
|
||||||
} |
|
||||||
|
|
||||||
.overflow { |
|
||||||
height: calc(100vh - 147px); |
|
||||||
padding: 0 20px; |
|
||||||
overflow: auto; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
.wrap { |
|
||||||
display: flex; |
|
||||||
margin-top: 20px; |
|
||||||
border: 1px solid #eee; |
|
||||||
|
|
||||||
.filter { |
|
||||||
margin-bottom: 15px; |
|
||||||
|
|
||||||
li { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
label { |
|
||||||
margin-right: 10px; |
|
||||||
font-size: 14px; |
|
||||||
color: #333; |
|
||||||
white-space: nowrap; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.item { |
|
||||||
width: 30%; |
|
||||||
padding: 15px; |
|
||||||
border-right: 1px solid #eee; |
|
||||||
|
|
||||||
&:last-child { |
|
||||||
width: 40%; |
|
||||||
border-right: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.total { |
|
||||||
font-size: 16px; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
|
|
||||||
.clear { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
font-size: 14px; |
|
||||||
color: #8b8b8b; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
|
|
||||||
.knowledges { |
|
||||||
padding-left: 44px; |
|
||||||
margin-top: 10px; |
|
||||||
} |
|
||||||
|
|
||||||
.lines { |
|
||||||
height: calc(100vh - 392px); |
|
||||||
overflow: auto; |
|
||||||
} |
|
||||||
|
|
||||||
.line { |
|
||||||
display: flex; |
|
||||||
padding: 5px 0; |
|
||||||
color: #333; |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
.able-check { |
|
||||||
.line { |
|
||||||
cursor: pointer; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
background-color: #f5f5f5; |
|
||||||
} |
|
||||||
|
|
||||||
&.active { |
|
||||||
background-color: #e5e5e5; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.serial { |
|
||||||
width: 32px; |
|
||||||
margin: 0 12px; |
|
||||||
text-align: center; |
|
||||||
white-space: nowrap; |
|
||||||
|
|
||||||
&.first { |
|
||||||
margin-left: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.stem { |
|
||||||
max-width: calc(100% - 71px); |
|
||||||
@include ellipsis; |
|
||||||
} |
|
||||||
|
|
||||||
.checked-stem { |
|
||||||
max-width: 165px; |
|
||||||
@include ellipsis; |
|
||||||
} |
|
||||||
|
|
||||||
.check-left { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.action-icon { |
|
||||||
font-size: 14px; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
File diff suppressed because it is too large
Load Diff
@ -1,610 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<el-drawer :title="diaTitle" :visible.sync="selectQuesVisible" size="1200px" :close-on-click-modal="false" |
|
||||||
custom-class="ques-dia" @closed="closeDia"> |
|
||||||
<div class="wrap"> |
|
||||||
<!-- 题库 --> |
|
||||||
<div class="item"> |
|
||||||
<p class="total m-b-10">题库</p> |
|
||||||
<ul class="filter"> |
|
||||||
<li class="m-b-10"> |
|
||||||
<label>题库分类</label> |
|
||||||
<el-cascader style="width: 240px;" placeholder="请选择题库分类" v-model="quesBankTypeVal" |
|
||||||
:options="quesBankTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable |
|
||||||
@change="initQuesBank"></el-cascader> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" clearable /> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
|
|
||||||
<template v-if="quesBanks.length"> |
|
||||||
<div class="line"> |
|
||||||
<span class="serial">序号</span> |
|
||||||
<span>题库名称</span> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="able-check lines"> |
|
||||||
<div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]" |
|
||||||
@click="questionBankClick(item)"> |
|
||||||
<span class="serial">{{ i + 1 }}</span> |
|
||||||
<p class="quesBank" :title="item.questionBankName">{{ item.questionBankName }}</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<div v-else class="empty"> |
|
||||||
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
|
||||||
<p>暂无数据</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<!-- 题目 --> |
|
||||||
<div class="item"> |
|
||||||
<p class="total m-b-10">{{ questionTypeName }}(共{{ ques.length }}道题)</p> |
|
||||||
|
|
||||||
<ul class="filter"> |
|
||||||
<li class="m-b-10"> |
|
||||||
<label>知识点</label> |
|
||||||
<el-cascader style="width: 240px;" placeholder="请选择知识点" v-model="knowledgeVal" :options="knowledges" |
|
||||||
:props="{ value: 'id', label: 'name', multiple: true }" clearable @change="getQues"></el-cascader> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<el-input placeholder="请输入题干" prefix-icon="el-icon-search" v-model="knowledgeKeyword" clearable /> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
|
|
||||||
<template v-if="ques.length"> |
|
||||||
<div class="line"> |
|
||||||
<el-checkbox v-model="quesAllCheck" @change="quesAllCheckChange"></el-checkbox> |
|
||||||
<span class="serial">序号</span> |
|
||||||
<span class="stem">题干</span> |
|
||||||
<span class="kl">知识点</span> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="lines"> |
|
||||||
<div v-for="(item, i) in ques" :key="i" class="line"> |
|
||||||
<el-checkbox v-model="item.check" :disabled="item.disabled" |
|
||||||
@change="val => quesChange(val, item)"></el-checkbox> |
|
||||||
<span class="serial">{{ i + 1 }}</span> |
|
||||||
<el-tooltip effect="dark" :content="item.stemText" placement="top-start"> |
|
||||||
<p class="stem cursor-pointer" @click="toShowQues(item)">{{ item.stemText }}</p> |
|
||||||
</el-tooltip> |
|
||||||
<el-tooltip effect="dark" :content="item.knowledgePointName" placement="top-start"> |
|
||||||
<p class="kl">{{ item.knowledgePointName }}</p> |
|
||||||
</el-tooltip> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<div v-else class="empty"> |
|
||||||
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
|
||||||
<p>暂无数据</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<!-- 已选试题 --> |
|
||||||
<div class="item"> |
|
||||||
<div v-if="$parent.curQues" class="m-b-20"> |
|
||||||
<p class="total m-b-10">原试题(共1道题)</p> |
|
||||||
<div v-html="$parent.curQues.stemText"></div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="flex j-between a-center"> |
|
||||||
<p v-if="$parent.curQues" class="total">更换试题(共{{ checked.length }}道题)</p> |
|
||||||
<p v-else class="total">已选试题(共{{ checkedLen }}道题)</p> |
|
||||||
<el-button type="text" @click="batchDelChecked">批量移除</el-button> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-input class="m-t-10 m-b-10" placeholder="请输入题干/知识点" prefix-icon="el-icon-search" v-model="checkedKeyword" |
|
||||||
clearable /> |
|
||||||
|
|
||||||
<template v-if="checked.length"> |
|
||||||
<div class="ques"> |
|
||||||
<div class="line"> |
|
||||||
<el-checkbox v-model="checkedAllCheck" @change="checkedAllCheckChange"></el-checkbox> |
|
||||||
<span class="serial">序号</span> |
|
||||||
<span class="stem">题干</span> |
|
||||||
<span class="kl">知识点</span> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div :class="['lines', { switch: $parent.curQues }]"> |
|
||||||
<template v-for="(item, i) in checked"> |
|
||||||
<div v-if="item.stemText.includes(checkedKeyword) || item.knowledgePointName.includes(checkedKeyword)" |
|
||||||
:key="i" class="line"> |
|
||||||
<div class="check-left"> |
|
||||||
<el-checkbox v-model="item.check"></el-checkbox> |
|
||||||
<span class="serial">{{ i + 1 }}</span> |
|
||||||
<el-tooltip effect="dark" :content="item.stemText" placement="top-start"> |
|
||||||
<p class="checked-stem">{{ item.stemText }}</p> |
|
||||||
</el-tooltip> |
|
||||||
<el-tooltip effect="dark" :content="item.knowledgePointName" placement="top-start"> |
|
||||||
<p class="kl checked-kl">{{ item.knowledgePointName }}</p> |
|
||||||
</el-tooltip> |
|
||||||
</div> |
|
||||||
<i class="el-icon-delete action-icon" @click="delChecked(item)"></i> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<div v-else class="empty"> |
|
||||||
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
|
||||||
<p>暂无数据</p> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div class="flex j-between p-l-20 p-r-20"> |
|
||||||
<p>未找到试题,<a class="link" @click="toAddQues">去新增</a></p> |
|
||||||
<p>已选题数/目标题数:{{ checkedLen }}/{{ $parent.curType.questionNum }} |
|
||||||
</p> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="btns"> |
|
||||||
<el-button @click="selectQuesVisible = false">取消</el-button> |
|
||||||
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button> |
|
||||||
</div> |
|
||||||
</el-drawer> |
|
||||||
|
|
||||||
|
|
||||||
<el-drawer title="新增试题" :visible.sync="addQuesVisible" size="1200px" :close-on-click-modal="false" |
|
||||||
custom-class="add-dia"> |
|
||||||
<QuesDetail :key="quesKey" :paperType.sync="paperType" :curQues.sync="curRow" @closeAdd="closeAdd" /> |
|
||||||
</el-drawer> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<script> |
|
||||||
import Setting from '@/setting' |
|
||||||
import Util from '@/libs/util' |
|
||||||
import _ from 'lodash' |
|
||||||
import QuesConst from '@/const/ques' |
|
||||||
import QuesDetail from '@/pages/ques/detail' |
|
||||||
export default { |
|
||||||
props: ['visible', 'questionType'], |
|
||||||
components: { QuesDetail }, |
|
||||||
data () { |
|
||||||
return { |
|
||||||
selectQuesVisible: false, |
|
||||||
searchTimer: null, |
|
||||||
quesBankKeyword: '', |
|
||||||
curQuesBank: {}, |
|
||||||
quesBankTypeVal: [], |
|
||||||
quesBankTypes: [], |
|
||||||
quesBanks: [], |
|
||||||
pageQuesBank: 1, |
|
||||||
pageSizeQuesBank: 10, |
|
||||||
totalQuesBank: 0, |
|
||||||
|
|
||||||
knowledgeKeyword: '', |
|
||||||
key: 1, |
|
||||||
knowledgeVal: [], |
|
||||||
knowledges: [], |
|
||||||
quesAllCheck: false, |
|
||||||
ques: [], |
|
||||||
checkedAllCheck: false, |
|
||||||
checked: [], |
|
||||||
curCheckQues: [], |
|
||||||
checkedKeyword: '', |
|
||||||
submiting: false, |
|
||||||
|
|
||||||
quesVisible: false, |
|
||||||
curRow: {}, |
|
||||||
addQuesVisible: false, |
|
||||||
quesKey: 1, |
|
||||||
paperType: 1, |
|
||||||
}; |
|
||||||
}, |
|
||||||
computed: { |
|
||||||
// 外面已经添加的试题+当前弹框已经勾选的试题 |
|
||||||
checkedLen () { |
|
||||||
let len = this.curCheckQues.length + this.checked.length |
|
||||||
if (this.$parent.curQues) len -= 1 |
|
||||||
return len |
|
||||||
}, |
|
||||||
// 题型name |
|
||||||
questionTypeName () { |
|
||||||
return this.questionType ? QuesConst.questionTypes.find(e => e.id === this.questionType).name : '' |
|
||||||
}, |
|
||||||
// 弹框标题 |
|
||||||
diaTitle () { |
|
||||||
const { curQuesIndex, curQues } = this.$parent |
|
||||||
return curQues ? |
|
||||||
'更换试题' : |
|
||||||
typeof curQuesIndex === 'number' ? |
|
||||||
'添加试题' : |
|
||||||
this.questionType ? `批量添加${QuesConst.questionTypes.find(e => e.id === this.questionType).name}` : '' |
|
||||||
}, |
|
||||||
}, |
|
||||||
watch: { |
|
||||||
'quesBankKeyword': function (val) { |
|
||||||
clearTimeout(this.searchTimer) |
|
||||||
this.searchTimer = setTimeout(this.initQuesBank, 500) |
|
||||||
}, |
|
||||||
'knowledgeKeyword': function (val) { |
|
||||||
clearTimeout(this.searchTimer) |
|
||||||
this.searchTimer = setTimeout(this.getQues, 500) |
|
||||||
}, |
|
||||||
visible () { |
|
||||||
this.selectQuesVisible = this.visible |
|
||||||
this.visible && this.init() |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
|
|
||||||
}, |
|
||||||
methods: { |
|
||||||
init () { |
|
||||||
// 清空所有状态和数据 |
|
||||||
this.key++ |
|
||||||
this.knowledges = [] |
|
||||||
this.ques = [] |
|
||||||
this.checked = [] |
|
||||||
this.quesAllCheck = false |
|
||||||
this.checkedAllCheck = false |
|
||||||
this.quesBankKeyword = '' |
|
||||||
this.knowledgeKeyword = '' |
|
||||||
|
|
||||||
// 当前大题的小题列表 |
|
||||||
const { curType, curQues } = this.$parent |
|
||||||
if (curQues) curQues.stemText = Util.delTag(curQues.stem) |
|
||||||
this.curCheckQues = curType.examQuestions |
|
||||||
|
|
||||||
this.getQuesBankType() |
|
||||||
this.initQuesBank() |
|
||||||
}, |
|
||||||
// 获取题库分类 |
|
||||||
async getQuesBankType () { |
|
||||||
try { |
|
||||||
const { data } = await this.$post(this.api.getAllQuestionBankCategories, { |
|
||||||
createSource: 1, |
|
||||||
status: 1, |
|
||||||
}) |
|
||||||
this.handleList(data) |
|
||||||
this.quesBankTypes = data |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 获取题库 |
|
||||||
async getQuesBank () { |
|
||||||
try { |
|
||||||
const type = this.quesBankTypeVal |
|
||||||
const res = await this.$post(this.api.questionBankList, { |
|
||||||
status: 1, |
|
||||||
pageNum: 1, |
|
||||||
pageSize: 1000, |
|
||||||
questionCategoryId: type.length ? type[type.length - 1] : '', |
|
||||||
name: this.quesBankKeyword |
|
||||||
}) |
|
||||||
const { records } = res.message |
|
||||||
this.quesBanks = records |
|
||||||
this.totalQuesBank = res.message.total |
|
||||||
records.length && this.questionBankClick(records[0]) |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
initQuesBank () { |
|
||||||
this.curQuesBank = {} |
|
||||||
this.pageQuesBank = 1 |
|
||||||
this.getQuesBank() |
|
||||||
}, |
|
||||||
// 切换页码 |
|
||||||
currentChangeQuesBank (val) { |
|
||||||
this.pageQuesBank = val |
|
||||||
this.getQuesBank() |
|
||||||
}, |
|
||||||
// 题目多选回调 |
|
||||||
questionBankClick (item) { |
|
||||||
this.curQuesBank = item |
|
||||||
this.knowledgeCheck = false |
|
||||||
this.getKnowledge() |
|
||||||
this.getQues() |
|
||||||
this.quesAllCheck = false |
|
||||||
}, |
|
||||||
|
|
||||||
// 处理树形 |
|
||||||
handleList (list) { |
|
||||||
list.map(e => { |
|
||||||
if (e.children && e.children.length) { |
|
||||||
this.handleList(e.children) |
|
||||||
} else { |
|
||||||
delete e.children |
|
||||||
} |
|
||||||
}) |
|
||||||
}, |
|
||||||
|
|
||||||
// 获取知识点 |
|
||||||
async getKnowledge () { |
|
||||||
try { |
|
||||||
const { id } = this.curQuesBank |
|
||||||
if (id) { |
|
||||||
const { data } = await this.$post(this.api.TreeStructure, { |
|
||||||
createSource: 1, |
|
||||||
questionBankId: id, |
|
||||||
keyword: '', |
|
||||||
}) |
|
||||||
this.handleList(data) |
|
||||||
this.knowledges = data |
|
||||||
} |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 获取试题 |
|
||||||
async getQues () { |
|
||||||
const { id } = this.curQuesBank |
|
||||||
let k = this.knowledgeVal // 选中的知识点 |
|
||||||
k = k.map(e => { |
|
||||||
return e[e.length - 1] |
|
||||||
}) |
|
||||||
if (id) { |
|
||||||
const { list } = await this.$post(this.api.findAllByQuestionBank, { |
|
||||||
status: 1, |
|
||||||
questionBankIds: [id], |
|
||||||
knowledgePointIds: k, |
|
||||||
questionTypes: this.questionType ? [this.questionType] : [], |
|
||||||
keyword: this.knowledgeKeyword, |
|
||||||
}) |
|
||||||
const data = list |
|
||||||
const { curCheckQues, checked } = this |
|
||||||
data.map(e => { |
|
||||||
e.stemText = Util.delTag(e.stem) |
|
||||||
const quesChecked = !!curCheckQues.find(n => n.questionVersionId === e.questionVersionId) |
|
||||||
e.disabled = quesChecked |
|
||||||
e.check = !!checked.find(n => n.questionVersionId === e.questionVersionId) || quesChecked |
|
||||||
}) |
|
||||||
this.ques = data |
|
||||||
} |
|
||||||
}, |
|
||||||
// 知识点勾选回调 |
|
||||||
knowledgeCheck () { |
|
||||||
|
|
||||||
}, |
|
||||||
// 题目全选回调 |
|
||||||
quesAllCheckChange (val) { |
|
||||||
this.ques.map(e => { |
|
||||||
if (!e.disabled) { |
|
||||||
e.check = val |
|
||||||
this.quesChange(val, e) |
|
||||||
} |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 题目多选回调 |
|
||||||
quesChange (val, item) { |
|
||||||
const cur = this.checked.findIndex(e => e.questionVersionId === item.questionVersionId) |
|
||||||
// 选中 |
|
||||||
if (val) { |
|
||||||
if (cur === -1) { |
|
||||||
const e = _.cloneDeep(item) |
|
||||||
e.check = false |
|
||||||
this.checked.push(e) |
|
||||||
} |
|
||||||
} else { |
|
||||||
// 取消选中 |
|
||||||
cur >= 0 && this.checked.splice(cur, 1) |
|
||||||
} |
|
||||||
}, |
|
||||||
// 已选试题全选回调 |
|
||||||
checkedAllCheckChange (val) { |
|
||||||
this.checked.map(e => e.check = val) |
|
||||||
}, |
|
||||||
// 批量移除已选试题 |
|
||||||
async batchDelChecked (val) { |
|
||||||
try { |
|
||||||
const checked = this.checked.filter(e => e.check) |
|
||||||
if (checked.length) { |
|
||||||
checked.map(e => { |
|
||||||
const cur = this.ques.find(n => n.questionVersionId === e.questionVersionId) |
|
||||||
if (cur) { |
|
||||||
cur.check = false |
|
||||||
} |
|
||||||
}) |
|
||||||
this.quesAllCheck = false |
|
||||||
this.checkedAllCheck = false |
|
||||||
this.checked = this.checked.filter(e => !e.check) |
|
||||||
} else { |
|
||||||
Util.warningMsg('请选择数据') |
|
||||||
} |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 已选试题单个删除 |
|
||||||
async delChecked (item) { |
|
||||||
try { |
|
||||||
const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId) |
|
||||||
if (cur) cur.check = false |
|
||||||
this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1) |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 新增试题 |
|
||||||
toAddQues () { |
|
||||||
this.quesKey++ |
|
||||||
this.paperType = 1 |
|
||||||
this.addQuesVisible = true |
|
||||||
}, |
|
||||||
// 查看试题 |
|
||||||
toShowQues (ques) { |
|
||||||
this.quesKey++ |
|
||||||
this.curRow = ques |
|
||||||
this.paperType = 3 |
|
||||||
this.addQuesVisible = true |
|
||||||
}, |
|
||||||
// 关闭新增试题弹框 |
|
||||||
closeAdd () { |
|
||||||
this.addQuesVisible = false |
|
||||||
}, |
|
||||||
// 提交 |
|
||||||
async submit () { |
|
||||||
if (this.submiting) return false |
|
||||||
const checked = _.cloneDeep(this.checked) |
|
||||||
if (!checked.length) return Util.warningMsg('请选择试题') |
|
||||||
|
|
||||||
const { curType, curQuesIndex, curQues } = this.$parent |
|
||||||
if (this.checkedLen > +curType.questionNum) return Util.warningMsg(`目标题数为${curType.questionNum},已选题数不得大于目标题数`) |
|
||||||
|
|
||||||
try { |
|
||||||
checked.map((e, i) => { |
|
||||||
this.$set(e, 'check', false) |
|
||||||
this.$set(e, 'sort', i + 1) |
|
||||||
this.$set(e, 'originSort', i + 1) |
|
||||||
this.$set(e, 'score', '') |
|
||||||
this.$parent.handleQuesInfo(e) |
|
||||||
}) |
|
||||||
|
|
||||||
if (curQues) { |
|
||||||
// curQues即是小题,有则说明是更换试题,需要把该小题去掉,再添加进选中的试题 |
|
||||||
this.curCheckQues.splice(curQuesIndex, 1, ...checked) |
|
||||||
} else { |
|
||||||
// curQuesIndex为数字,则是小题里面的添加试题打开的弹框,则把选择的试题添加到该小题后面;否则直接添加到最后面 |
|
||||||
typeof curQuesIndex === 'number' ? |
|
||||||
this.curCheckQues.splice(curQuesIndex + 1, 0, ...checked) : |
|
||||||
this.curCheckQues.push(...checked) |
|
||||||
} |
|
||||||
// 给题目重新排序 |
|
||||||
this.curCheckQues.map((e, i) => { |
|
||||||
this.$set(e, 'serialNumber', i + 1) |
|
||||||
}) |
|
||||||
|
|
||||||
this.$parent.calcDifficult() |
|
||||||
this.selectQuesVisible = false |
|
||||||
this.submiting = false |
|
||||||
} catch (e) { |
|
||||||
this.submiting = false |
|
||||||
} |
|
||||||
}, |
|
||||||
// 弹框关闭回调 |
|
||||||
closeDia () { |
|
||||||
this.$emit('update:visible', false) |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
/deep/.ques-dia { |
|
||||||
.el-drawer__header { |
|
||||||
margin-bottom: 20px; |
|
||||||
} |
|
||||||
|
|
||||||
.wrap { |
|
||||||
display: flex; |
|
||||||
margin-bottom: 10px; |
|
||||||
border: 1px solid #eee; |
|
||||||
|
|
||||||
.filter { |
|
||||||
margin-bottom: 15px; |
|
||||||
|
|
||||||
li { |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
label { |
|
||||||
margin-right: 10px; |
|
||||||
font-size: 14px; |
|
||||||
color: #333; |
|
||||||
white-space: nowrap; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.item { |
|
||||||
width: 38%; |
|
||||||
padding: 15px; |
|
||||||
border-right: 1px solid #eee; |
|
||||||
|
|
||||||
&:first-child { |
|
||||||
width: 24%; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.total { |
|
||||||
font-size: 16px; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
|
|
||||||
.lines { |
|
||||||
height: calc(100vh - 358px); |
|
||||||
overflow: auto; |
|
||||||
} |
|
||||||
|
|
||||||
.ques { |
|
||||||
.lines { |
|
||||||
height: calc(100vh - 328px); |
|
||||||
overflow: auto; |
|
||||||
|
|
||||||
&.switch { |
|
||||||
height: calc(100vh - 394px); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.line { |
|
||||||
display: flex; |
|
||||||
padding: 5px 0; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
|
|
||||||
.able-check { |
|
||||||
.line { |
|
||||||
cursor: pointer; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
background-color: #f5f5f5; |
|
||||||
} |
|
||||||
|
|
||||||
&.active { |
|
||||||
background-color: #e5e5e5; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.serial { |
|
||||||
width: 32px; |
|
||||||
margin: 0 12px; |
|
||||||
text-align: center; |
|
||||||
white-space: nowrap; |
|
||||||
} |
|
||||||
|
|
||||||
.quesBank { |
|
||||||
width: calc(100% - 71px); |
|
||||||
@include ellipsis; |
|
||||||
} |
|
||||||
|
|
||||||
.stem { |
|
||||||
width: calc(100% - 210px); |
|
||||||
margin-right: 20px; |
|
||||||
@include ellipsis; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
opacity: .9; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.kl { |
|
||||||
width: 120px; |
|
||||||
@include ellipsis; |
|
||||||
|
|
||||||
&.checked-kl { |
|
||||||
width: 100px; |
|
||||||
margin-right: 10px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.checked-stem { |
|
||||||
width: 190px; |
|
||||||
margin-right: 20px; |
|
||||||
@include ellipsis; |
|
||||||
} |
|
||||||
|
|
||||||
.check-left { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.action-icon { |
|
||||||
font-size: 14px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.link { |
|
||||||
color: $main-color; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/deep/.add-dia { |
|
||||||
.el-drawer__header { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
@ -1,119 +0,0 @@ |
|||||||
<template> |
|
||||||
<el-drawer title="提示" :visible.sync="listVisible" size="800px" :close-on-press-escape="false" :wrapperClosable="false" |
|
||||||
:show-close="false" custom-class="ques-dia" @closed="closeDia"> |
|
||||||
<div class="wrap p-20"> |
|
||||||
<el-alert title="以下试题在试卷中疑似出现重复,是否要继续发布!" type="warning" effect="dark" :closable="false" /> |
|
||||||
<el-table class="m-t-10" :data="data" stripe header-align="center" row-key="uuid"> |
|
||||||
<el-table-column prop="outlineName" label="大题名称" align="center" width="90"></el-table-column> |
|
||||||
<el-table-column prop="serialNumber" label="题号" align="center" width="60"></el-table-column> |
|
||||||
<el-table-column prop="stem" label="题干" align="center" min-width="120"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<div v-html="scope.row.stem"></div> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="操作" align="center" width="140"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-button type="text" @click="toQues(scope.row)">详情</el-button> |
|
||||||
<el-button type="text" @click="delQues(scope.row, scope.$index)">移除</el-button> |
|
||||||
<!-- <el-button type="text" @click="switchQues(scope.row, scope.$index)">替换</el-button> --> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
</div> |
|
||||||
<div class="btns"> |
|
||||||
<el-button type="primary" @click="check">检查一下</el-button> |
|
||||||
<el-button :loading="submiting" @click="submit">继续发布</el-button> |
|
||||||
</div> |
|
||||||
</el-drawer> |
|
||||||
</template> |
|
||||||
<script> |
|
||||||
import _ from 'lodash' |
|
||||||
export default { |
|
||||||
props: ['visible', 'list'], |
|
||||||
data () { |
|
||||||
return { |
|
||||||
listVisible: false, |
|
||||||
data: [], |
|
||||||
submiting: false, |
|
||||||
}; |
|
||||||
}, |
|
||||||
watch: { |
|
||||||
visible () { |
|
||||||
this.listVisible = this.visible |
|
||||||
this.visible && this.init() |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
|
|
||||||
}, |
|
||||||
methods: { |
|
||||||
init () { |
|
||||||
this.data = this.list |
|
||||||
}, |
|
||||||
// 详情 |
|
||||||
toQues (row) { |
|
||||||
const paper = this.$parent.form.paperOutline |
|
||||||
this.$parent.toQues(paper[row.paperIndex], row.quesIndex, paper[row.paperIndex].examQuestions[row.quesIndex], 3) |
|
||||||
}, |
|
||||||
// 移除 |
|
||||||
async delQues (row, i) { |
|
||||||
try { |
|
||||||
await this.$confirm(`确认要移除吗?`, '提示', { |
|
||||||
confirmButtonText: '确定', |
|
||||||
cancelButtonText: '取消', |
|
||||||
type: 'warning', |
|
||||||
closeOnClickModal: false, |
|
||||||
}) |
|
||||||
this.$parent.delQues(this.$parent.form.paperOutline[row.paperIndex], row.quesIndex, 1) |
|
||||||
|
|
||||||
const { data } = this |
|
||||||
data.splice(i, 1) |
|
||||||
data.map(e => e.repeat = false) |
|
||||||
this.data = this.$parent.hasRepeatQues(data) |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 替换 |
|
||||||
switchQues (row) { |
|
||||||
const paper = this.$parent.form.paperOutline |
|
||||||
this.$parent.showManualDia(paper[row.paperIndex], row.quesIndex, paper[row.paperIndex].examQuestions[row.quesIndex]) |
|
||||||
this.listVisible = false |
|
||||||
}, |
|
||||||
// 检查一下 |
|
||||||
async check () { |
|
||||||
const { data } = this |
|
||||||
this.$parent.form.paperOutline.map(e => { |
|
||||||
e.examQuestions.map(n => { |
|
||||||
this.$set(n, 'repeat', !!data.find(m => m.questionVersionId === n.questionVersionId)) |
|
||||||
}) |
|
||||||
}) |
|
||||||
this.$parent.submiting = false |
|
||||||
this.listVisible = false |
|
||||||
}, |
|
||||||
// 提交 |
|
||||||
async submit () { |
|
||||||
if (this.submiting) return false |
|
||||||
this.submiting = true |
|
||||||
await this.$parent.saveTestPaper() |
|
||||||
this.submiting = false |
|
||||||
}, |
|
||||||
// 弹框关闭回调 |
|
||||||
closeDia () { |
|
||||||
this.$parent.submiting = false |
|
||||||
this.$emit('update:visible', false) |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
/deep/.ques-dia { |
|
||||||
.el-drawer__header { |
|
||||||
margin-bottom: 0; |
|
||||||
} |
|
||||||
|
|
||||||
.wrap { |
|
||||||
max-height: calc(100vh - 110px); |
|
||||||
overflow: auto; |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
@ -1,329 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<el-dialog title="选择试卷大纲模板" :visible.sync="listVisible" width="1200px" :close-on-click-modal="false" |
|
||||||
@closed="closeDia"> |
|
||||||
<div class="tool"> |
|
||||||
<ul class="filter"> |
|
||||||
<li> |
|
||||||
<label>题型</label> |
|
||||||
<el-select v-model="questionType" multiple clearable placeholder="请选择题目类型" @change="initData"> |
|
||||||
<el-option v-for="(item, i) in questionTypes" :key="i" :value="item.id" :label="item.name"></el-option> |
|
||||||
</el-select> |
|
||||||
</li> |
|
||||||
<li> |
|
||||||
<label>搜索</label> |
|
||||||
<el-input style="width: 250px;" placeholder="请输入模板名称" prefix-icon="el-icon-search" v-model="templateName" |
|
||||||
clearable /> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
<div> |
|
||||||
<el-button type="primary" @click="add">新增模板</el-button> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-table :data="list" stripe header-align="center" row-key="libraryId"> |
|
||||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
|
||||||
<el-table-column prop="templateName" label="模板名称" align="center" min-width="100"></el-table-column> |
|
||||||
<el-table-column prop="questionTypeName" label="题型" align="center" min-width="140"></el-table-column> |
|
||||||
<el-table-column prop="outlineNum" label="大题数" align="center" width="60"></el-table-column> |
|
||||||
<el-table-column prop="questionNum" label="小题总数" align="center" width="80"></el-table-column> |
|
||||||
<el-table-column prop="totalScore" label="总分" align="center" width="60"></el-table-column> |
|
||||||
<el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column> |
|
||||||
<el-table-column prop="createUser" label="创建人" align="center" width="80"></el-table-column> |
|
||||||
<el-table-column label="操作" align="center" width="150"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-button type="text" @click="useTemplate(scope.row, 0)">使用模板</el-button> |
|
||||||
<el-button type="text" @click="edit(scope.row, 1)">编辑</el-button> |
|
||||||
<el-button type="text" @click="del(scope.row)">删除</el-button> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
<div class="pagination"> |
|
||||||
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" |
|
||||||
:total="total"></el-pagination> |
|
||||||
</div> |
|
||||||
<span slot="footer" class="dialog-footer"> |
|
||||||
<el-button @click="listVisible = false">关闭</el-button> |
|
||||||
</span> |
|
||||||
</el-dialog> |
|
||||||
|
|
||||||
<el-dialog title="新增模板" :visible.sync="detailVisible" width="800px" :close-on-click-modal="false"> |
|
||||||
<el-form :model="form" :rules="rules" label-width="100px"> |
|
||||||
<el-form-item prop="templateName" label="模板名称"> |
|
||||||
<el-input placeholder="请输入模板名称" v-model="form.templateName" /> |
|
||||||
</el-form-item> |
|
||||||
</el-form> |
|
||||||
|
|
||||||
<el-table :data="form.paperOutline" stripe header-align="center" row-key="id"> |
|
||||||
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> |
|
||||||
<el-table-column prop="outlineName" label="大题" align="center" min-width="120"> |
|
||||||
<template slot-scope="scope">第{{ arabicToChinese(scope.$index + 1) }}大题</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column prop="name" label="题型" align="center" min-width="120"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-select v-model="scope.row.questionType" placeholder="请选择题型"> |
|
||||||
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.id"></el-option> |
|
||||||
</el-select> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column prop="name" label="目标题数" align="center" min-width="120"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input placeholder="请输入目标题数" v-model="scope.row.questionNum" type="number" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column prop="name" label="目标分值" align="center" min-width="120"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<el-input placeholder="请输入目标分值" v-model="scope.row.targetScore" /> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="操作" align="center" width="120"> |
|
||||||
<template slot-scope="scope"> |
|
||||||
<i class="el-icon-circle-plus-outline action-icon m-r-10" @click="addLine(scope.$index)"></i> |
|
||||||
<i v-if="form.paperOutline.length > 1" class="el-icon-remove-outline action-icon" |
|
||||||
@click="delLine(scope.$index)"></i> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
<p class="m-t-10 text-right">目标总题数:{{ questionNum }};目标总分:{{ totalScore }}</p> |
|
||||||
<span slot="footer" class="dialog-footer"> |
|
||||||
<el-button @click="detailVisible = false">取消</el-button> |
|
||||||
<el-button type="primary" v-loading="submiting" @click="submit">保存模板</el-button> |
|
||||||
</span> |
|
||||||
</el-dialog> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<script> |
|
||||||
import Setting from '@/setting' |
|
||||||
import Util from '@/libs/util' |
|
||||||
import _ from 'lodash' |
|
||||||
import QuesConst from '@/const/ques' |
|
||||||
export default { |
|
||||||
props: ['visible'], |
|
||||||
data () { |
|
||||||
return { |
|
||||||
arabicToChinese: Util.arabicToChinese, |
|
||||||
questionTypes: QuesConst.questionTypes, |
|
||||||
listVisible: false, |
|
||||||
searchTimer: null, |
|
||||||
|
|
||||||
templateName: '', |
|
||||||
questionType: [], |
|
||||||
list: [], |
|
||||||
page: 1, |
|
||||||
pageSize: 10, |
|
||||||
total: 0, |
|
||||||
|
|
||||||
detailVisible: false, |
|
||||||
originForm: {}, |
|
||||||
form: { |
|
||||||
templateName: '', |
|
||||||
paperOutline: [ |
|
||||||
{ |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '单选题', |
|
||||||
questionNum: '', |
|
||||||
questionType: 'single_choice', |
|
||||||
targetScore: '', |
|
||||||
}, |
|
||||||
{ |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '多选题', |
|
||||||
questionNum: '', |
|
||||||
questionType: 'multiple_choice', |
|
||||||
targetScore: '', |
|
||||||
}, |
|
||||||
{ |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '判断题', |
|
||||||
questionNum: '', |
|
||||||
questionType: 'judgement', |
|
||||||
targetScore: '', |
|
||||||
}, |
|
||||||
{ |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '填空题', |
|
||||||
questionNum: '', |
|
||||||
questionType: 'fill_blank', |
|
||||||
targetScore: '', |
|
||||||
}, |
|
||||||
{ |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '问答题', |
|
||||||
questionNum: '', |
|
||||||
questionType: 'essay', |
|
||||||
targetScore: '', |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
rules: { |
|
||||||
templateName: [ |
|
||||||
{ required: true, message: '请输入模板名称', trigger: 'blur' } |
|
||||||
], |
|
||||||
}, |
|
||||||
submiting: false, |
|
||||||
|
|
||||||
}; |
|
||||||
}, |
|
||||||
computed: { |
|
||||||
questionNum () { |
|
||||||
return this.form.paperOutline.reduce((e, j) => (e += +j.questionNum), 0) |
|
||||||
}, |
|
||||||
totalScore () { |
|
||||||
return this.form.paperOutline.reduce((e, j) => (e += +j.targetScore), 0) |
|
||||||
} |
|
||||||
}, |
|
||||||
watch: { |
|
||||||
templateName: function (val) { |
|
||||||
clearTimeout(this.searchTimer) |
|
||||||
this.searchTimer = setTimeout(this.initData, 500) |
|
||||||
}, |
|
||||||
visible () { |
|
||||||
this.listVisible = this.visible |
|
||||||
this.visible && this.getList() |
|
||||||
} |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
this.originForm = _.cloneDeep(this.form) |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
// 获取模板列表 |
|
||||||
async getList () { |
|
||||||
try { |
|
||||||
const res = await this.$post(this.api.examPaperTemplateList, { |
|
||||||
pageNum: this.page, |
|
||||||
pageSize: this.pageSize, |
|
||||||
questionType: this.questionType.join(), |
|
||||||
templateName: this.templateName |
|
||||||
}) |
|
||||||
const list = res.pageList.records |
|
||||||
const types = QuesConst.questionTypes |
|
||||||
list.map(e => { |
|
||||||
const names = [] |
|
||||||
e.questionType.split('、').map(n => { |
|
||||||
const item = types.find(m => m.id === n) |
|
||||||
item && names.push(item.name) |
|
||||||
}) |
|
||||||
if (names.length) e.questionTypeName = names.join('、') |
|
||||||
}) |
|
||||||
this.list = list |
|
||||||
this.total = res.pageList.total |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 切换页码 |
|
||||||
currentChange (val) { |
|
||||||
this.page = val |
|
||||||
this.getList() |
|
||||||
}, |
|
||||||
initData () { |
|
||||||
this.page = 1 |
|
||||||
this.getList() |
|
||||||
}, |
|
||||||
// 新增 |
|
||||||
add () { |
|
||||||
this.form = _.cloneDeep(this.originForm) |
|
||||||
this.detailVisible = true |
|
||||||
}, |
|
||||||
// 试卷大纲添加行 |
|
||||||
addLine (i) { |
|
||||||
this.form.paperOutline.splice(i + 1, 0, { |
|
||||||
examQuestions: [], |
|
||||||
outlineName: '', |
|
||||||
questionNum: '', |
|
||||||
questionType: '', |
|
||||||
targetScore: '', |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 试卷大纲移除行 |
|
||||||
delLine (i) { |
|
||||||
this.form.paperOutline.length > 1 && this.form.paperOutline.splice(i, 1) |
|
||||||
}, |
|
||||||
// 使用模板 |
|
||||||
async useTemplate (row) { |
|
||||||
const data = await this.getDetail(row.templateId) |
|
||||||
data.paperOutline.map(e => { |
|
||||||
e.shrink = false |
|
||||||
e.checkAll = false |
|
||||||
e.examQuestions = [] |
|
||||||
}) |
|
||||||
this.$parent.form.paperOutline = data.paperOutline |
|
||||||
this.$parent.templateName = data.templateName |
|
||||||
this.listVisible = false |
|
||||||
}, |
|
||||||
// 获取详情 |
|
||||||
async getDetail (id) { |
|
||||||
const res = await this.$get(this.api.templateDetails, { |
|
||||||
id |
|
||||||
}) |
|
||||||
return res.template |
|
||||||
}, |
|
||||||
// 编辑 |
|
||||||
async edit (row) { |
|
||||||
this.detailVisible = true |
|
||||||
const data = await this.getDetail(row.templateId) |
|
||||||
this.form = data |
|
||||||
}, |
|
||||||
// 删除 |
|
||||||
async del (row) { |
|
||||||
try { |
|
||||||
await this.$confirm(`确认要删除【${row.templateName}】吗?`, '提示', { |
|
||||||
confirmButtonText: '确定', |
|
||||||
cancelButtonText: '取消', |
|
||||||
type: 'warning', |
|
||||||
closeOnClickModal: false, |
|
||||||
}) |
|
||||||
await this.$post(this.api.deleteTemplate, { |
|
||||||
ids: [row.templateId] |
|
||||||
}) |
|
||||||
Util.successMsg('删除成功') |
|
||||||
this.getList() |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 提交 |
|
||||||
async submit () { |
|
||||||
if (this.submiting) return false |
|
||||||
const { form } = this |
|
||||||
if (!form.templateName) return Util.warningMsg('请输入模板名称') |
|
||||||
let invalid = 0 |
|
||||||
for (const e of form.paperOutline) { |
|
||||||
if (!e.questionType) { |
|
||||||
Util.warningMsg('请选择题型') |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
if (!e.questionNum) { |
|
||||||
Util.warningMsg('请输入目标题数') |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
if (!e.targetScore) { |
|
||||||
Util.warningMsg('请输入目标分值') |
|
||||||
invalid = 1 |
|
||||||
break |
|
||||||
} |
|
||||||
} |
|
||||||
if (invalid) return false |
|
||||||
this.submiting = true |
|
||||||
form.createSource = 1 |
|
||||||
form.questionNum = this.questionNum |
|
||||||
form.totalScore = this.totalScore |
|
||||||
form.outlineNum = form.paperOutline.length |
|
||||||
form.questionType = [...new Set(form.paperOutline.map(e => e.questionType))].join('、') |
|
||||||
try { |
|
||||||
await this.$post(this.api.saveExamPaperTemplate, form) |
|
||||||
Util.successMsg('保存成功') |
|
||||||
this.detailVisible = false |
|
||||||
this.submiting = false |
|
||||||
this.getList() |
|
||||||
} catch (e) { |
|
||||||
this.submiting = false |
|
||||||
} |
|
||||||
}, |
|
||||||
// 弹框关闭回调 |
|
||||||
closeDia () { |
|
||||||
this.$emit('update:visible', false) |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped></style> |
|
@ -1,706 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="index"> |
|
||||||
<div class="top"> |
|
||||||
<p class="names">{{ form.name }}</p> |
|
||||||
|
|
||||||
<div class="count m-r-30"> |
|
||||||
用时 |
|
||||||
<span>{{ timeSum.day }}</span>天 |
|
||||||
<span>{{ timeSum.hour }}</span>小时 |
|
||||||
<span>{{ timeSum.minutes }}</span>分 |
|
||||||
<span>{{ timeSum.seconds }}</span>秒 |
|
||||||
</div> |
|
||||||
|
|
||||||
<img class="exit" src="@/assets/images/exit.svg" alt="" @click="close"> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="wrap"> |
|
||||||
<div class="left"> |
|
||||||
<h6 class="title">答题卡</h6> |
|
||||||
<div class="progress"> |
|
||||||
<p class="fs-14">答题进度</p> |
|
||||||
<el-progress class="m-t-5 m-b-5" :percentage="progress" :format="progressFormat"></el-progress> |
|
||||||
<p>共{{ form.questionCount }}题,满分{{ form.score }}分</p> |
|
||||||
</div> |
|
||||||
<div v-if="form.paperOutline" class="type-wrap"> |
|
||||||
<div v-for="(item, i) in form.paperOutline" :key="i" class="type"> |
|
||||||
<h6 class="stem">{{ arabicToChinese(i + 1) }}、{{ item.outlineName }}(本题共{{ item.questionNum }}小题,共{{ |
|
||||||
item.targetScore }}分)</h6> |
|
||||||
<ul class="serials"> |
|
||||||
<template v-for="(ques, j) in item.examQuestions"> |
|
||||||
<li |
|
||||||
v-if="!sheetStatus || (sheetStatus === 1 && !ques.answered) || (sheetStatus === 2 && ques.answered) || (sheetStatus === 3 && ques.partAnswer) || (sheetStatus === 4 && ques.sign)" |
|
||||||
:key="j" :class="{ answered: ques.answered, partAnswer: ques.partAnswer }" |
|
||||||
@click="scrollToQues(ques, item)"> |
|
||||||
<img v-if="ques.sign" class="tag" src="@/assets/images/tag-active.svg" alt=""> |
|
||||||
{{ j + 1 }} |
|
||||||
</li> |
|
||||||
</template> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<ul class="status-filter"> |
|
||||||
<li :class="{ active: sheetStatus === 1 }" @click="filterStatus(1)">未作答</li> |
|
||||||
<li :class="{ active: sheetStatus === 2 }" @click="filterStatus(2)">已作答</li> |
|
||||||
<li :class="{ active: sheetStatus === 3 }" @click="filterStatus(3)">部分已作答</li> |
|
||||||
<li :class="{ active: sheetStatus === 4 }" @click="filterStatus(4)"><img class="tag" |
|
||||||
src="@/assets/images/tag-active.svg" alt=""> 已标记</li> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
|
|
||||||
<ul v-if="form.paperOutline" class="ques-wrap" id="quesWrap"> |
|
||||||
<li v-for="(item, i) in form.paperOutline" :key="i"> |
|
||||||
<div class="outline"> |
|
||||||
{{ arabicToChinese(i + 1) }}、{{ item.outlineName }}(本题共{{ item.questionNum }}小题,共{{ |
|
||||||
item.targetScore }}分) |
|
||||||
<img :class="['shrink', { active: item.shrink }]" src="@/assets/images/shrink.svg" alt="" |
|
||||||
@click="item.shrink = !item.shrink"> |
|
||||||
</div> |
|
||||||
<div :class="['ques', { hide: item.shrink }]"> |
|
||||||
<div v-for="(ques, j) in item.examQuestions" :key="j" |
|
||||||
:class="['item', { disabled: !ques.status, del: ques.isDel, repeat: ques.repeat }]" |
|
||||||
:id="'ques' + ques.id"> |
|
||||||
<div class="stem-wrap"> |
|
||||||
<span class="label">{{ j + 1 }} / {{ item.questionNum }}</span> |
|
||||||
<span class="label">{{ item.questionTypeName }}</span> |
|
||||||
<div class="stem html-parse" :id="'stem' + ques.id" v-html="getQuesStem(ques)"></div> |
|
||||||
<p v-if="item.questionType !== 'fill_blank'">({{ ques.score }}分)</p> |
|
||||||
<img class="tag" :src="require('@/assets/images/' + (ques.sign ? 'tag-active' : 'tag') + '.svg')" alt="" |
|
||||||
@click="ques.sign = ques.sign ? 0 : 1"> |
|
||||||
</div> |
|
||||||
|
|
||||||
<!-- 单选、多选、判断的选项 --> |
|
||||||
<template |
|
||||||
v-if="item.questionType !== 'fill_blank' && item.questionType !== 'essay' && ques.questionAnswerVersionsList"> |
|
||||||
<div v-for="(opt, j) in ques.questionAnswerVersionsList" :key="j" class="opt"> |
|
||||||
<el-checkbox v-if="item.questionType === 'multiple_choice'" v-model="opt.answer" :true-label="1" |
|
||||||
@change="mulChange(ques)"></el-checkbox> |
|
||||||
<el-radio v-else v-model="opt.answer" :true-label="1" :label="1" |
|
||||||
@change="singleChange(ques, j)"></el-radio> |
|
||||||
|
|
||||||
<span>{{ numToLetter(j) }}. </span> |
|
||||||
<div class="text html-parse" v-html="opt.optionText"></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<!-- 简答题需要展示题干文件及富文本 --> |
|
||||||
<template v-if="item.questionType === 'essay'"> |
|
||||||
<div v-if="ques.stemAttachment" class="m-b-20"> |
|
||||||
<el-link class="m-r-10" type="primary" @click="preview(ques.stemAttachment)">{{ ques.fileName |
|
||||||
|| ques.stemAttachment |
|
||||||
}}</el-link> |
|
||||||
<el-button type="primary" size="mini" round |
|
||||||
@click="download(ques.fileName || ques.stemAttachment, ques.stemAttachment)">下载</el-button> |
|
||||||
</div> |
|
||||||
<UeditorPlus :ref="'essayAnswer' + ques.id" v-model="ques.answer" |
|
||||||
@ready="editor => essayAnswerReady(editor, ques)" /> |
|
||||||
<div v-if="ques.allowAttachment" class="m-t-20"> |
|
||||||
<div v-if="ques.uploadInstructions" class="flex m-b-10 fs-12"> |
|
||||||
<span>上传要求说明:</span> |
|
||||||
<div class="html-parse" v-html="ques.uploadInstructions"></div> |
|
||||||
</div> |
|
||||||
<el-upload action="#"> |
|
||||||
<el-button size="small" type="primary">上传文件</el-button> |
|
||||||
</el-upload> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-dialog title="图片预览" :visible.sync="previewImgVisible" width="800px" :close-on-click-modal="false"> |
|
||||||
<el-image style="max-width: 100px; max-height: 100px" :src="previewImg" :preview-src-list="[previewImg]"> |
|
||||||
</el-image> |
|
||||||
</el-dialog> |
|
||||||
<PdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc" /> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Util from '@/libs/util' |
|
||||||
import Setting from "@/setting" |
|
||||||
import QuesConst from '@/const/ques' |
|
||||||
import TestPaperConst from '@/const/testPaper' |
|
||||||
import _ from 'lodash' |
|
||||||
import Oss from '@/components/upload/upload.js' |
|
||||||
import Upload from '@/components/upload' |
|
||||||
import UeditorPlus from '@/components/ueditorPlus' |
|
||||||
import PdfDia from '@/components/pdf' |
|
||||||
|
|
||||||
export default { |
|
||||||
components: { |
|
||||||
Upload, UeditorPlus, PdfDia |
|
||||||
}, |
|
||||||
data () { |
|
||||||
return { |
|
||||||
questionTypes: QuesConst.questionTypes, |
|
||||||
numToLetter: Util.numToLetter, |
|
||||||
arabicToChinese: Util.arabicToChinese, |
|
||||||
id: +this.$route.query.id, |
|
||||||
entryTime: '', |
|
||||||
counterTimer: null, // 获取setInterval对象值 |
|
||||||
timeSumVal: 0, |
|
||||||
// 用时 |
|
||||||
timeSum: { |
|
||||||
day: 0, |
|
||||||
seconds: 0, |
|
||||||
minutes: 0, |
|
||||||
hour: 0, |
|
||||||
}, |
|
||||||
totalAnswered: 0, |
|
||||||
progress: 0, |
|
||||||
sheetStatus: '', |
|
||||||
form: { |
|
||||||
questionCount: 0, |
|
||||||
}, |
|
||||||
previewImgVisible: false, |
|
||||||
previewImg: '', |
|
||||||
pdfVisible: false, |
|
||||||
pdfSrc: '', |
|
||||||
}; |
|
||||||
}, |
|
||||||
mounted () { |
|
||||||
this.$once('hook:beforeDestroy', function () { |
|
||||||
clearInterval(this.counterTimer) |
|
||||||
}) |
|
||||||
|
|
||||||
this.getPaper() |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
// 获取试卷详情 |
|
||||||
async getPaper (now) { |
|
||||||
try { |
|
||||||
this.entryTime = await Util.getNow() |
|
||||||
const { id } = this |
|
||||||
if (id) { |
|
||||||
// 试卷详情 |
|
||||||
const { examPaper } = await this.$get(this.api.examPaperDetails, { id }) |
|
||||||
|
|
||||||
this.startCount() |
|
||||||
|
|
||||||
const r = examPaper |
|
||||||
const paper = r.paperOutline |
|
||||||
const types = this.questionTypes |
|
||||||
paper.map(e => { |
|
||||||
const type = e.questionType |
|
||||||
e.questionTypeName = types.find(n => n.id === type).name |
|
||||||
e.shrink = false |
|
||||||
e.examQuestions.map(n => { |
|
||||||
Object.assign(n, n.question) |
|
||||||
n.sign = 0 |
|
||||||
const opts = n.questionAnswerVersionsList |
|
||||||
if (type !== 'fill_blank' && type !== 'essay' && opts) { // 选择题 |
|
||||||
opts.map(m => { |
|
||||||
m.answer = 0 |
|
||||||
}) |
|
||||||
} else { // 简答题 |
|
||||||
n.answer = '' |
|
||||||
// 附件 |
|
||||||
n.uploadList = [] |
|
||||||
} |
|
||||||
}) |
|
||||||
}) |
|
||||||
this.form = r |
|
||||||
|
|
||||||
// 给填空题的每个空监听input事件,用以显示已作答状态 |
|
||||||
this.$nextTick(() => { |
|
||||||
paper.map(e => { |
|
||||||
e.examQuestions.map(n => { |
|
||||||
if (e.questionType === 'fill_blank') { |
|
||||||
const stem = document.querySelector(`#stem` + n.id) |
|
||||||
if (stem) { |
|
||||||
const inputs = stem.querySelectorAll('.fill-input') |
|
||||||
if (inputs) { |
|
||||||
for (const e of inputs) { |
|
||||||
e.addEventListener('input', () => { |
|
||||||
const answers = [] |
|
||||||
for (const e of inputs) { |
|
||||||
e.value && answers.push(e.value) |
|
||||||
} |
|
||||||
n.answered = answers.length === inputs.length ? 1 : 0 |
|
||||||
n.partAnswer = answers.length && answers.length !== inputs.length ? 1 : 0 |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
||||||
}) |
|
||||||
this.calcProgress() |
|
||||||
}) |
|
||||||
} |
|
||||||
} catch (e) { } |
|
||||||
}, |
|
||||||
// 计时器 |
|
||||||
handleCounter (counterTime, isCount) { |
|
||||||
let leave1 = counterTime % (24 * 3600) //计算天数后剩余的毫秒数 |
|
||||||
let leave2 = leave1 % 3600 //计算小时数后剩余的毫秒数 |
|
||||||
let leave3 = leave2 % 60 //计算分钟数后剩余的毫秒数 |
|
||||||
let day = Math.floor(counterTime / (24 * 3600)) //计算相差天数 |
|
||||||
let hour = Math.floor(leave1 / 3600) //计算相差小时 |
|
||||||
let minutes = Math.floor(leave2 / 60) //计算相差分钟 |
|
||||||
let seconds = Math.round(leave3) //计算相差秒 |
|
||||||
day = this.timeFormat(day) |
|
||||||
hour = this.timeFormat(hour) |
|
||||||
minutes = this.timeFormat(minutes) |
|
||||||
seconds = this.timeFormat(seconds) |
|
||||||
const count = this[isCount ? 'counterVal' : 'timeSum'] |
|
||||||
count.day = day |
|
||||||
count.hour = hour |
|
||||||
count.minutes = minutes |
|
||||||
count.seconds = seconds |
|
||||||
}, |
|
||||||
// 启动倒计时 |
|
||||||
startCount () { |
|
||||||
clearInterval(this.counterTimer) |
|
||||||
this.counterTimer = setInterval(() => { |
|
||||||
this.timeSumVal >= 0 && this.handleCounter(this.timeSumVal++) |
|
||||||
}, 1000) |
|
||||||
}, |
|
||||||
timeFormat (param) { |
|
||||||
return param < 10 ? '0' + param : param |
|
||||||
}, |
|
||||||
// 计算答题进度 |
|
||||||
calcProgress () { |
|
||||||
let answered = 0 |
|
||||||
this.form.paperOutline.map(e => { |
|
||||||
answered += e.examQuestions.filter(n => n.answered).length |
|
||||||
}) |
|
||||||
this.totalAnswered = answered |
|
||||||
this.progress = +(answered / this.form.questionCount * 100).toFixed(1) |
|
||||||
}, |
|
||||||
// 答题进度格式 |
|
||||||
progressFormat (e) { |
|
||||||
return this.totalAnswered + '/' + this.form.questionCount |
|
||||||
}, |
|
||||||
scrollToSmooth (position, duration) { |
|
||||||
let startTime = Date.now() |
|
||||||
|
|
||||||
function scroll () { |
|
||||||
let now = Date.now() |
|
||||||
let progress = Math.min(1, (now - startTime) / duration) |
|
||||||
document.querySelector('#quesWrap').scrollTo(0, position * progress) |
|
||||||
|
|
||||||
if (progress < 1) { |
|
||||||
window.requestAnimationFrame(scroll) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
window.requestAnimationFrame(scroll) |
|
||||||
}, |
|
||||||
// 答题卡题目点击滚动 |
|
||||||
scrollToQues (e, item) { |
|
||||||
item.shrink = false |
|
||||||
const el = document.querySelector('#ques' + e.id) |
|
||||||
this.$nextTick(() => { |
|
||||||
el && this.scrollToSmooth(el.offsetTop - document.querySelector('#quesWrap').offsetTop, 200) |
|
||||||
}) |
|
||||||
}, |
|
||||||
// 答题卡筛选 |
|
||||||
filterStatus (e) { |
|
||||||
this.sheetStatus = this.sheetStatus === e ? '' : e |
|
||||||
}, |
|
||||||
// 处理题干显示 |
|
||||||
getQuesStem (ques) { |
|
||||||
let { stem } = ques |
|
||||||
if (ques.questionType === 'fill_blank') { // 填空题 |
|
||||||
let { fills } = ques |
|
||||||
|
|
||||||
const regex = /<span class="gapfilling-span" data-id="(.*?)">______<\/span>/g |
|
||||||
let match |
|
||||||
let index = 0 // 用于跟踪索引 |
|
||||||
let result = stem |
|
||||||
|
|
||||||
while ((match = regex.exec(stem)) !== null) { |
|
||||||
const newInput = `<input type="text" class="fill-input" value="${fills && fills.length ? fills[index] : ''}">` |
|
||||||
result = result.replace(match[0], newInput) |
|
||||||
index++ |
|
||||||
} |
|
||||||
return result |
|
||||||
} else { |
|
||||||
return stem |
|
||||||
} |
|
||||||
}, |
|
||||||
// 单选题回调 |
|
||||||
singleChange (ques, j) { |
|
||||||
ques.questionAnswerVersionsList.map(e => { |
|
||||||
e.answer = 0 |
|
||||||
}) |
|
||||||
ques.questionAnswerVersionsList[j].answer = 1 |
|
||||||
|
|
||||||
ques.answered = 1 |
|
||||||
this.calcProgress() |
|
||||||
}, |
|
||||||
// 多选题回调 |
|
||||||
mulChange (ques) { |
|
||||||
ques.answered = ques.questionAnswerVersionsList.some(e => e.answer) |
|
||||||
this.calcProgress() |
|
||||||
}, |
|
||||||
|
|
||||||
// 简答题富文本加载完毕回调 |
|
||||||
essayAnswerReady (editor, ques) { |
|
||||||
editor.ques = ques |
|
||||||
editor.addListener('contentChange', () => { |
|
||||||
ques.answered = editor.getContent() ? 1 : 0 |
|
||||||
this.calcProgress() |
|
||||||
}) |
|
||||||
ques.answer && editor.setContent(ques.answer) |
|
||||||
}, |
|
||||||
// 预览附件 |
|
||||||
preview (url) { |
|
||||||
const ext = url.split('.').pop() |
|
||||||
if (Util.isDoc(ext)) { |
|
||||||
window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url) |
|
||||||
} else if (Util.isImg(ext)) { |
|
||||||
this.previewImgVisible = true |
|
||||||
this.previewImg = url |
|
||||||
} else if (ext === 'pdf') { |
|
||||||
this.pdfVisible = true |
|
||||||
this.pdfSrc = url |
|
||||||
} |
|
||||||
}, |
|
||||||
// 下载附件 |
|
||||||
download (name, url) { |
|
||||||
Util.downloadFile(name, url) |
|
||||||
}, |
|
||||||
handleRemove (ques) { |
|
||||||
Oss.del(ques.attachmentUrl) |
|
||||||
ques.attachmentName = '' |
|
||||||
ques.attachmentUrl = '' |
|
||||||
}, |
|
||||||
uploadSuccess (file, ques) { |
|
||||||
ques.attachmentName = file.name |
|
||||||
ques.attachmentUrl = file.url |
|
||||||
}, |
|
||||||
// 解析富文本加载完毕回调 |
|
||||||
answerAnalysisReady (editor) { |
|
||||||
this.answerAnalysis && editor.setContent(this.answerAnalysis) |
|
||||||
}, |
|
||||||
close () { |
|
||||||
window.close() |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
.top { |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
padding: 10px 20px; |
|
||||||
color: #fff; |
|
||||||
background-color: #5786fc; |
|
||||||
|
|
||||||
.item { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.names { |
|
||||||
font-size: 18px; |
|
||||||
font-weight: 600; |
|
||||||
} |
|
||||||
|
|
||||||
.submit { |
|
||||||
width: 106px; |
|
||||||
font-size: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.exit { |
|
||||||
margin-left: 20px; |
|
||||||
cursor: pointer; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
opacity: .9; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/deep/.wrap { |
|
||||||
display: flex; |
|
||||||
padding: 15px; |
|
||||||
|
|
||||||
.left { |
|
||||||
width: 300px; |
|
||||||
margin-right: 15px; |
|
||||||
background-color: #fff; |
|
||||||
|
|
||||||
.title { |
|
||||||
padding: 10px 0; |
|
||||||
font-size: 16px; |
|
||||||
text-align: center; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
|
|
||||||
.progress { |
|
||||||
padding: 10px; |
|
||||||
color: #5a5a5a; |
|
||||||
background-color: #d4e9ff; |
|
||||||
} |
|
||||||
|
|
||||||
.type-wrap { |
|
||||||
max-height: calc(100vh - 248px); |
|
||||||
padding: 10px; |
|
||||||
overflow: auto; |
|
||||||
|
|
||||||
.type { |
|
||||||
margin-bottom: 20px; |
|
||||||
} |
|
||||||
|
|
||||||
.stem { |
|
||||||
font-size: 15px; |
|
||||||
color: #333; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.serials { |
|
||||||
display: flex; |
|
||||||
flex-wrap: wrap; |
|
||||||
margin-top: 5px; |
|
||||||
|
|
||||||
li { |
|
||||||
position: relative; |
|
||||||
width: 35px; |
|
||||||
margin: 7px 9px; |
|
||||||
font-size: 13px; |
|
||||||
text-align: center; |
|
||||||
line-height: 35px; |
|
||||||
color: #505050; |
|
||||||
border: 1px solid #d3d3d3; |
|
||||||
cursor: pointer; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
opacity: .9; |
|
||||||
} |
|
||||||
|
|
||||||
&.answered { |
|
||||||
color: #fff; |
|
||||||
background-color: #66b2ff; |
|
||||||
border-color: #66b2ff; |
|
||||||
} |
|
||||||
|
|
||||||
&.partAnswer { |
|
||||||
border-color: #66b2ff; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.tag { |
|
||||||
position: absolute; |
|
||||||
top: -2px; |
|
||||||
left: -4px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.status-filter { |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
padding: 10px; |
|
||||||
border-top: 1px solid #e5e5e5; |
|
||||||
|
|
||||||
li { |
|
||||||
display: inline-flex; |
|
||||||
align-items: center; |
|
||||||
padding: 0 3px; |
|
||||||
font-size: 12px; |
|
||||||
color: #333; |
|
||||||
cursor: pointer; |
|
||||||
border: 1px solid transparent; |
|
||||||
|
|
||||||
&:not(:last-child):before { |
|
||||||
content: ''; |
|
||||||
width: 13px; |
|
||||||
height: 13px; |
|
||||||
margin-right: 5px; |
|
||||||
border: 1px solid #ccc; |
|
||||||
} |
|
||||||
|
|
||||||
&:nth-child(2):before { |
|
||||||
background-color: #56aaff; |
|
||||||
border: 0; |
|
||||||
} |
|
||||||
|
|
||||||
&:nth-child(3):before { |
|
||||||
border-color: #56aaff; |
|
||||||
} |
|
||||||
|
|
||||||
&.active { |
|
||||||
font-weight: 600; |
|
||||||
color: #007eff; |
|
||||||
border-color: #007eff; |
|
||||||
|
|
||||||
&:last-child { |
|
||||||
color: #d81e06; |
|
||||||
border-color: #d81e06; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.ques-wrap { |
|
||||||
width: calc(100% - 315px); |
|
||||||
height: calc(100vh - 80px); |
|
||||||
background-color: #fff; |
|
||||||
overflow: auto; |
|
||||||
|
|
||||||
&>li { |
|
||||||
margin-bottom: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.outline { |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
padding: 10px 15px; |
|
||||||
font-size: 15px; |
|
||||||
font-weight: 600; |
|
||||||
color: #333; |
|
||||||
background-color: #e8f0ff; |
|
||||||
} |
|
||||||
|
|
||||||
.shrink { |
|
||||||
cursor: pointer; |
|
||||||
transition: .5s; |
|
||||||
|
|
||||||
&.active { |
|
||||||
transform: rotate(180deg); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.ques { |
|
||||||
max-height: none; |
|
||||||
padding: 15px; |
|
||||||
margin-bottom: 15px; |
|
||||||
transition: all 1.5s; |
|
||||||
overflow: hidden; |
|
||||||
|
|
||||||
&.hide { |
|
||||||
max-height: 10px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.item { |
|
||||||
position: relative; |
|
||||||
overflow: hidden; |
|
||||||
|
|
||||||
&:not(:last-child) { |
|
||||||
padding-bottom: 15px; |
|
||||||
margin-bottom: 15px; |
|
||||||
border-bottom: 1px dashed #e1e1e1; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
&.disabled, |
|
||||||
&.del, |
|
||||||
&.repeat { |
|
||||||
border-color: #f00; |
|
||||||
|
|
||||||
&:after { |
|
||||||
content: '已 禁 用'; |
|
||||||
position: absolute; |
|
||||||
top: 17px; |
|
||||||
right: -33px; |
|
||||||
padding: 5px 36px; |
|
||||||
font-size: 14px; |
|
||||||
color: #fff; |
|
||||||
background-color: #f00; |
|
||||||
transform: rotate(45deg); |
|
||||||
opacity: .6; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&.del { |
|
||||||
&:after { |
|
||||||
content: '已 删 除'; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&.repeat { |
|
||||||
border-color: #ff962a; |
|
||||||
|
|
||||||
&:after { |
|
||||||
content: '存在重复题'; |
|
||||||
background-color: #ff962a; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
.stem-wrap { |
|
||||||
display: flex; |
|
||||||
align-items: baseline; |
|
||||||
margin-bottom: 10px; |
|
||||||
} |
|
||||||
|
|
||||||
.tag { |
|
||||||
margin-left: 10px; |
|
||||||
cursor: pointer; |
|
||||||
|
|
||||||
&:hover { |
|
||||||
opacity: .9; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.label { |
|
||||||
padding: 3px 5px; |
|
||||||
margin-right: 10px; |
|
||||||
font-size: 12px; |
|
||||||
line-height: 1; |
|
||||||
color: $main-color; |
|
||||||
white-space: nowrap; |
|
||||||
border: 1px solid; |
|
||||||
border-radius: 2px; |
|
||||||
} |
|
||||||
|
|
||||||
.stem { |
|
||||||
max-width: calc(100% - 191px); |
|
||||||
} |
|
||||||
|
|
||||||
img { |
|
||||||
max-width: 100%; |
|
||||||
} |
|
||||||
|
|
||||||
.fill-input { |
|
||||||
width: 100px; |
|
||||||
height: 28px; |
|
||||||
padding: 0 15px; |
|
||||||
margin: 0 10px; |
|
||||||
font-size: 13px; |
|
||||||
line-height: 28px; |
|
||||||
color: #606266; |
|
||||||
border: 1px solid #DCDEE0; |
|
||||||
border-radius: 2px; |
|
||||||
|
|
||||||
&:focus { |
|
||||||
outline: none; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.opt { |
|
||||||
display: flex; |
|
||||||
flex-wrap: wrap; |
|
||||||
align-items: baseline; |
|
||||||
padding-left: 10px; |
|
||||||
margin-bottom: 5px; |
|
||||||
font-size: 14px; |
|
||||||
color: #707070; |
|
||||||
line-height: 1.6; |
|
||||||
|
|
||||||
.el-radio, |
|
||||||
.el-checkbox { |
|
||||||
margin-right: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
.el-radio__label { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
|
|
||||||
.text { |
|
||||||
max-width: calc(100% - 48px); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
@ -0,0 +1,262 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-drawer title="分配评阅人员" :visible.sync="allocationVisible" size="1200px" :close-on-click-modal="false" |
||||||
|
custom-class="allo-dia" @closed="closeDia"> |
||||||
|
<div class="overflow"> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter"> |
||||||
|
<li style="align-items: flex-start;"> |
||||||
|
<label>分配方式</label> |
||||||
|
<div> |
||||||
|
<el-radio v-model="radio" label="1">按整卷分配</el-radio> |
||||||
|
<p class="tips m-b-20">(每份答卷将从以下已选的评阅人员中,按照评阅设置的每题评阅人数随机挑选评阅人员对整卷进行评阅,且以下已选的每位评阅人员分配到的答卷数量基本平均)</p> |
||||||
|
<el-radio v-model="radio" label="2">按每道人工判分题分配</el-radio> |
||||||
|
<p class="tips">(每份答卷的每道人工判分题将从以下题目已选的评阅人员中,按照评阅设置的每题评阅人数随机挑选评阅人员对该题进行评阅,且以下已选的每位评阅人员分配到的该题答卷数量基本平均)</p> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- <People /> --> |
||||||
|
|
||||||
|
<div> |
||||||
|
<div class="flex a-center m-b-10"> |
||||||
|
<h6 class="page-name m-r-10" style="margin-bottom: 0">选择评阅人员</h6> |
||||||
|
<el-button type="primary" size="mini" @click="batchAlloc">批量分配</el-button> |
||||||
|
</div> |
||||||
|
<el-table :data="ques" class="table" ref="table" stripe header-align="center" row-key="id" |
||||||
|
@selection-change="handleSelectionChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="50" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="stem" label="题干" align="center" min-width="120"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="100"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<i class="el-icon-edit-outline"></i> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="btns"> |
||||||
|
<el-button @click="allocationVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button> |
||||||
|
</div> |
||||||
|
</el-drawer> |
||||||
|
|
||||||
|
|
||||||
|
<el-drawer title="分配评阅人员" :visible.sync="peopleVisible" :with-header="false" size="1000px" |
||||||
|
:close-on-click-modal="false" custom-class="allo-dia"> |
||||||
|
<div class="p-l-20 p-r-20"> |
||||||
|
<People /> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="btns"> |
||||||
|
<el-button @click="peopleVisible = false">取消</el-button> |
||||||
|
<el-button type="primary" :loading="submiting" @click="peopleSubmit">确定</el-button> |
||||||
|
</div> |
||||||
|
</el-drawer> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import People from './people' |
||||||
|
import Setting from '@/setting' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import QuesConst from '@/const/ques' |
||||||
|
import TestPaperConst from '@/const/testPaper' |
||||||
|
import _ from 'lodash' |
||||||
|
import Decimal from 'decimal.js' |
||||||
|
export default { |
||||||
|
components: { People }, |
||||||
|
props: ['visible'], |
||||||
|
data () { |
||||||
|
return { |
||||||
|
radio: '', |
||||||
|
allocationVisible: false, |
||||||
|
searchTimer: null, |
||||||
|
|
||||||
|
userType: '', |
||||||
|
ques: [], |
||||||
|
multipleSelection: [], |
||||||
|
submiting: false, |
||||||
|
|
||||||
|
peopleVisible: false, |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
visible () { |
||||||
|
this.allocationVisible = this.visible |
||||||
|
this.visible && this.init() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
|
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 初始化 |
||||||
|
init () { |
||||||
|
this.handleQuesList() |
||||||
|
|
||||||
|
}, |
||||||
|
// 获取题库分类 |
||||||
|
async getQuesBankType () { |
||||||
|
try { |
||||||
|
const { data } = await this.$post(this.api.getAllQuestionBankCategories, { |
||||||
|
createSource: 1, |
||||||
|
status: 1, |
||||||
|
}) |
||||||
|
this.handleList(data) |
||||||
|
this.quesBankTypes = data |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
handleSelectionChange (val) { |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
// 批量分配 |
||||||
|
async batchAlloc () { |
||||||
|
try { |
||||||
|
this.peopleVisible = true |
||||||
|
return |
||||||
|
const checked = this.multipleSelection |
||||||
|
if (checked.length) { |
||||||
|
this.peopleVisible = true |
||||||
|
} else { |
||||||
|
Util.warningMsg('请选择数据') |
||||||
|
} |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 单个分配 |
||||||
|
alloc () { |
||||||
|
this.peopleVisible = true |
||||||
|
}, |
||||||
|
// 弹框选择人员提交 |
||||||
|
peopleSubmit () { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
// 提交 |
||||||
|
async submit () { |
||||||
|
if (this.submiting) return false |
||||||
|
const { list } = this |
||||||
|
let invalid = 0 |
||||||
|
let totalCount = 0 |
||||||
|
for (const i in list) { |
||||||
|
const e = list[i] |
||||||
|
const name = `第${Util.arabicToChinese(+i + 1)}大题` |
||||||
|
if (!e.questionType) { |
||||||
|
Util.warningMsg(`${name}请先选择题型`) |
||||||
|
invalid = 1 |
||||||
|
break |
||||||
|
} |
||||||
|
if (!e.questionNum || isNaN(e.questionNum) || e.questionNum <= 0) { |
||||||
|
Util.warningMsg(`${name}的目标题数请输入正整数`) |
||||||
|
invalid = 1 |
||||||
|
break |
||||||
|
} |
||||||
|
let total = Decimal(e.basicDifficulty || 0).add(e.normalDifficulty || 0).add(e.hardDifficulty || 0).add(e.veryHardDifficulty || 0).toNumber() // 先算前4个难度的题数 |
||||||
|
if (total) { // 前面4个空有填1个,则清空随机 |
||||||
|
this.$set(e, 'randomDifficulty', 0) |
||||||
|
} else { |
||||||
|
total = +e.randomDifficulty || 0 |
||||||
|
} |
||||||
|
|
||||||
|
if (total > e.questionNum) { |
||||||
|
Util.warningMsg(`${name}的小题总数大于目标题数,请重新输入`) |
||||||
|
invalid = 1 |
||||||
|
break |
||||||
|
} |
||||||
|
e.count = total |
||||||
|
totalCount = Decimal(totalCount).add(total).toNumber() |
||||||
|
} |
||||||
|
if (invalid) return false |
||||||
|
if (!totalCount) return Util.warningMsg(`请填写难度题数`) |
||||||
|
this.submiting = true |
||||||
|
const k = this.allKnowledges.map(e => e.id) |
||||||
|
|
||||||
|
const years = [] |
||||||
|
this.yearCheck.map(e => { |
||||||
|
if (e === '暂无年份') { |
||||||
|
years.push('') |
||||||
|
} else if (e === '更早') { |
||||||
|
// 选的是更早则直接传1990~2005所有年份 |
||||||
|
for (let i = 1990; i < 2006; i++) { |
||||||
|
years.push(i) |
||||||
|
} |
||||||
|
} else { |
||||||
|
years.push(+e) |
||||||
|
} |
||||||
|
}) |
||||||
|
list.map(e => { |
||||||
|
e.givenYears = years |
||||||
|
e.knowledgePointsIds = k |
||||||
|
}) |
||||||
|
try { |
||||||
|
const res = await this.$post(this.api.selectQuestionsByTypeAndDifficulty, list) |
||||||
|
|
||||||
|
let invalid = 0 |
||||||
|
let hasQues = 0 |
||||||
|
list.map((e, i) => { |
||||||
|
if (+e.count !== res.list[i].questions.length) invalid = 1 |
||||||
|
if (e.examQuestions.length) hasQues = 1 |
||||||
|
e.score = 0 |
||||||
|
}) |
||||||
|
|
||||||
|
// 3种情况提示不一样 |
||||||
|
const tips = invalid && hasQues ? |
||||||
|
'此操作会清空当前试卷已添加的试题,并且满足自动选题设置的试题数量不足,确定要继续自动选题吗?' : |
||||||
|
invalid && !hasQues ? |
||||||
|
'满足自动选题设置的试题数量不足,确认要继续自动选题吗?' : |
||||||
|
!invalid && hasQues ? '此操作会清空当前试卷已添加的试题,是否确定要继续自动选题吗?' : |
||||||
|
'' |
||||||
|
|
||||||
|
if (tips) { |
||||||
|
await this.$confirm(tips, '提示', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
type: 'warning', |
||||||
|
closeOnClickModal: false, |
||||||
|
}) |
||||||
|
} |
||||||
|
list.map((e, i) => { |
||||||
|
res.list[i].questions.map((e, i) => { |
||||||
|
e.questionId = e.id |
||||||
|
e.serialNumber = i + 1 |
||||||
|
e.originSort = i + 1 |
||||||
|
this.$parent.handleQuesInfo(e) |
||||||
|
}) |
||||||
|
this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions |
||||||
|
}) |
||||||
|
this.allocationVisible = false |
||||||
|
this.$parent.calcDifficult() |
||||||
|
this.submiting = false |
||||||
|
} catch (e) { |
||||||
|
this.submiting = false |
||||||
|
} |
||||||
|
}, |
||||||
|
// 弹框关闭回调 |
||||||
|
closeDia () { |
||||||
|
this.$emit('update:visible', false) |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.allo-dia { |
||||||
|
.el-drawer__header { |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.overflow { |
||||||
|
height: calc(100vh - 147px); |
||||||
|
padding: 0 20px; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.tips { |
||||||
|
margin-top: 3px; |
||||||
|
font-size: 12px; |
||||||
|
color: #585858; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,336 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<Breadcrumb :data="crumbs" /> |
||||||
|
<h6 class="page-name">筛选</h6> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter"> |
||||||
|
<li> |
||||||
|
<label>省份</label> |
||||||
|
<el-select v-model="filter.provinceId" clearable placeholder="请选择省份" @change="provinceChange" |
||||||
|
@clear="clearprovince"> |
||||||
|
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName" |
||||||
|
:value="item.provinceId"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>城市</label> |
||||||
|
<el-select v-model="filter.cityId" clearable placeholder="请选择城市" :disabled="!filter.provinceId" |
||||||
|
@clear="clearcity" @change="getSchool"> |
||||||
|
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>学校</label> |
||||||
|
<el-select v-model="filter.schoolId" clearable filterable placeholder="请选择学校" :disabled="!filter.cityId" |
||||||
|
@change="initData"> |
||||||
|
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName" |
||||||
|
:value="item.schoolId"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>评阅状态</label> |
||||||
|
<el-select v-model="filter.status" clearable placeholder="请选择评阅状态" @change="initData"> |
||||||
|
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>是否完成分配</label> |
||||||
|
<el-select v-model="filter.status" clearable placeholder="请选择是否完成分配" @change="initData"> |
||||||
|
<el-option v-for="(item, i) in status" :key="i" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>搜索</label> |
||||||
|
<el-input style="width: 400px;" placeholder="请输入学生姓名、学生学号、团队名称、答卷ID、提交名称" prefix-icon="el-icon-search" |
||||||
|
v-model="filter.keyword" clearable /> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
<div> |
||||||
|
<el-button type="primary" @click="batchReview">修改评阅设置</el-button> |
||||||
|
<!-- <el-button type="primary">批量导出评分表</el-button> --> |
||||||
|
<el-button type="primary">批量导出列表</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table :data="list" class="table" ref="table" stripe header-align="center" row-key="id" |
||||||
|
@selection-change="handleSelectionChange"> |
||||||
|
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="50" label="序号" align="center"></el-table-column> |
||||||
|
<el-table-column prop="stem" label="省份" align="center" min-width="120"></el-table-column> |
||||||
|
<el-table-column prop="professionalName" label="城市" align="center" min-width="100"></el-table-column> |
||||||
|
<el-table-column prop="knowledgePointName" label="学生所在学校" align="center" min-width="100"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="团队名称" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="学生姓名" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="学号" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="答卷ID" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="用时" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="提交时间" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="提交名称" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="是否完成分配" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="评阅人员" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="评阅人数" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="评阅状态" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="成绩" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="最新分配时间" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column prop="lastEditor" label="最新分配人" align="center" width="90"></el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="100" fixed="right"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="allocation(scope.row)">分配评阅人员</el-button> |
||||||
|
<!-- <el-button type="text" @click="toScore(scope.row)">查看评分表</el-button> |
||||||
|
<el-button type="text" @click="exportScore(scope.row)">导出评分表</el-button> --> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" |
||||||
|
:total="total"></el-pagination> |
||||||
|
</div> |
||||||
|
|
||||||
|
<Allocation :visible.sync="allocationVisible" /> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Allocation from './allocation' |
||||||
|
import Breadcrumb from '@/components/breadcrumb' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
import Const from '@/const/ques' |
||||||
|
import Qs from 'qs' |
||||||
|
import dayjs from 'dayjs' |
||||||
|
export default { |
||||||
|
components: { Allocation, Breadcrumb }, |
||||||
|
data () { |
||||||
|
return { |
||||||
|
crumbs: [], |
||||||
|
paperName: this.$route.query.paperName, |
||||||
|
difficults: Const.difficults, |
||||||
|
questionTypes: Const.questionTypes, |
||||||
|
loading: false, |
||||||
|
|
||||||
|
provinces: [], |
||||||
|
cities: [], |
||||||
|
schools: [], |
||||||
|
status: [ |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '启用' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
name: '禁用' |
||||||
|
}, |
||||||
|
], |
||||||
|
date: [], |
||||||
|
filter: { |
||||||
|
month: '', |
||||||
|
startTime: null, |
||||||
|
endTime: null, |
||||||
|
status: '', |
||||||
|
keyword: '', |
||||||
|
}, |
||||||
|
list: [{}], |
||||||
|
page: +this.$route.query.page || 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
multipleSelection: [], |
||||||
|
|
||||||
|
allocationVisible: false, |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
'filter.month': function (val) { |
||||||
|
if (val) { |
||||||
|
let unit = 24 * 60 * 60 * 1000 |
||||||
|
this.date = [dayjs(new Date(Date.now() - unit * 30 * val)).format('YYYY-MM-DD'), dayjs(new Date(Date.now() + unit)).format('YYYY-MM-DD')] |
||||||
|
} else { |
||||||
|
this.date = [] |
||||||
|
} |
||||||
|
}, |
||||||
|
date: function (val) { |
||||||
|
if (val) { |
||||||
|
this.filter.startTime = val[0]; |
||||||
|
this.filter.endTime = val[1]; |
||||||
|
} else { |
||||||
|
this.filter.startTime = '' |
||||||
|
this.filter.endTime = '' |
||||||
|
} |
||||||
|
// this.initData(); |
||||||
|
}, |
||||||
|
'filter.keyword': function () { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(this.initData, 500) |
||||||
|
}, |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.crumbs = [ |
||||||
|
{ |
||||||
|
name: '分配评阅任务', |
||||||
|
route: '/allocationReview' |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: '任务分配' |
||||||
|
}, |
||||||
|
|
||||||
|
] |
||||||
|
|
||||||
|
const { query } = this.$route |
||||||
|
if (query.page) { |
||||||
|
const { questionTypes, correctRateEnd, correctRateStart, difficultys, specialtyIds, status, keyword, questionTypeSort, givenYearSort, difficultySort, correctRateSort, updateTimeSort, referenceCountSort, givenYears, knowledgePointIds, questionBankId, questionBankName, questionBankCategory } = query |
||||||
|
this.filter = { |
||||||
|
questionTypes: questionTypes ? questionTypes.split(',') : [], |
||||||
|
correctRateEnd: correctRateEnd || '', |
||||||
|
correctRateStart: correctRateStart || '', |
||||||
|
difficultys: difficultys ? difficultys.split(',') : [], |
||||||
|
specialtyIds: specialtyIds ? specialtyIds.split(',').map(e => +e) : [], |
||||||
|
status: status ? +status : '', |
||||||
|
keyword: keyword || '', |
||||||
|
questionTypeSort: questionTypeSort || '', |
||||||
|
givenYearSort: givenYearSort || '', |
||||||
|
difficultySort: difficultySort || '', |
||||||
|
correctRateSort: correctRateSort || '', |
||||||
|
updateTimeSort: updateTimeSort || '', |
||||||
|
referenceCountSort: referenceCountSort || '', |
||||||
|
} |
||||||
|
this.givenYears = givenYears || '' |
||||||
|
this.knowledgePointIds = knowledgePointIds ? JSON.parse(knowledgePointIds) : [] |
||||||
|
|
||||||
|
this.$router.push(`/myReview?questionBankId=${questionBankId}&questionBankName=${questionBankName}&questionBankCategory=${questionBankCategory}`).catch(() => { }) |
||||||
|
} |
||||||
|
|
||||||
|
this.getProvince() |
||||||
|
// this.getProfessional() |
||||||
|
// this.getKnowledge() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
async getList () { |
||||||
|
let type = this.$refs.typeTree.getCurrentKey() |
||||||
|
const k = this.knowledgePointIds |
||||||
|
if (k.length) { // 右边筛选里的知识点 |
||||||
|
type = k.map(e => { |
||||||
|
return e[e.length - 1] |
||||||
|
}) |
||||||
|
} else if (type) { |
||||||
|
type = [type] |
||||||
|
} |
||||||
|
const { message } = await this.$post(this.api.listQuestion, { |
||||||
|
...this.filter, |
||||||
|
givenYears: this.givenYears ? [this.givenYears] : [], |
||||||
|
isNotJoin: this.isNotJoin || '', |
||||||
|
pageNum: this.page, |
||||||
|
pageSize: this.pageSize, |
||||||
|
questionBankId: this.questionBankId, |
||||||
|
knowledgePointIds: type || [], |
||||||
|
}) |
||||||
|
this.list = Util.removeTag(message.records) |
||||||
|
this.total = message.total |
||||||
|
}, |
||||||
|
// 切换页码 |
||||||
|
currentChange (val) { |
||||||
|
this.page = val |
||||||
|
this.getList() |
||||||
|
}, |
||||||
|
handleSelectionChange (val) { // 多选 |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
initData () { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.page = 1 |
||||||
|
this.getList() |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取省份 |
||||||
|
async getProvince () { |
||||||
|
const { list } = await this.$get(this.api.queryProvince) |
||||||
|
this.provinces = list |
||||||
|
}, |
||||||
|
// 清除省份 |
||||||
|
clearprovince () { |
||||||
|
this.filter.cityId = '', |
||||||
|
this.filter.schoolId = '' |
||||||
|
}, |
||||||
|
// 省份选择回调 |
||||||
|
provinceChange () { |
||||||
|
this.clearprovince() |
||||||
|
this.getCity() |
||||||
|
this.initData() |
||||||
|
}, |
||||||
|
// 获取城市 |
||||||
|
async getCity () { |
||||||
|
const { list } = await this.$get(this.api.queryCity, { |
||||||
|
provinceId: this.filter.provinceId |
||||||
|
}) |
||||||
|
this.cities = list |
||||||
|
}, |
||||||
|
// 清除城市 |
||||||
|
clearcity () { |
||||||
|
this.filter.schoolId = '' |
||||||
|
}, |
||||||
|
// 城市选择回调 |
||||||
|
cityChange () { |
||||||
|
this.filter.schoolId = '' |
||||||
|
this.getSchool() |
||||||
|
this.initData() |
||||||
|
}, |
||||||
|
// 获取学校 |
||||||
|
async getSchool () { |
||||||
|
const { list } = await this.$get(this.api.querySchoolByReadAndAppraise, { |
||||||
|
provinceId: this.filter.provinceId, |
||||||
|
cityId: this.filter.cityId, |
||||||
|
}) |
||||||
|
this.schools = list |
||||||
|
}, |
||||||
|
|
||||||
|
// 批量评阅 |
||||||
|
async batchReview () { |
||||||
|
const list = this.multipleSelection |
||||||
|
if (list.length) { |
||||||
|
try { |
||||||
|
await this.$confirm(`确定要删除已选定的${list.length}份试卷吗?`, '提示', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
type: 'warning', |
||||||
|
closeOnClickModal: false, |
||||||
|
}) |
||||||
|
await this.$post(this.api.paperDel, { |
||||||
|
delete: false, |
||||||
|
ids: list.map(e => e.paperId) |
||||||
|
}) |
||||||
|
Util.successMsg('删除成功') |
||||||
|
this.multipleSelection = [] |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.getList() |
||||||
|
} catch (e) { } |
||||||
|
} else { |
||||||
|
Util.warningMsg('请选择数据') |
||||||
|
} |
||||||
|
}, |
||||||
|
// 分配评阅人员 |
||||||
|
allocation (row) { |
||||||
|
this.allocationVisible = true |
||||||
|
}, |
||||||
|
// 查看评分表 |
||||||
|
toScore (row) { |
||||||
|
|
||||||
|
}, |
||||||
|
// 导出评分表 |
||||||
|
exportScore (row) { |
||||||
|
|
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.tool { |
||||||
|
margin-bottom: 0; |
||||||
|
|
||||||
|
.filter { |
||||||
|
flex-wrap: wrap; |
||||||
|
|
||||||
|
li { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,351 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<h6 class="page-name m-t-20">选择评阅人员</h6> |
||||||
|
<div class="wrap"> |
||||||
|
<div class="item"> |
||||||
|
<el-radio-group class="m-b-10" v-model="userType" size="small"> |
||||||
|
<el-radio-button label="平台用户"></el-radio-button> |
||||||
|
<el-radio-button label="专家"></el-radio-button> |
||||||
|
</el-radio-group> |
||||||
|
|
||||||
|
<el-tree :data="nakadais" default-expand-all ref="nakadais" node-key="id" highlight-current |
||||||
|
:expand-on-click-node="false" @node-click="getNakadaiUser" |
||||||
|
:props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }"></el-tree> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<p class="total m-b-10">用户</p> |
||||||
|
<el-input class="m-b-10" placeholder="请输入姓名、现所在单位" prefix-icon="el-icon-search" v-model="userKeyword" |
||||||
|
clearable /> |
||||||
|
|
||||||
|
<template v-if="users.length"> |
||||||
|
<div class="line"> |
||||||
|
<el-checkbox v-model="userCheck" @change="userAllCheckChange"></el-checkbox> |
||||||
|
<span class="username">姓名</span> |
||||||
|
<!-- <span>现所在单位</span> |
||||||
|
<span>职务</span> --> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="lines"> |
||||||
|
<div v-for="(item, i) in users" :key="i" class="line"> |
||||||
|
<el-checkbox v-model="item.check" :disabled="item.disabled" |
||||||
|
@change="val => userChange(val, item)"></el-checkbox> |
||||||
|
<p class="username" :title="item.userName">{{ item.userName }}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div v-else class="empty"> |
||||||
|
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
||||||
|
<p>暂无数据</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="item"> |
||||||
|
<div class="flex j-between a-center"> |
||||||
|
<p class="total">已选人</p> |
||||||
|
<el-button type="text" @click="batchDelChecked">批量移除</el-button> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-input class="m-b-10" placeholder="请输入姓名、现所在单位" prefix-icon="el-icon-search" v-model="checkedKeyword" |
||||||
|
clearable /> |
||||||
|
|
||||||
|
<template v-if="checked.length"> |
||||||
|
<div class="line"> |
||||||
|
<el-checkbox v-model="checkedAllCheck" @change="checkedAllCheckChange"></el-checkbox> |
||||||
|
<span class="username">姓名</span> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="lines"> |
||||||
|
<template v-for="(item, i) in checked"> |
||||||
|
<div v-if="item.userName.includes(checkedKeyword)" :key="i" class="line"> |
||||||
|
<div class="check-left"> |
||||||
|
<el-checkbox v-model="item.check"></el-checkbox> |
||||||
|
<p class="username" :title="item.userName">{{ item.userName }}</p> |
||||||
|
</div> |
||||||
|
<i class="el-icon-delete action-icon" @click="delChecked(item)"></i> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div v-else class="empty"> |
||||||
|
<img class="icon" src="@/assets/images/empty.svg" alt=""> |
||||||
|
<p>暂无数据</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script> |
||||||
|
import Setting from '@/setting' |
||||||
|
import Util from '@/libs/util' |
||||||
|
import _ from 'lodash' |
||||||
|
import Decimal from 'decimal.js' |
||||||
|
export default { |
||||||
|
data () { |
||||||
|
return { |
||||||
|
nakadais: [], |
||||||
|
searchTimer: null, |
||||||
|
|
||||||
|
userType: '', |
||||||
|
userCheck: false, |
||||||
|
users: [], |
||||||
|
userKeyword: '', |
||||||
|
|
||||||
|
checkedKeyword: '', |
||||||
|
checkedAllCheck: false, |
||||||
|
checked: [], |
||||||
|
submiting: false, |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
'quesBankKeyword': function (val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(this.initQuesBank, 500) |
||||||
|
}, |
||||||
|
'userKeyword': function (val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(this.getKnowledge, 500) |
||||||
|
}, |
||||||
|
}, |
||||||
|
mounted () { |
||||||
|
this.getNakadais() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 获取中台部门 |
||||||
|
async getNakadais () { |
||||||
|
const res = await this.$post(this.api.treeListArch) |
||||||
|
const list = res.treeList |
||||||
|
this.handleList(list) |
||||||
|
this.nakadais = list |
||||||
|
}, |
||||||
|
// 处理树形 |
||||||
|
handleList (list) { |
||||||
|
list.map(e => { |
||||||
|
if (e.children && e.children.length) { |
||||||
|
this.handleList(e.children) |
||||||
|
} else { |
||||||
|
delete e.children |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
async getNakadaiUser (data) { |
||||||
|
console.log(11, data) |
||||||
|
const { page } = await this.$post(this.api.staffList, { |
||||||
|
type: 1, |
||||||
|
staffArchitectureId: data.id || '', |
||||||
|
keyWord: this.userKeyword, |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 1000 |
||||||
|
}) |
||||||
|
this.users = page.records |
||||||
|
}, |
||||||
|
nakadaiClick () { |
||||||
|
|
||||||
|
}, |
||||||
|
// 获取题库 |
||||||
|
async getQuesBank () { |
||||||
|
try { |
||||||
|
const type = this.quesBankTypeVal |
||||||
|
const res = await this.$post(this.api.questionBankList, { |
||||||
|
status: 1, |
||||||
|
pageNum: 1, |
||||||
|
pageSize: 1000, |
||||||
|
questionCategoryId: type.length ? type[type.length - 1] : '', |
||||||
|
name: this.quesBankKeyword |
||||||
|
}) |
||||||
|
this.quesBanks = res.message.records |
||||||
|
this.totalQuesBank = res.message.total |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 题目多选回调 |
||||||
|
questionBankClick (item) { |
||||||
|
this.curQuesBank = item |
||||||
|
this.userCheck = false |
||||||
|
this.getKnowledgeType() |
||||||
|
this.getKnowledge() |
||||||
|
}, |
||||||
|
|
||||||
|
// 处理树形 |
||||||
|
handleList (list) { |
||||||
|
list.map(e => { |
||||||
|
if (e.children && e.children.length) { |
||||||
|
this.handleList(e.children) |
||||||
|
} else { |
||||||
|
delete e.children |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 用户全选回调 |
||||||
|
userAllCheckChange (val) { |
||||||
|
this.users.map(e => { |
||||||
|
e.check = val |
||||||
|
this.userChange(val, e) |
||||||
|
}) |
||||||
|
}, |
||||||
|
// 用户勾选回调 |
||||||
|
userChange (val, item) { |
||||||
|
const cur = this.checked.findIndex(e => e.userId === item.userId) |
||||||
|
// 选中 |
||||||
|
if (val) { |
||||||
|
if (cur === -1) { |
||||||
|
const e = _.cloneDeep(item) |
||||||
|
e.check = false |
||||||
|
this.checked.push(e) |
||||||
|
} |
||||||
|
} else { |
||||||
|
// 取消选中 |
||||||
|
cur >= 0 && this.checked.splice(cur, 1) |
||||||
|
} |
||||||
|
}, |
||||||
|
// 处理大纲列表 |
||||||
|
handleQuesList () { |
||||||
|
this.list = _.cloneDeep(this.$parent.form.paperOutline) |
||||||
|
}, |
||||||
|
// 已选全选回调 |
||||||
|
checkedAllCheckChange (val) { |
||||||
|
this.checked.map(e => e.check = val) |
||||||
|
}, |
||||||
|
// 批量移除已选 |
||||||
|
async batchDelChecked (val) { |
||||||
|
try { |
||||||
|
const checked = this.checked.filter(e => e.check) |
||||||
|
if (checked.length) { |
||||||
|
checked.map(e => { |
||||||
|
const cur = this.users.find(n => n.userId === e.userId) |
||||||
|
if (cur) { |
||||||
|
cur.check = false |
||||||
|
} |
||||||
|
}) |
||||||
|
this.userCheck = false |
||||||
|
this.checkedAllCheck = false |
||||||
|
this.checked = this.checked.filter(e => !e.check) |
||||||
|
} else { |
||||||
|
Util.warningMsg('请选择数据') |
||||||
|
} |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
// 已选单个删除 |
||||||
|
async delChecked (item) { |
||||||
|
try { |
||||||
|
const cur = this.users.find(e => e.userId === item.userId) |
||||||
|
if (cur) cur.check = false |
||||||
|
this.checked.splice(this.checked.findIndex(e => e.userId === item.userId), 1) |
||||||
|
} catch (e) { } |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
// 提交 |
||||||
|
async submit () { |
||||||
|
if (this.submiting) return false |
||||||
|
|
||||||
|
this.submiting = true |
||||||
|
|
||||||
|
try { |
||||||
|
const res = await this.$post(this.api.selectQuestionsByTypeAndDifficulty, list) |
||||||
|
|
||||||
|
let invalid = 0 |
||||||
|
let hasQues = 0 |
||||||
|
list.map((e, i) => { |
||||||
|
if (+e.count !== res.list[i].questions.length) invalid = 1 |
||||||
|
if (e.examQuestions.length) hasQues = 1 |
||||||
|
e.score = 0 |
||||||
|
}) |
||||||
|
|
||||||
|
// 3种情况提示不一样 |
||||||
|
const tips = invalid && hasQues ? |
||||||
|
'此操作会清空当前试卷已添加的试题,并且满足自动选题设置的试题数量不足,确定要继续自动选题吗?' : |
||||||
|
invalid && !hasQues ? |
||||||
|
'满足自动选题设置的试题数量不足,确认要继续自动选题吗?' : |
||||||
|
!invalid && hasQues ? '此操作会清空当前试卷已添加的试题,是否确定要继续自动选题吗?' : |
||||||
|
'' |
||||||
|
|
||||||
|
if (tips) { |
||||||
|
await this.$confirm(tips, '提示', { |
||||||
|
confirmButtonText: '确定', |
||||||
|
cancelButtonText: '取消', |
||||||
|
type: 'warning', |
||||||
|
closeOnClickModal: false, |
||||||
|
}) |
||||||
|
} |
||||||
|
list.map((e, i) => { |
||||||
|
res.list[i].questions.map((e, i) => { |
||||||
|
e.questionId = e.id |
||||||
|
e.serialNumber = i + 1 |
||||||
|
e.originSort = i + 1 |
||||||
|
this.$parent.handleQuesInfo(e) |
||||||
|
}) |
||||||
|
this.$parent.form.paperOutline[i].examQuestions = res.list[i].questions |
||||||
|
}) |
||||||
|
this.allocationVisible = false |
||||||
|
this.$parent.calcDifficult() |
||||||
|
this.submiting = false |
||||||
|
} catch (e) { |
||||||
|
this.submiting = false |
||||||
|
} |
||||||
|
}, |
||||||
|
// 弹框关闭回调 |
||||||
|
closeDia () { |
||||||
|
this.$emit('update:visible', false) |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.wrap { |
||||||
|
display: flex; |
||||||
|
margin-top: 20px; |
||||||
|
border: 1px solid #eee; |
||||||
|
|
||||||
|
.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled) { |
||||||
|
box-shadow: none; |
||||||
|
} |
||||||
|
|
||||||
|
.item { |
||||||
|
width: 30%; |
||||||
|
padding: 15px; |
||||||
|
border-right: 1px solid #eee; |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
width: 40%; |
||||||
|
border-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.total { |
||||||
|
font-size: 16px; |
||||||
|
color: #333; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.users { |
||||||
|
padding-left: 44px; |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.lines { |
||||||
|
height: calc(100vh - 392px); |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.line { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 5px 0; |
||||||
|
color: #333; |
||||||
|
|
||||||
|
.username { |
||||||
|
margin: 0 12px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.check-left { |
||||||
|
display: inline-flex; |
||||||
|
align-items: center; |
||||||
|
width: calc(100% - 30px); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.action-icon { |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
Loading…
Reference in new issue