yujialong 3 months ago
parent 2a049f380e
commit 05840159d0
  1. 3
      src/components/ueditorPlus/index.vue
  2. 20
      src/pages/ques/detail/index.vue
  3. 27
      src/pages/ques/list/index.vue
  4. 68
      src/pages/testPaper/detail/auto.vue
  5. 17
      src/pages/testPaper/detail/index.vue
  6. 368
      src/pages/testPaper/detail/manual.vue
  7. 2
      src/pages/testPaperLibrary/index.vue
  8. 1
      src/router/permission.js
  9. 2
      src/setting.js

@ -48,11 +48,12 @@ export default {
}, },
methods: { methods: {
initEditor () { initEditor () {
const host = Setting.isPro ? location.origin : `http://121.37.12.51`
this.$nextTick(() => { this.$nextTick(() => {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
this.instance = UE.getEditor(this.randomId, { this.instance = UE.getEditor(this.randomId, {
UEDITOR_HOME_URL: Setting.isDev ? '/static/ueditorPlus/' : '/examination/static/ueditorPlus/', UEDITOR_HOME_URL: Setting.isDev ? '/static/ueditorPlus/' : '/examination/static/ueditorPlus/',
serverUrl: "http://121.37.12.51/exam/exam/upload/configAndUpload", serverUrl: host + `/exam/exam/upload/configAndUpload`,
plugins: 'gapfilling', plugins: 'gapfilling',
...this.config ...this.config
}) })

@ -22,7 +22,7 @@
<el-form-item prop="knowledgePointIds" label="所属知识点"> <el-form-item prop="knowledgePointIds" label="所属知识点">
<el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges" <el-cascader placeholder="请选择所属知识点" v-model="form.knowledgePointIds" :options="knowledges"
:props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" :show-all-levels="false" :props="{ value: 'id', label: 'name', multiple: true, checkStrictly: true }" :show-all-levels="false"
clearable></el-cascader> filterable clearable></el-cascader>
</el-form-item> </el-form-item>
</div> </div>
<div class="item-line"> <div class="item-line">
@ -155,10 +155,8 @@
<el-button v-if="detailType === 1" type="primary" :loading="submiting && keep === 0" <el-button v-if="detailType === 1" type="primary" :loading="submiting && keep === 0"
@click="submit(1)">保存</el-button> @click="submit(1)">保存</el-button>
<template v-else> <template v-else>
<el-button type="primary" :loading="submiting && keep === 0" @click="submit(0)">{{ questionId ? '仅更新此题' : <el-button type="primary" :loading="submiting && keep === 0" @click="submit(0)">保存</el-button>
'保存' <el-button type="primary" :loading="submiting && keep === 1" @click="submit(1)">{{ questionId ? '保存并同步更新相似题'
}}</el-button>
<el-button type="primary" :loading="submiting && keep === 1" @click="submit(1)">{{ questionId ? '同步更新相似题'
: :
'保存并继续新增' }}</el-button> '保存并继续新增' }}</el-button>
</template> </template>
@ -166,7 +164,8 @@
</div> </div>
<el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false"> <el-dialog title="提示" :visible.sync="repeatVisible" width="800px" :close-on-click-modal="false">
<el-alert title="与当前题库中已有的试题重复(如下),是否继续保存?" type="warning" effect="dark" :closable="false" /> <el-alert title="您确定要保存对本题所做的更改吗?更新后,所有关联的试卷将会自动更新" type="warning" effect="dark" :closable="false" />
<p class="m-t-10 m-b-10 fs-12">系统已经识别出题库中有与本题相似的其他题目如果您选择同步更新这些相似题目那么所有关联的试卷将会自动更新</p>
<el-table class="m-t-10" :data="repeats" stripe header-align="center" row-key="id"> <el-table class="m-t-10" :data="repeats" stripe header-align="center" row-key="id">
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="题型" align="center" min-width="120"> <el-table-column prop="name" label="题型" align="center" min-width="120">
@ -299,12 +298,15 @@ export default {
}, },
}, },
mounted () { mounted () {
const { query } = this.$route
this.crumbs = [ this.crumbs = [
{ {
name: '试题管理', name: '试题管理',
route: 'list', route: 'list',
query: { query: {
id: this.questionBankId questionBankId: query.questionBankId,
questionBankName: query.questionBankName,
questionBankCategory: query.questionBankCategory,
} }
}, },
{ {
@ -636,7 +638,7 @@ export default {
} else { } else {
// //
try { try {
await this.$confirm(`<p style="margin-bottom: 10px;">确认仅更新此题吗?</p>${this.detailType === 4 ? '' : '<p>更新后,相关试卷自动同步</p>'}`, '提示', { await this.$confirm(`<p style="margin-bottom: 10px;">您确定要保存对本题所做的更改吗?</p>${this.detailType === 4 ? '' : '<p>保存后,所有关联的试卷将会自动更新</p>'}`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -669,7 +671,7 @@ export default {
type === 4 && this.$emit('updateQues', this.tempForm, res.questionVersionId) type === 4 && this.$emit('updateQues', this.tempForm, res.questionVersionId)
Util.successMsg('保存成功') Util.successMsg('保存成功')
!form.questionId && this.keep ? this.init() : this.back() !form.questionId && this.keep ? '' : this.back()
this.repeatVisible = false this.repeatVisible = false
} finally { } finally {
this.submiting = false this.submiting = false

@ -127,7 +127,7 @@
<el-button type="text" :disabled="!isKnowLedge" @click="remove(scope.row)">移除</el-button> <el-button type="text" :disabled="!isKnowLedge" @click="remove(scope.row)">移除</el-button>
<el-button type="text" @click="del([scope.row])">删除</el-button> <el-button type="text" @click="del([scope.row])">删除</el-button>
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" style="margin: 0 10px 0 5px" <el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" style="margin: 0 10px 0 5px"
:active-text="scope.row.status ? '开' : '关'" :active-text="scope.row.status ? '启用' : '禁用'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch> @change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
@ -247,7 +247,7 @@ export default {
givenYearSort: '', givenYearSort: '',
difficultySort: '', difficultySort: '',
correctRateSort: '', correctRateSort: '',
updateTimeSort: 'desc', updateTimeSort: '',
referenceCountSort: '', referenceCountSort: '',
}, },
list: [], list: [],
@ -324,7 +324,10 @@ export default {
}, },
// //
toSet () { toSet () {
this.$router.push(`/knowledge?questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}`) this.$router.push({
path: '/knowledge',
query: this.$route.query
})
}, },
// //
typeChange () { typeChange () {
@ -419,11 +422,25 @@ export default {
// //
add () { add () {
const knowledgeCheck = this.$refs.typeTree.getCurrentNode() const knowledgeCheck = this.$refs.typeTree.getCurrentNode()
this.$router.push(`detail?questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}&questionBankCategory=${this.questionBankCategory}&path=${knowledgeCheck && knowledgeCheck.type ? knowledgeCheck.path : ''}`) this.$router.push({
path: 'detail',
query: {
...this.$route.query,
path: knowledgeCheck && knowledgeCheck.type ? knowledgeCheck.path : ''
}
})
}, },
// / type: 123 // / type: 123
toDetail (row, type) { toDetail (row, type) {
this.$router.push(`detail?questionId=${row.questionId}&version=${row.version}&questionBankId=${this.questionBankId}&questionBankName=${this.questionBankName}&questionBankCategory=${this.questionBankCategory}&detailType=${type}`) this.$router.push({
path: 'detail',
query: {
...this.$route.query,
questionId: row.questionId,
version: row.version,
detailType: type
}
})
}, },
// //
async remove (row) { async remove (row) {

@ -63,7 +63,7 @@
<label>题库分类</label> <label>题库分类</label>
<el-cascader style="width: 240px;" placeholder="请选择题库分类" v-model="quesBankTypeVal" <el-cascader style="width: 240px;" placeholder="请选择题库分类" v-model="quesBankTypeVal"
:options="quesBankTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable :options="quesBankTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable
@change="getQuesBank"></el-cascader> @change="initQuesBank"></el-cascader>
</li> </li>
<li> <li>
<el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" clearable /> <el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" clearable />
@ -76,9 +76,9 @@
<span>题库名称</span> <span>题库名称</span>
</div> </div>
<div class="lines"> <div class="able-check">
<div v-for="(item, i) in quesBanks" :key="i" <div v-for="(item, i) in quesBanks" :key="i" :class="['line', { active: curQuesBank.id === item.id }]"
:class="['line able-check', { active: curQuesBank.id === item.id }]" @click="questionBankClick(item)"> @click="questionBankClick(item)">
<span class="serial first">{{ i + 1 }}</span> <span class="serial first">{{ i + 1 }}</span>
<p class="stem" :title="item.questionBankName">{{ item.questionBankName }}</p> <p class="stem" :title="item.questionBankName">{{ item.questionBankName }}</p>
</div> </div>
@ -142,16 +142,18 @@
</p> </p>
</div> </div>
<div v-for="(item, i) in checked" :key="i" class="j-between m-b-10"> <template v-for="(item, i) in checked">
<div class="flex a-center"> <div :key="i" class="j-between m-b-10">
题库{{ item.quesBank.questionBankName }} <div class="flex a-center">
<i class="el-icon-delete action-icon m-l-10" @click="delQuesBank(i)"></i> 题库{{ item.quesBank.questionBankName }}
</div> <i class="el-icon-delete action-icon m-l-10" @click="delQuesBank(i)"></i>
<div class="knowledges"> </div>
<el-tag v-for="(tag, j) in item.knowledges" :key="tag.name" class="m-r-8 m-b-8" closable <div class="knowledges">
@close="delKnowledge(i, j, item, tag)">{{ tag.name }}</el-tag> <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> </div>
</div> </template>
</div> </div>
</div> </div>
@ -194,7 +196,6 @@ export default {
quesBankTypes: [], quesBankTypes: [],
quesBankKeyword: '', quesBankKeyword: '',
quesAllCheck: false,
quesBanks: [], quesBanks: [],
pageQuesBank: 1, pageQuesBank: 1,
pageSizeQuesBank: 10, pageSizeQuesBank: 10,
@ -209,6 +210,7 @@ export default {
pageSizeKn: 10, pageSizeKn: 10,
totalKn: 0, totalKn: 0,
checkedKeyword: '',
checked: [], checked: [],
list: [], list: [],
years: ['暂无年份', '2024', '2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '更早'], years: ['暂无年份', '2024', '2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '更早'],
@ -229,7 +231,7 @@ export default {
watch: { watch: {
'quesBankKeyword': function (val) { 'quesBankKeyword': function (val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getQuesBank, 500) this.searchTimer = setTimeout(this.initQuesBank, 500)
}, },
'knowledgeKeyword': function (val) { 'knowledgeKeyword': function (val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
@ -249,7 +251,7 @@ export default {
this.yearCheck = this.years this.yearCheck = this.years
this.handleQuesList() this.handleQuesList()
this.getQuesBankType() this.getQuesBankType()
this.getQuesBank() this.initQuesBank()
this.difficult = this.$parent.form.difficult this.difficult = this.$parent.form.difficult
this.difficult && this.difficultChange(this.difficult) this.difficult && this.difficultChange(this.difficult)
}, },
@ -279,6 +281,11 @@ export default {
this.totalQuesBank = res.message.total this.totalQuesBank = res.message.total
} catch (e) { } } catch (e) { }
}, },
initQuesBank () {
this.curQuesBank = {}
this.pageQuesBank = 1
this.getQuesBank()
},
// //
currentChangeQuesBank (val) { currentChangeQuesBank (val) {
this.pageQuesBank = val this.pageQuesBank = val
@ -316,16 +323,19 @@ export default {
// //
async getKnowledge () { async getKnowledge () {
try { try {
const type = this.knowledgeTypeVal const { id } = this.curQuesBank
const res = await this.$post(this.api.knowledgeHierarchyList, { if (id) {
pageNum: this.pageKn, const type = this.knowledgeTypeVal
pageSize: this.pageSizeKn, const res = await this.$post(this.api.knowledgeHierarchyList, {
questionBankId: this.curQuesBank.id, pageNum: this.pageKn,
knowledgePointCategoryId: type.length ? type[type.length - 1] : '', pageSize: this.pageSizeKn,
name: this.knowledgeKeyword, questionBankId: id,
}) knowledgePointCategoryId: type.length ? type[type.length - 1] : '',
this.knowledges = res.message.records name: this.knowledgeKeyword,
this.totalKn = res.message.total })
this.knowledges = res.message.records
this.totalKn = res.message.total
}
} catch (e) { } } catch (e) { }
}, },
// //
@ -617,13 +627,15 @@ export default {
margin-top: 10px; margin-top: 10px;
} }
.line { .line {
display: flex; display: flex;
padding: 5px 0; padding: 5px 0;
color: #333; color: #333;
&.able-check { }
.able-check {
.line {
cursor: pointer; cursor: pointer;
&:hover { &:hover {

@ -165,7 +165,8 @@
<div class="actions"> <div class="actions">
<div class="sort"> <div class="sort">
<span>排序</span> <span>排序</span>
<el-input class="l-input sort-input" v-model="ques.serialNumber" /> <el-input class="l-input sort-input" v-model="ques.serialNumber"
@change="sortChange(item, ques)" />
</div> </div>
<el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button> <el-button type="text" @click="toQues(item, j, ques)">编辑试题</el-button>
<el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button> <el-button type="text" @click="showManualDia(item, j, ques)">更换试题</el-button>
@ -370,7 +371,8 @@ export default {
const paper = r.paperOutline const paper = r.paperOutline
paper.map(e => { paper.map(e => {
e.shrink = false e.shrink = false
e.examQuestions.map(n => { e.examQuestions.map((n, j) => {
n.originSort = j + 1
Object.assign(n, n.question) Object.assign(n, n.question)
}) })
@ -638,6 +640,17 @@ export default {
this.$set(e, 'serialNumber', i + 1) this.$set(e, 'serialNumber', i + 1)
}) })
}, },
//
sortChange (item, ques) {
item.examQuestions.sort((a, b) => {
if (a.serialNumber == b.serialNumber && (a.questionVersionId === ques.questionVersionId || b.questionVersionId === ques.questionVersionId)) return b.originSort - a.originSort
return a.serialNumber - b.serialNumber
})
item.examQuestions.map((e, i) => {
e.originSort = i + 1
e.serialNumber = i + 1
})
},
// //
async delQues (item, i) { async delQues (item, i) {
try { try {

@ -6,33 +6,63 @@
<!-- 题库 --> <!-- 题库 -->
<div class="item"> <div class="item">
<p class="total m-b-10">题库</p> <p class="total m-b-10">题库</p>
<el-input class="m-b-10" placeholder="请输入题库分类/题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" <ul class="filter">
clearable /> <li class="m-b-10">
<el-tree :key="key" node-key="id" default-expand-all ref="quesBank" :data="quesBanks" <label>题库分类</label>
:props="{ label: 'name' }" @node-click="getKnowledge" @check-change="quesBankCheck"></el-tree> <el-cascader style="width: 240px;" placeholder="请选择题库分类" v-model="quesBankTypeVal"
</div> :options="quesBankTypes" :props="{ value: 'id', label: 'name', checkStrictly: true }" clearable
<!-- 知识点 --> @change="initQuesBank"></el-cascader>
<div class="item"> </li>
<p class="total m-b-10">知识点框架</p> <li>
<el-input class="m-b-10" placeholder="请输入知识点分类/知识点名称" prefix-icon="el-icon-search" v-model="knowledgeKeyword" <el-input placeholder="请输入题库名称" prefix-icon="el-icon-search" v-model="quesBankKeyword" clearable />
clearable /> </li>
<el-tree :data="knowledges" default-expand-all ref="knowledge" node-key="id" highlight-current </ul>
:expand-on-click-node="false" @node-click="getQues" @check-change="knowledgeCheck"
:props="{ label: 'name' }"> <template v-if="quesBanks.length">
<span class="custom-tree-node" slot-scope="{ node, data }"> <div class="line">
<img v-if="data.type" class="m-r-5" src="@/assets/images/knowledge.svg" alt=""> <span class="serial">序号</span>
<span class="org-name">{{ data.name }}</span> <span>题库名称</span>
</span> </div>
</el-tree>
<div class="able-check">
<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>
<div class="pagination">
<el-pagination background @current-change="currentChangeQuesBank" small :current-page="pageQuesBank"
layout="total, prev, pager, next" :total="totalQuesBank"></el-pagination>
</div>
</template>
<div v-else class="empty">
<img class="icon" src="@/assets/images/empty.svg" alt="">
<p>暂无数据</p>
</div>
</div> </div>
<!-- 题目 --> <!-- 题目 -->
<div class="item"> <div class="item">
<p class="total">{{ questionTypeName }}{{ ques.length }}道题</p> <p class="total m-b-10">{{ questionTypeName }}{{ ques.length }}道题</p>
<div class="ques">
<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"> <div class="line">
<el-checkbox v-model="quesAllCheck" @change="quesAllCheckChange"></el-checkbox> <el-checkbox v-model="quesAllCheck" @change="quesAllCheckChange"></el-checkbox>
<span class="serial">序号</span> <span class="serial">序号</span>
<span>题干</span> <span class="stem">题干</span>
<span class="kl">知识点</span>
</div> </div>
<div v-for="(item, i) in ques" :key="i" class="line"> <div v-for="(item, i) in ques" :key="i" class="line">
@ -40,9 +70,16 @@
@change="val => quesChange(val, item)"></el-checkbox> @change="val => quesChange(val, item)"></el-checkbox>
<span class="serial">{{ i + 1 }}</span> <span class="serial">{{ i + 1 }}</span>
<el-tooltip effect="dark" :content="item.stemText" placement="top-start"> <el-tooltip effect="dark" :content="item.stemText" placement="top-start">
<p class="stem" :title="item.stemText">{{ item.stemText }}</p> <p class="stem">{{ item.stemText }}</p>
</el-tooltip>
<el-tooltip effect="dark" :content="item.knowledgePointName" placement="top-start">
<p class="kl">{{ item.knowledgePointName }}</p>
</el-tooltip> </el-tooltip>
</div> </div>
</template>
<div v-else class="empty">
<img class="icon" src="@/assets/images/empty.svg" alt="">
<p>暂无数据</p>
</div> </div>
</div> </div>
<!-- 已选试题 --> <!-- 已选试题 -->
@ -57,30 +94,47 @@
<p v-else class="total">已选试题{{ checkedLen }}道题</p> <p v-else class="total">已选试题{{ checkedLen }}道题</p>
<el-button type="text" @click="batchDelChecked">批量移除</el-button> <el-button type="text" @click="batchDelChecked">批量移除</el-button>
</div> </div>
<div class="ques">
<div class="line">
<el-checkbox v-model="checkedAllCheck" @change="checkedAllCheckChange"></el-checkbox>
<span class="serial">序号</span>
<span>题干</span>
</div>
<div v-for="(item, i) in checked" :key="i" class="line j-between"> <el-input class="m-t-10 m-b-10" placeholder="请输入题干/知识点" prefix-icon="el-icon-search" v-model="checkedKeyword"
<div class="check-left"> clearable />
<el-checkbox v-model="item.check"></el-checkbox>
<span class="serial">{{ i + 1 }}</span> <template v-if="checked.length">
<el-tooltip effect="dark" :content="item.stemText" placement="top-start"> <div class="ques">
<p class="checked-stem" :title="item.stemText">{{ item.stemText }}</p> <div class="line">
</el-tooltip> <el-checkbox v-model="checkedAllCheck" @change="checkedAllCheckChange"></el-checkbox>
<span class="serial">序号</span>
<span class="stem">题干</span>
<span class="kl">知识点</span>
</div> </div>
<i class="el-icon-delete action-icon" @click="delChecked(item)"></i>
<template v-for="(item, i) in checked">
<div v-if="item.stemText.includes(checkedKeyword) || item.knowledgePointName.includes(checkedKeyword)"
:key="i" class="line j-between">
<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>
</div> </div>
<div class="flex j-between p-l-10 p-r-10"> <div class="flex j-between p-l-20 p-r-20">
<p>未找到试题<a class="link" @click="toAddQues">去新增</a></p> <p>未找到试题<a class="link" @click="toAddQues">去新增</a></p>
<p>已选题数/目标题数{{ checkedLen }}/{{ $parent.curType.questionNum }}&emsp;&emsp; <p>已选题数/目标题数{{ checkedLen }}/{{ $parent.curType.questionNum }}
<!-- <a class="link" @click="toEditQues">修改目标</a> --> <!-- &emsp;&emsp;<a class="link" @click="toEditQues">修改目标</a> -->
</p> </p>
</div> </div>
@ -101,17 +155,26 @@ export default {
data () { data () {
return { return {
selectQuesVisible: false, selectQuesVisible: false,
searchTimer: null,
quesBankKeyword: '', quesBankKeyword: '',
curQuesBank: {},
quesBankTypeVal: [],
quesBankTypes: [],
quesBanks: [],
pageQuesBank: 1,
pageSizeQuesBank: 10,
totalQuesBank: 0,
knowledgeKeyword: '', knowledgeKeyword: '',
searchTimer: null,
key: 1, key: 1,
quesBanks: [], knowledgeVal: [],
knowledges: [], knowledges: [],
quesAllCheck: false, quesAllCheck: false,
ques: [], ques: [],
checkedAllCheck: false, checkedAllCheck: false,
checked: [], checked: [],
curCheckQues: [], curCheckQues: [],
checkedKeyword: '',
submiting: false, submiting: false,
quesVisible: false, quesVisible: false,
@ -141,11 +204,11 @@ export default {
watch: { watch: {
'quesBankKeyword': function (val) { 'quesBankKeyword': function (val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getQuesBank, 500) this.searchTimer = setTimeout(this.initQuesBank, 500)
}, },
'knowledgeKeyword': function (val) { 'knowledgeKeyword': function (val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getKnowledge, 500) this.searchTimer = setTimeout(this.getQues, 500)
}, },
visible () { visible () {
this.selectQuesVisible = this.visible this.selectQuesVisible = this.visible
@ -171,69 +234,109 @@ export default {
const parent = this.$parent.curType const parent = this.$parent.curType
this.curCheckQues = parent.examQuestions this.curCheckQues = parent.examQuestions
this.getQuesBank() 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 () { async getQuesBank () {
try { try {
const { list } = await this.$post(this.api.questionBankStructureLevel, { const type = this.quesBankTypeVal
keyword: this.quesBankKeyword, const res = await this.$post(this.api.questionBankList, {
createSource: 1,
status: 1, status: 1,
pageNum: this.pageQuesBank,
pageSize: this.pageSizeQuesBank,
questionCategoryId: type.length ? type[type.length - 1] : '',
name: this.quesBankKeyword
}) })
this.quesBanks = list const { records } = res.message
this.quesBanks = records
this.totalQuesBank = res.message.total
records.length && this.questionBankClick(records[0])
} catch (e) { } } 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 () { async getKnowledge () {
try { try {
const id = this.$refs.quesBank.getCurrentKey() const { id } = this.curQuesBank
if (id) { if (id) {
const { data } = await this.$post(this.api.TreeStructure, { const { data } = await this.$post(this.api.TreeStructure, {
createSource: 1, createSource: 1,
questionBankId: id, questionBankId: id,
keyword: this.knowledgeKeyword, keyword: '',
}) })
this.handleList(data)
this.knowledges = data this.knowledges = data
} }
} catch (e) { } } catch (e) { }
}, },
// //
async getQues () { async getQues () {
let k = this.$refs.knowledge.getCurrentNode() // const { id } = this.curQuesBank
// debugger let k = this.knowledgeVal //
// k = k.map(e => {
if (k && k.type) { return e[e.length - 1]
})
if (id) {
const { list } = await this.$post(this.api.findAllByQuestionBank, { const { list } = await this.$post(this.api.findAllByQuestionBank, {
status: 1, status: 1,
questionBankId: this.$refs.quesBank.getCurrentKey(), questionBankIds: [id],
knowledgePointIds: [k.id], knowledgePointIds: k,
questionTypes: this.questionType ? [this.questionType] : [], questionTypes: this.questionType ? [this.questionType] : [],
keyword: this.knowledgeKeyword,
}) })
const data = list const data = list
const checked = this.curCheckQues const { curCheckQues, checked } = this
data.map(e => { data.map(e => {
const el = document.createElement('div') const el = document.createElement('div')
el.innerHTML = e.stem el.innerHTML = e.stem
e.stemText = el.innerText e.stemText = el.innerText
e.check = !!this.checked.find(n => n.questionVersionId === e.questionVersionId) const quesChecked = !!curCheckQues.find(n => n.questionVersionId === e.questionVersionId)
e.disabled = !!checked.find(n => n.questionVersionId === e.questionVersionId) e.disabled = quesChecked
e.check = !!checked.find(n => n.questionVersionId === e.questionVersionId) || quesChecked
}) })
this.ques = data this.ques = data
} }
},
//
quesBankCheck (data, checked) {
// debugger
if (checked) {
// this.$refs.quesBank.setCurrentKey(data.id)
this.getKnowledge()
}
this.$refs.knowledge.setCheckedNodes(checked ? this.knowledges : [])
},
//
knowledgeClick (data) {
}, },
// //
knowledgeCheck () { knowledgeCheck () {
@ -242,8 +345,10 @@ export default {
// //
quesAllCheckChange (val) { quesAllCheckChange (val) {
this.ques.map(e => { this.ques.map(e => {
e.check = val if (!e.disabled) {
this.quesChange(val, e) e.check = val
this.quesChange(val, e)
}
}) })
}, },
// //
@ -270,7 +375,7 @@ export default {
try { try {
const checked = this.checked.filter(e => e.check) const checked = this.checked.filter(e => e.check)
if (checked.length) { if (checked.length) {
await this.$confirm(`确认要除吗?`, '提示', { await this.$confirm(`确认要除吗?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
@ -293,12 +398,12 @@ export default {
// //
async delChecked (item) { async delChecked (item) {
try { try {
// await this.$confirm(``, '', { await this.$confirm(`确认要移除吗?`, '提示', {
// confirmButtonText: '', confirmButtonText: '确定',
// cancelButtonText: '', cancelButtonText: '取消',
// type: 'warning', type: 'warning',
// closeOnClickModal: false, closeOnClickModal: false,
// }) })
const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId) const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId)
if (cur) cur.check = false if (cur) cur.check = false
this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1) this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1)
@ -377,16 +482,28 @@ export default {
margin-bottom: 10px; margin-bottom: 10px;
border: 1px solid #eee; 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 { .item {
width: 25%; width: 38%;
max-height: calc(100vh - 190px); height: calc(100vh - 173px);
padding: 15px; padding: 15px;
border-right: 1px solid #eee; border-right: 1px solid #eee;
overflow: auto; overflow: auto;
&:last-child {
border-right: 0;
}
} }
.total { .total {
@ -394,40 +511,69 @@ export default {
color: #333; color: #333;
} }
.ques {
margin-top: 10px;
.line {
display: flex;
padding: 5px 0;
color: #333;
}
.able-check {
.line { .line {
display: flex; cursor: pointer;
margin: 8px 0;
}
.serial { &:hover {
width: 32px; background-color: #f5f5f5;
margin: 0 12px; }
text-align: center;
white-space: nowrap;
}
.stem { &.active {
max-width: calc(100% - 71px); background-color: #e5e5e5;
@include ellipsis; }
} }
}
.checked-stem { .serial {
max-width: 165px; width: 32px;
@include ellipsis; margin: 0 12px;
} text-align: center;
white-space: nowrap;
}
.check-left { .quesBank {
display: inline-flex; width: calc(100% - 71px);
align-items: center; @include ellipsis;
} }
.action-icon { .stem {
font-size: 14px; width: calc(100% - 210px);
margin-right: 20px;
@include ellipsis;
}
.kl {
width: 120px;
@include ellipsis;
&.checked-kl {
width: 90px;
margin-right: 10px;
} }
} }
.checked-stem {
max-width: 165px;
margin-right: 20px;
@include ellipsis;
}
.check-left {
display: inline-flex;
align-items: center;
}
.action-icon {
font-size: 14px;
}
} }
.link { .link {

@ -58,7 +58,7 @@
<el-table-column prop="examPaperNum" label="试卷数量" align="center" width="100" <el-table-column prop="examPaperNum" label="试卷数量" align="center" width="100"
sortable="custom"></el-table-column> sortable="custom"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center" width="160" sortable="custom"></el-table-column> <el-table-column prop="createTime" label="创建时间" align="center" width="160" sortable="custom"></el-table-column>
<el-table-column prop="createUserName" label="创建人" align="center" width="100"></el-table-column> <el-table-column prop="createUser" label="创建人" align="center" width="100"></el-table-column>
<el-table-column label="操作" align="center" width="280"> <el-table-column label="操作" align="center" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="toTestPaper(scope.row)">试卷管理</el-button> <el-button type="text" @click="toTestPaper(scope.row)">试卷管理</el-button>

@ -4,5 +4,6 @@ import util from '@/libs/util'
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
document.title = Setting.titleSuffix document.title = Setting.titleSuffix
localStorage.setItem('examPath', to.fullPath)
next() next()
}); });

@ -2,6 +2,7 @@
* 业务配置 * 业务配置
* */ * */
const isDev = process.env.NODE_ENV === 'development' // 开发环境 const isDev = process.env.NODE_ENV === 'development' // 开发环境
const isPro = location.host.includes('huorantech.cn') //正式服
let host = location.origin let host = location.origin
if (isDev) { if (isDev) {
host = 'http://192.168.31.51:9000' host = 'http://192.168.31.51:9000'
@ -22,6 +23,7 @@ const Setting = {
errorModalType: "Message", // 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice errorModalType: "Message", // 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice
tokenExpires: 1296000000, // token在localStorage的时间(毫秒) tokenExpires: 1296000000, // token在localStorage的时间(毫秒)
isDev, isDev,
isPro,
/** /**
* 路由白名单 * 路由白名单
* */ * */

Loading…
Cancel
Save