提交 7f689cd5 authored 作者: matian's avatar matian

Merge remote-tracking branch 'origin/master'

...@@ -4,6 +4,7 @@ module.exports = { ...@@ -4,6 +4,7 @@ module.exports = {
}, },
extends: ['plugin:vue/essential', 'standard'], extends: ['plugin:vue/essential', 'standard'],
rules: { rules: {
'vue/no-mutating-props': 'off', // 暂时关闭
'vue/comment-directive': 'off', 'vue/comment-directive': 'off',
'vue/multi-word-component-names': 'off', 'vue/multi-word-component-names': 'off',
'space-before-function-paren': 'off' 'space-before-function-paren': 'off'
......
...@@ -31,6 +31,7 @@ export default { ...@@ -31,6 +31,7 @@ export default {
} }
.app-card-hd { .app-card-hd {
display: flex; display: flex;
align-items: flex-start;
} }
.app-card-hd__title { .app-card-hd__title {
flex: 1; flex: 1;
......
...@@ -147,7 +147,7 @@ export default { ...@@ -147,7 +147,7 @@ export default {
// 翻页参数设置 // 翻页参数设置
if (this.hasPagination) { if (this.hasPagination) {
params.page = this.page.currentPage.toString() params.page = this.page.currentPage.toString()
params.page_size = this.page.size.toString() params.limit = this.page.size.toString()
} }
// 接口请求之前 // 接口请求之前
if (beforeRequest) { if (beforeRequest) {
......
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
/**
* 获取知识点/标签
*/
export function getKnowledge(params) {
return httpRequest.get('/admin/v1/knowledge-point/search/x1', { params })
}
/** /**
* 获取试卷列表 * 获取试卷列表
*/ */
...@@ -34,9 +28,45 @@ export function getPaper(params) { ...@@ -34,9 +28,45 @@ export function getPaper(params) {
return httpRequest.get(`/api/qbs/admin/v1/question-paper/${params.id}`, { params }) return httpRequest.get(`/api/qbs/admin/v1/question-paper/${params.id}`, { params })
} }
/**
* 删除试卷
*/
export function batchDeletePaper(data) {
return httpRequest.post('/api/qbs/admin/v1/question-paper/batch-delete', data)
}
/**
* 获取试题列表
*/
export function getQuestionList(params) {
return httpRequest.get('/api/qbs/admin/v1/questions', { params })
}
/**
* 批量获取试题列表
*/
export function batchGetQuestionList(data) {
return httpRequest.post('/api/qbs/admin/v1/questions/batch', data)
}
/**
* 设置组题规则
* 添加试题和设置试题分数
*/
export function updatePaperRules(data) {
return httpRequest.post(`/api/qbs/admin/v1/question-paper/rules/${data.id}`, data)
}
/** /**
* 获取试卷分类 * 获取试卷分类
*/ */
export function getPaperCategory(params) { export function getPaperCategory(params) {
return httpRequest.get(`/api/qbs/admin/v1/question-category/tree/${params.project_prefix}`, { params }) return httpRequest.get(`/api/qbs/admin/v1/question-category/tree/${params.project_prefix}`, { params })
} }
/**
* 获取知识点/标签
*/
export function getKnowledge(params) {
return httpRequest.get('/admin/v1/knowledge-point/search/x1', { params })
}
<template> <template>
<el-dialog v-bind="$attrs" v-on="$listeners" :modal="false" width="20%"> <el-dialog title="批量设置分数" v-bind="$attrs" v-on="$listeners" append-to-body width="400px">
<el-form> <el-form>
<el-form-item>单选题</el-form-item> <el-form-item>单选题</el-form-item>
<el-form-item>数量:8</el-form-item> <el-form-item>数量:8</el-form-item>
......
<template>
<div>
<el-row :gutter="20" style="margin-top: 20px">
<!-- 试题列表 -->
<el-col :span="18">
<app-card title="试题列表">
<template #header-aside>
<el-button type="primary" @click="handleAdd">添加试题</el-button>
<el-button type="primary" @click="handleRemove">删除选中试题</el-button>
</template>
<question-list :list="questions">
<template v-slot:selection="item">
<el-checkbox @change="handleSelectionChange(arguments[0], item)"></el-checkbox>
</template>
</question-list>
</app-card>
</el-col>
<!-- 试题序号 -->
<el-col :span="6">
<question-num :list="questions">
<template #footer>
<el-button type="primary" @click="handleSubmit">保存试卷</el-button>
</template>
</question-num>
</el-col>
</el-row>
<!-- 选题组卷 -->
<template v-if="data.paper_type === 1">
<addPaper :visible.sync="visible" :data="data" @update="handelUpdate" v-if="visible" />
</template>
<!-- 自动组卷 -->
<template v-if="data.paper_type === 2">
<AutomaticPaper :visible.sync="visible" :data="data" @update="handelUpdate" v-if="visible" />
</template>
</div>
</template>
<script>
import QuestionList from './QuestionList.vue'
import QuestionNum from './QuestionNum.vue'
import AddPaper from './AddPaper.vue'
import AutomaticPaper from './AutomaticPaper.vue'
import { updatePaperRules } from '../api.js'
export default {
props: {
data: { type: Object, default: () => ({}) }
},
components: { QuestionList, QuestionNum, AddPaper, AutomaticPaper },
data() {
return {
visible: false,
questions: [],
multipleSelection: [] // 选择项
}
},
watch: {
data: {
immediate: true,
handler(data) {
this.questions = data.questions || []
}
}
},
computed: {},
methods: {
// 增加试题
handleAdd() {
this.visible = true
},
handleSelectionChange(checked, data) {
if (checked) {
this.multipleSelection.push(data.id)
} else {
this.multipleSelection = this.multipleSelection.filter(id => id !== data.id)
}
},
// 删除选中试题
handleRemove() {
this.questions = this.questions.filter(item => !this.multipleSelection.includes(item.id))
},
// 保存试卷
handleSubmit() {
const rules = []
this.questions.forEach(question => {
rules.push({ id: question.id, score: question.score || 0 })
if (question.children && question.children.length) {
question.children.forEach(question => {
rules.push({ id: question.id, score: question.score || 0 })
})
}
})
const parmas = { id: this.data.id, rules }
updatePaperRules(parmas).then(res => {
this.$message.success('保存成功')
})
},
// 更新详情数据
handelUpdate() {
this.$emit('update')
}
}
}
</script>
<template>
<el-card style="margin-bottom: 20px" shadow="hover">
<div class="question-item">
<div class="question-item-hd">
<div class="question-item-hd-top">
<slot name="selection"></slot>
<div class="question-index">{{ index }}</div>
<div class="question-type">{{ questionTypeText }}</div>
<div class="question-score">
<p>分数:</p>
<el-input v-model="data.score" style="width: 100px"></el-input>
</div>
</div>
<!-- 题干 -->
<div class="question-title" v-html="data.question_content"></div>
</div>
<slot>
<div class="question-item-bd">
<!-- 单选题 -->
<template v-if="questionType === 1">
<el-radio-group :disabled="disabled" :value="data.question_answer[0]">
<div class="question-item-option" v-for="item in data.question_options" :key="item.id">
<el-radio :label="item.id">{{ item.option }}</el-radio>
</div>
</el-radio-group>
</template>
<!-- 多选题 -->
<template v-if="questionType === 2">
<el-checkbox-group :disabled="disabled" :value="data.question_answer">
<div class="question-item-option" v-for="item in data.question_options" :key="item.id">
<el-checkbox :label="item.id"> {{ item.option }} </el-checkbox>
</div>
</el-checkbox-group>
</template>
<!-- 问答题 -->
<template v-if="questionType === 3">
<v-editor></v-editor>
</template>
<!-- 判断题 -->
<template v-if="questionType === 6">
<el-radio-group :disabled="disabled" :value="data.question_answer">
<div class="question-item-option" v-for="item in data.question_options" :key="item.id">
<el-radio :label="item.id">{{ item.option }}</el-radio>
</div>
</el-radio-group>
</template>
</div>
</slot>
<div class="question-item-ft"></div>
</div>
</el-card>
</template>
<script>
import VEditor from '@/components/tinymce/Index.vue'
export default {
props: {
index: { type: Number, default: 1 },
disabled: { type: Boolean, default: false },
data: { type: Object, default: () => ({}) }
},
components: { VEditor },
data() {
return {
question: {}
}
},
watch: {
data: {
immediate: true,
handler(data) {
this.question = this.genQuestion(data)
}
}
},
computed: {
// 试题类型
questionType() {
// 1单选,2多选,3简答,5案例题, 6判断, 7实操,8情景
return this.data.child_question_type || this.data.question_type
},
// 26个英文字母
A_Z() {
const result = []
for (let i = 0; i < 26; i++) {
result.push(String.fromCharCode(65 + i))
}
return result
},
// 选项类型
questionTypeText() {
const map = { 1: '单选题', 2: '多选题', 3: '问答题', 5: '案例题', 6: '判断题', 7: '实操题', 8: '情景题' }
return map[this.questionType]
}
},
methods: {
genQuestion(data) {}
}
}
</script>
<style lang="scss" scoped>
.question-item-hd-top {
display: flex;
.question-index {
margin-left: 10px;
color: #c01c40;
}
.question-type {
flex: 1;
color: #c01c40;
}
.question-score {
display: flex;
align-items: center;
p {
white-space: nowrap;
}
}
}
.question-title {
padding: 10px 0;
}
.question-item-option {
margin: 10px 0;
}
</style>
<template>
<div>
<div v-for="(item, index) in questionList" :key="index">
<!-- 简单题类型 [1,2,3,6] :根据判断题的类型渲染 -->
<el-card class="boxCard" v-if="signQuestionTypes.includes(item.question_type)" :id="`page${index}`">
<div class="boxHeader">
<div class="headerLeft">
<div class="check">
<input
type="checkbox"
class="checkInpt"
v-model="selectSubjects"
:value="item"
@change="slectSubItem(item)"
/>
</div>
<div class="title">
<div class="titleType">{{ index + 1 }}{{ item.question_title }}</div>
<div class="titleDec" v-html="item.question_content"></div>
</div>
</div>
<div class="pmty"></div>
<div class="headerRight">
<div class="scoreValue">
<span class="lableScore">分数:</span>
<el-input v-model="item.score"></el-input>
</div>
</div>
</div>
<div class="boxMain">
<el-radio-group class="options">
<el-radio v-for="(v, index) in item.question_options" :key="index" :label="v.options" class="option">{{
v.options
}}</el-radio>
</el-radio-group>
</div>
<div class="boxFooter">
<div>正确答案:</div>
<div class="boxAnswer">{{ item.question_answer }}</div>
</div>
</el-card>
<!-- 复杂题类型 [5,7,8] :根据判断题的类型渲染 复杂利用上面的头部,内部重新写个页面渲染复杂题中的小题-->
<el-card class="boxCard" v-if="intricacyQuestionTypes.includes(item.question_type)" :id="`page${index}`">
<div class="boxHeader">
<div class="headerLeft">
<div class="check">
<input
type="checkbox"
class="checkInpt"
v-model="selectSubjects"
:value="item"
@change="slectSubItem(item)"
/>
</div>
<div class="title">
<div class="titleType">{{ index + 1 }}{{ item.question_title }}</div>
<div class="titleDec" v-html="item.question_content"></div>
</div>
</div>
<div class="headerRight">
<div class="scoreValue">
<span class="lableScore">分数:</span>
<el-input :value="getSubScore(item)"></el-input>
</div>
</div>
</div>
<div class="intricacyBoxMain" v-for="(v, index) in item.list" :key="index" style="margin-top: 20px">
<div class="intricacyHeader">
<div class="intricacyDsc">
<div class="intricacyTitle">{{ index + 1 }}{{ v.question_title }}</div>
<div class="titleDec" v-html="v.question_content"></div>
</div>
<div class="intricacyScoreValue">
<span class="lableScore">分数:</span>
<el-input v-model="v.score"></el-input>
</div>
<div class="empty"></div>
</div>
<div class="intricacyMain">
<el-radio-group class="options">
<el-radio v-for="(o, index) in v.question_options" :key="index" :label="o.options" class="option">{{
o.options
}}</el-radio>
</el-radio-group>
</div>
<div class="intricacyFooter">
<div>正确答案:</div>
<div class="intricacyAnswer">{{ v.question_answer }}</div>
</div>
</div>
</el-card>
</div>
</div>
</template>
<script>
export default {
// 问答、情景、案例
props: {
questionList: {
// 试题数据
type: Array
}
},
data() {
return {
selectSubjects: [], // 选中的题
signQuestionTypes: [1, 2, 3, 6], // 简单题类型
intricacyQuestionTypes: [5, 7, 8] // 复杂题类型
}
},
methods: {
// 根据小题的分数计算大题的分数,以至于监听分数变化 s.score*1 是为了下次修改,返回的是字符串变成number类型才可以计算
getSubScore(item) {
return item?.list?.map(s => parseInt(s.score) * 1).reduce((pre, em) => pre + em, 0)
},
// 返回点击题号的offsettop
handleScroll(key) {
const PageId = document.querySelector('#page' + key)
this.$emit('handlePosition', PageId.offsetTop)
},
// 选中的数据回传
slectSubItem(item) {
console.log(item)
this.$emit('selectSubjectsChange', this.selectSubjects)
}
}
}
</script>
<style lang="scss">
.boxCard {
margin-bottom: 10px;
.boxHeader {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
.headerLeft {
flex: 0.75;
display: flex;
.check {
margin-right: 20px;
}
.title {
justify-content: space-around;
.titleType {
width: 200px;
color: #1890ff;
}
}
.checkInpt .title {
display: inline-block;
}
}
.pmty {
flex: 0.05;
}
.headerRight {
flex: 0.2;
display: flex;
position: relative;
.scoreValue {
position: absolute;
top: 0px;
display: flex;
align-items: center;
.lableScore {
width: 100px;
}
}
}
}
.boxMain {
padding-left: 70px;
.options {
display: flex;
flex-direction: column;
.option {
margin-bottom: 5px;
}
}
}
.boxFooter {
margin-top: 30px;
padding-left: 40px;
display: flex;
align-items: center;
.boxAnswer {
color: #1890ff;
font-size: 14px;
}
}
.intricacyBoxMain {
padding-left: 70px;
padding-top: 20px;
.options {
display: flex;
flex-direction: column;
.option {
margin-bottom: 5px;
}
}
.intricacyHeader {
display: flex;
align-items: center;
.intricacyDsc {
flex: 0.8;
.intricacyTitle {
width: 200px;
color: #949091;
}
}
.intricacyScoreValue {
flex: 0.2;
margin-left: 50px;
display: flex;
align-items: center;
.lableScore {
width: 80px;
}
}
}
.intricacyMain {
padding-left: 30px;
}
.intricacyFooter {
margin-top: 10px;
display: flex;
align-items: center;
.intricacyAnswer {
color: #1890ff;
font-size: 14px;
}
}
}
}
</style>
<template> <template>
<el-card> <app-card class="fixed">
<div class="titleIndex"> <div class="question-num">
<ul> <div class="question-num-bd">
<li <ul>
:class="currentIndex === index ? `dotItem` : ''" <li :class="className" v-for="(item, index) in list" :key="index" @click="handleClick(index)">
v-for="(item, index) in list" {{ index + 1 }}
:key="index" </li>
@click="TitleClick(index)" </ul>
> </div>
{{ index + 1 }} <div class="question-num-ft">
</li> <slot name="footer"></slot>
</ul>
<div style="margin-top: 10px; display: flex; justify-content: center; align-items: center">
<el-button type="primary">保存试卷</el-button>
</div> </div>
</div> </div>
</el-card> </app-card>
</template> </template>
<script> <script>
...@@ -31,8 +28,13 @@ export default { ...@@ -31,8 +28,13 @@ export default {
currentIndex: 0 // 当前点击题号 currentIndex: 0 // 当前点击题号
} }
}, },
computed: {
className() {
return {}
}
},
methods: { methods: {
TitleClick(index) { handleClick(index) {
this.currentIndex = index this.currentIndex = index
this.$emit('indexClick', `${index + 1}`) this.$emit('indexClick', `${index + 1}`)
} }
...@@ -40,12 +42,15 @@ export default { ...@@ -40,12 +42,15 @@ export default {
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.titleIndex { .fixed {
position: sticky;
top: 0;
}
.question-num {
ul { ul {
display: flex; display: flex;
justify-content: space-around; flex-wrap: wrap;
align-items: center;
li { li {
border-radius: 50px; border-radius: 50px;
width: 24px; width: 24px;
...@@ -56,10 +61,15 @@ export default { ...@@ -56,10 +61,15 @@ export default {
border: 2px solid #ccc; border: 2px solid #ccc;
color: #666; color: #666;
cursor: pointer; cursor: pointer;
margin: 10px 5px;
} }
.dotItem { .dotItem {
background-color: rgb(243, 190, 190); background-color: rgb(243, 190, 190);
} }
} }
} }
.question-num-ft {
margin-top: 20px;
text-align: center;
}
</style> </style>
<template> <template>
<el-dialog title="添加试卷试题" v-bind="$attrs" v-on="$listeners"></el-dialog> <app-list v-bind="tableOptions" ref="list" style="padding-left: 30px"> </app-list>
</template> </template>
<script> <script>
......
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
<app-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange"> <app-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange">
<div class="btn_operate"> <div class="btn_operate">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新建试卷</el-button> <el-button type="primary" icon="el-icon-plus" @click="handleCreate">新建试卷</el-button>
<el-button type="primary" icon="el-icon-delete" @click="batchDelete">批量删除</el-button> <el-button type="primary" icon="el-icon-delete" :disabled="!multipleSelection.length" @click="handleBatchDelete"
>批量删除</el-button
>
</div> </div>
<template v-slot:filter-category="{ params }"> <template v-slot:filter-category="{ params }">
<question-type-cascader v-model="params.paper_category"></question-type-cascader> <question-type-cascader v-model="params.paper_category"></question-type-cascader>
...@@ -18,7 +20,7 @@ ...@@ -18,7 +20,7 @@
</template> </template>
<script> <script>
import { getPaperList } from '../api' import { getPaperList, batchDeletePaper } from '../api'
import QuestionTypeCascader from '@/components/base/QuestionTypeCascader.vue' import QuestionTypeCascader from '@/components/base/QuestionTypeCascader.vue'
const paperType = [ const paperType = [
...@@ -30,9 +32,7 @@ export default { ...@@ -30,9 +32,7 @@ export default {
components: { QuestionTypeCascader }, components: { QuestionTypeCascader },
data() { data() {
return { return {
visible: false, multipleSelection: [] // 选择项
multipleSelection: [], // 选择项
paperCategoryList: []
} }
}, },
computed: { computed: {
...@@ -85,8 +85,15 @@ export default { ...@@ -85,8 +85,15 @@ export default {
columns: [ columns: [
{ type: 'selection', width: '50px', fixed: 'left' }, { type: 'selection', width: '50px', fixed: 'left' },
{ type: 'index', label: '序号', minWidth: '50px', fixed: 'left' }, { type: 'index', label: '序号', minWidth: '50px', fixed: 'left' },
{ label: '组卷模式', prop: 'paper_type' }, {
{ label: '试卷分类', prop: 'paper_category' }, label: '组卷模式',
prop: 'paper_type',
computed: ({ row }) => {
const map = { 1: '选题组卷', 2: '自动组卷' }
return map[row.paper_type] || row.paper_type
}
},
{ label: '试卷分类', prop: 'paper_category.category_name' },
{ label: '试卷名称', prop: 'paper_title' }, { label: '试卷名称', prop: 'paper_title' },
{ label: '总分', prop: 'paper_total_score' }, { label: '总分', prop: 'paper_total_score' },
{ label: '及格分数', prop: 'pass_score' }, { label: '及格分数', prop: 'pass_score' },
...@@ -113,13 +120,34 @@ export default { ...@@ -113,13 +120,34 @@ export default {
handleSelectionChange(val) { handleSelectionChange(val) {
this.multipleSelection = val this.multipleSelection = val
}, },
// 批量删除
batchDelete() {
console.log('111')
},
// 单个删除 // 单个删除
handleDelete(row) { handleDelete(row) {
// this.$refs.list.refetch() this.$confirm('确定删除该试卷吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const ids = [row.id]
this.batchDeletePaper(ids)
})
},
// 批量删除
handleBatchDelete() {
this.$confirm('确定删除所选试卷吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const ids = this.multipleSelection.map(item => item.id)
this.batchDeletePaper(ids)
})
},
// 批量删除
batchDeletePaper(ids) {
batchDeletePaper({ ids }).then(res => {
// 刷新列表
this.$refs.list.refetch()
})
} }
} }
} }
......
...@@ -131,7 +131,6 @@ ...@@ -131,7 +131,6 @@
<el-button type="primary" @click="handleSubmitSelect" v-if="hasSelectQuestionButton">保存并选择试题</el-button> <el-button type="primary" @click="handleSubmitSelect" v-if="hasSelectQuestionButton">保存并选择试题</el-button>
</div> </div>
</el-form> </el-form>
<question-select :visible.sync="questionSelectVisible"></question-select>
</app-card> </app-card>
</template> </template>
...@@ -141,7 +140,7 @@ import QuestionTypeCascader from '@/components/base/QuestionTypeCascader.vue' ...@@ -141,7 +140,7 @@ import QuestionTypeCascader from '@/components/base/QuestionTypeCascader.vue'
export default { export default {
props: { id: { type: String } }, props: { id: { type: String } },
components: { QuestionTypeCascader, QuestionSelect: () => import('../components/QuestionSelect.vue') }, components: { QuestionTypeCascader },
data() { data() {
return { return {
form: { form: {
......
...@@ -38,103 +38,20 @@ export function addQuestion(data) { ...@@ -38,103 +38,20 @@ export function addQuestion(data) {
} }
/** /**
* 获取应用详情 * 删除试题
*/ */
export function getApp(id, params) { export function deleteQuestion(data) {
return httpRequest.get(`/api/permissions/admin/v1/${id}/application`, { params }) return httpRequest.post('/api/qbs/admin/v1/question/batch-delete', data)
} }
/** /**
* 创建应用 * 更新试题
*/ */
export function createApp(data) { export function updateQuestion(id, data) {
return httpRequest.post('/api/permissions/admin/v1/application', data) return httpRequest.put(`/api/qbs/admin/v1/question/${id}`, data)
} }
/** /**
* 更新应用 * 试题详情
*/
export function updateApp(id, data) {
return httpRequest.put(`/api/permissions/admin/v1/${id}/application`, data)
}
/**
* 删除应用
*/
export function deleteApp(id, data) {
return httpRequest.delete(`/api/permissions/admin/v1/${id}/application`, data)
}
/**
* 更新应用签名秘钥
*/
export function updateAppSecretKey(id, data) {
return httpRequest.patch(`/api/permissions/admin/v1/${id}/application/secret-key`, data)
}
/**
* 获取应用管理员
*/
export function getAppAdminUsers(params) {
return httpRequest.get(`/api/permissions/admin/v1/${params.app_id}/application/assign/app-users`, { params })
}
/**
* 删除应用管理员
*/
export function deleteAppAdminUsers(appid, data) {
return httpRequest.post(`/api/permissions/admin/v1/${appid}/application/assign/remove-app-users`, data)
}
/**
* 创建成员
*/
export function createUser(appid, data) {
return httpRequest.post(`/api/permissions/admin/v1/${appid}/application/user`, data)
}
/**
* 创建应用管理员
*/
export function createAppAdminUsers(appid, data) {
return httpRequest.post(`/api/permissions/admin/v1/${appid}/application/assign/users-to-app`, data)
}
/**
* 获取事件列表
*/
export function getEventList(params) {
return httpRequest.get(`/api/permissions/admin/v1/${params.app_id}/events`, { params })
}
/**
* 创建事件
*/
export function createEvent(appid, data) {
return httpRequest.post(`/api/permissions/admin/v1/${appid}/event/create`, data)
}
/**
* 更新事件
*/
export function updateEvent(id, data) {
return httpRequest.put(`/api/permissions/admin/v1/event/${id}/update`, data)
}
/**
* 删除事件
*/
export function deleteEvents(data) {
return httpRequest.post('/api/permissions/admin/v1/event/batch-delete', data)
}
/**
* 获取事件详情
*/
export function getEvent(params) {
return httpRequest.get(`/api/permissions/admin/v1/event/${params.id}/detail`, { params })
}
/**
* 刷新事件token
*/
export function refreshEventToken(params) {
return httpRequest.patch(`/api/permissions/admin/v1/event/${params.id}/refresh-token`, { params })
}
/**
* 获取获取事件回调记录列表
*/ */
export function getEventRecordList(params) { export function questionDetail(id) {
return httpRequest.get(`/api/permissions/admin/v1/${params.app_id}/event/records`, { params }) return httpRequest.get(`/api/qbs/admin/v1/question/${id}`)
} }
...@@ -9,12 +9,19 @@ ...@@ -9,12 +9,19 @@
<template v-if="source == 1"> <template v-if="source == 1">
<div class="radio-box"> <div class="radio-box">
<div class="tips-tit index">请选择题库:</div> <div class="tips-tit index">请选择题库:</div>
<el-radio v-model="questionBank" label="1">我的题库</el-radio> <el-radio @change="radioChange" v-model="questionBank" label="1">我的题库</el-radio>
<el-radio v-model="questionBank" label="2" style="text-indent: 1.5em">公共题库</el-radio> <el-radio @change="radioChange" v-model="questionBank" label="2" style="text-indent: 1.5em">公共题库</el-radio>
</div> </div>
<app-list v-bind="tableOptions" ref="list" class="app-list"></app-list> <app-list v-bind="tableOptions" ref="list" class="app-list" @selection-change="handleSelectionChange">
<template v-slot:input-filter>
<div class="filter-input">
<el-input v-model="filterInput" placeholder="请选择"></el-input>
<div class="pop" @click="dialogVisible = true"></div>
</div>
</template>
</app-list>
<div class="btn-box"> <div class="btn-box">
<el-button type="primary">&nbsp;&nbsp;&nbsp;&nbsp;确定&nbsp;&nbsp;&nbsp;&nbsp;</el-button> <el-button type="primary" @click="$emit('haveQuestion', checkedList)">&nbsp;&nbsp;&nbsp;&nbsp;确定&nbsp;&nbsp;&nbsp;&nbsp;</el-button>
</div> </div>
</template> </template>
<template v-else> <template v-else>
...@@ -22,72 +29,236 @@ ...@@ -22,72 +29,236 @@
<div class="tips-tit">请选择子题目类型:</div> <div class="tips-tit">请选择子题目类型:</div>
<el-radio v-model="type" label="1">单选题</el-radio> <el-radio v-model="type" label="1">单选题</el-radio>
<el-radio v-model="type" label="2">多选题</el-radio> <el-radio v-model="type" label="2">多选题</el-radio>
<el-radio v-model="type" label="3">判断题</el-radio> <el-radio v-model="type" label="6">判断题</el-radio>
<el-radio v-model="type" label="4">问答题</el-radio> <el-radio v-model="type" label="3">简答题</el-radio>
</div>
<div class="btn-box" style="padding-top:50px;">
<el-button type="primary" @click="addQuestionConfirm">&nbsp;&nbsp;&nbsp;&nbsp;确定&nbsp;&nbsp;&nbsp;&nbsp;</el-button>
</div> </div>
</template> </template>
<el-dialog title="提示" :visible="dialogVisible" width="30%" :before-close="handleClose">
<el-tree
:data="treeList"
:props="defaultProps"
@node-click="handleNodeClick"
:expand-on-click-node="false"
></el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="dialogConfirm">确 定</el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getAppList } from '../api' import { getAppList, getQuestionCategory } from '../api'
export default { export default {
data() { data() {
return { return {
dialogVisible: false,
filterInput: '',
source: '1', source: '1',
questionBank: '1', questionBank: '1',
type: '1' type: '1',
visible: false,
treeList: [],
defaultProps: '',
treeValue: {
name: '',
id: ''
},
checkedList: []
} }
}, },
computed: { computed: {
tableOptions() { tableOptions() {
return { return {
limit: 10,
filters: [ filters: [
{ {
type: 'select', type: 'select',
label: '题目类型:' label: '题目类型:',
prop: 'question_type',
options: [
{ label: '单选题', value: 1 },
{ label: '多选题', value: 2 },
{ label: '问答题', value: 3 },
{ label: '案例题', value: 5 },
{ label: '判断题', value: 6 },
{ label: '实操题', value: 7 },
{ label: '情景题', value: 8 }
]
}, },
{ {
type: 'select', prop: 'question_title',
label: '等级难度:' type: 'input',
label: '题目标题:'
}, },
{ {
type: 'select', prop: 'question_content',
label: '试题分类:' type: 'input',
label: '题干内容:'
}, },
{ {
type: 'input', prop: 'question_difficulty',
label: '题目标题:' type: 'select',
label: '难度等级:',
options: [
{ label: '易', value: '1' },
{ label: '中', value: '2' },
{ label: '难', value: '3' }
]
}, },
{ {
slots: 'input-filter',
prop: 'question_category',
type: 'input', type: 'input',
label: '题干内容:' label: '试题分类:'
}, },
{ {
type: 'input', type: 'input',
label: '知识点:' prop: 'question_tag',
label: '知识点/标签:'
} }
], ],
remote: { httpRequest: getAppList }, remote: {
httpRequest: getAppList,
params: {
permission: this.questionBank,
project_prefix: 'x1',
question_category: this.treeValue.id
},
callback(data) {
const questionType = {
1: '单选题',
2: '多选题',
3: '问答题',
6: '判断题'
}
const questionDifficulty = {
1: '易',
2: '中',
3: '难'
}
return data.data.reduce((a, b) => {
const type = b.question_type
b.question_type = questionType[b.question_type]
b.question_difficulty = questionDifficulty[b.question_difficulty]
if (type !== 5 && type !== 7 && type !== 8) a.push(b)
return a
}, [])
}
},
columns: [ columns: [
{ type: 'selection', minWidth: '50px', fixed: 'left' }, { type: 'selection', minWidth: '50px', fixed: 'left' },
{ label: '序号', prop: 'order' }, { label: '序号', prop: 'question_order' },
{ label: '题目类型', prop: 'type' }, { label: '题目类型', prop: 'question_type' },
{ label: '试题分类', prop: 'sort' }, { label: '试题分类', prop: 'question_category.category_name' },
{ label: '题目目标', prop: 'title' }, { label: '题目标题', prop: 'question_title' },
{ label: '知识点', prop: 'points' }, { label: '知识点', prop: 'knowledge_point.title' },
{ label: '等级难度', prop: 'grade' }, { label: '等级难度', prop: 'question_difficulty' },
{ label: '更新人', prop: 'update_people' } { label: '更新人', prop: 'operator.nickname' },
{ label: '更新时间', prop: 'updated_at' },
{ label: '操作', slots: 'table-x', align: 'right' }
] ]
} }
} }
}, },
mounted() {
this.getTreeList()
},
methods: { methods: {
handleSelectionChange(data) {
this.checkedList = data.reduce((a, b) => {
const data = {}
console.log(typeof b.child_question_type)
data.question_title = b.question_title
data.child_question_type = b.child_question_type || '1'
data.question_content = b.question_content
data.question_analysis = b.question_analysis
if (this.type !== '3') data.question_options = b.question_options
a.push(data)
return a
}, [])
},
radioChange() {
this.$refs.list.refetch()
},
addQuestionConfirm() {
const data = {
question_title: '',
child_question_type: this.type,
question_content: '',
question_analysis: ''
}
let options = []
if (this.type !== '3') {
if (this.type === '1' || this.type === '2') {
options = [
{ option: '', checked: true },
{ option: '', checked: false },
{ option: '', checked: false }
]
} else {
options = [
{ option: '正确', checked: true },
{ option: '错误', checked: false }
]
}
data.question_options = options
}
this.$emit('questionList', data)
},
handleNodeClick(data) {
this.treeValue.name = data.label
this.treeValue.id = data.id
},
handleClose() {
this.treeValue.name = ''
this.treeValue.id = ''
this.dialogVisible = false
},
dialogConfirm() {
this.dialogVisible = false
this.filterInput = this.treeValue.name
this.$refs.list.refetch()
},
// 获取tree列表
getTreeList() {
getQuestionCategory('x1').then(res => {
if (Array.isArray(res.data)) {
this.initTree(res.data)
}
})
},
// 过滤数据 变成tree组件需要的数据
initTree(data) {
this.treeList = data.reduce((a, b) => {
b.label = b.category_name
if (b.children.length) {
setData(b.children)
}
a.push(b)
return a
}, [])
function setData(item) {
return item.map(element => {
if (element.children.length) {
setData(element.children)
element.label = element.category_name
} else {
element.label = element.category_name
}
return element
})
}
}
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.add-chidren { .add-chidren {
padding: 0 20px; padding: 0 20px;
.radio-tips { .radio-tips {
...@@ -113,6 +284,10 @@ export default { ...@@ -113,6 +284,10 @@ export default {
.btn-box { .btn-box {
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-bottom: 30px;
} }
} }
.v-modal{
z-index: 10 !important;
}
</style> </style>
<template> <template>
<div> <div>
<!-- <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> -->
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="题库范围" prop="permission"> <el-form-item label="题库范围" prop="permission">
<el-radio v-model="ruleForm.permission" label="1">我的题库</el-radio> <el-radio v-model="ruleForm.permission" label="1">我的题库</el-radio>
<el-radio v-model="ruleForm.permission" label="2">公共题库</el-radio> <el-radio v-model="ruleForm.permission" label="2">公共题库</el-radio>
</el-form-item> </el-form-item>
<el-form-item label="题目类型" prop="question_type"> <el-form-item label="题目类型" prop="question_type">
<!-- <el-input v-model="ruleForm.name"></el-input> --> <el-select @change="questionTypeChange" v-model="ruleForm.question_type" placeholder="请选择活题目类型">
<el-select v-model="ruleForm.question_type" placeholder="请选择活题目类型" @change="changeQuestionType">
<el-option v-for="(item, index) in qType" :label="item.label" :value="item.value" :key="index"></el-option> <el-option v-for="(item, index) in qType" :label="item.label" :value="item.value" :key="index"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
...@@ -26,13 +26,13 @@ ...@@ -26,13 +26,13 @@
</el-form-item> </el-form-item>
<el-form-item label="选项" prop="question_options" v-if="ruleForm.question_type != 3"> <el-form-item label="选项" prop="question_options" v-if="ruleForm.question_type != 3">
<!-- 单选题 --> <!-- 单选题 -->
<radio ref="options" v-if="ruleForm.question_type == 1"></radio> <radio ref="options" :option="ruleForm.question_options" v-if="ruleForm.question_type == 1"></radio>
<!-- 多选题 --> <!-- 多选题 -->
<checkbox ref="options" v-if="ruleForm.question_type == 2"></checkbox> <checkbox ref="options" :option="ruleForm.question_options" v-if="ruleForm.question_type == 2"></checkbox>
<!-- 判断题 --> <!-- 判断题 -->
<judgment ref="options" v-if="ruleForm.question_type == 6"></judgment> <judgment ref="options" :option="ruleForm.question_options" v-if="ruleForm.question_type == 6"></judgment>
</el-form-item> </el-form-item>
<el-form-item label="标签" prop="type"> <el-form-item label="标签" prop="question_tag">
<el-input v-model="ruleForm.question_tag"></el-input> <el-input v-model="ruleForm.question_tag"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="题目解析" prop="question_analysis"> <el-form-item label="题目解析" prop="question_analysis">
...@@ -53,27 +53,28 @@ ...@@ -53,27 +53,28 @@
remote remote
reserve-keyword reserve-keyword
placeholder="请输入关键词" placeholder="请输入关键词"
:remote-method="remoteMethod"> :remote-method="remoteMethod"
<el-option >
v-for="item in pointOptions" <el-option v-for="item in pointOptions" :key="item.id" :label="item.title" :value="item.id"> </el-option>
:key="item.id"
:label="item.title"
:value="item.id">
</el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> <template v-if="$route.query.id">
<el-button v-if="$route.query.type == 'edit'" type="primary" @click="submitForm('ruleForm')">确认修改</el-button>
</template>
<template v-else>
<el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
</template>
<!-- <el-button @click="resetForm('ruleForm')">重置</el-button> --> <!-- <el-button @click="resetForm('ruleForm')">重置</el-button> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-dialog <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
title="提示" <el-tree
:visible.sync="dialogVisible" :data="treeList"
width="30%" :props="defaultProps"
:before-close="handleClose" @node-click="handleNodeClick"
> :expand-on-click-node="false"
<el-tree :data="treeList" :props="defaultProps" @node-click="handleNodeClick" :expand-on-click-node="false"></el-tree> ></el-tree>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button> <el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="dialogConfirm">确 定</el-button> <el-button type="primary" @click="dialogConfirm">确 定</el-button>
...@@ -86,12 +87,17 @@ import VEditor from '@/components/tinymce/Index.vue' ...@@ -86,12 +87,17 @@ import VEditor from '@/components/tinymce/Index.vue'
import Radio from '../components/QTypeRadio.vue' import Radio from '../components/QTypeRadio.vue'
import Checkbox from '../components/QTypeCheckbox.vue' import Checkbox from '../components/QTypeCheckbox.vue'
import Judgment from '../components/QTypeJudgment.vue' import Judgment from '../components/QTypeJudgment.vue'
import { getQuestionCategory, searchTag, addQuestion } from '../api' import { getQuestionCategory, searchTag, addQuestion, updateQuestion } from '../api'
export default { export default {
components: { VEditor, Radio, Checkbox, Judgment }, components: { VEditor, Radio, Checkbox, Judgment },
props: {
detailData: {
type: Object
}
},
data() { data() {
return { return {
pointOptions: '', pointOptions: [],
treeList: [], treeList: [],
defaultProps: '', defaultProps: '',
treeValue: { treeValue: {
...@@ -106,7 +112,7 @@ export default { ...@@ -106,7 +112,7 @@ export default {
question_difficulty: '', question_difficulty: '',
question_title: '', question_title: '',
question_content: '', question_content: '',
// question_options: [], question_options: [],
question_analysis: '', question_analysis: '',
question_category: '', question_category: '',
knowledge_point: '', knowledge_point: '',
...@@ -115,7 +121,7 @@ export default { ...@@ -115,7 +121,7 @@ export default {
qType: [ qType: [
{ label: '单选题', value: 1 }, { label: '单选题', value: 1 },
{ label: '多选题', value: 2 }, { label: '多选题', value: 2 },
{ label: '答题', value: 3 }, { label: '答题', value: 3 },
{ label: '案例题', value: 5 }, { label: '案例题', value: 5 },
{ label: '判断题', value: 6 }, { label: '判断题', value: 6 },
{ label: '实操题', value: 7 }, { label: '实操题', value: 7 },
...@@ -134,24 +140,34 @@ export default { ...@@ -134,24 +140,34 @@ export default {
} }
}, },
mounted() { mounted() {
if (this.detailData) {
this.ruleForm = this.detailData
}
this.getTreeList() this.getTreeList()
}, },
methods: { methods: {
submitForm(formName) { submitForm(formName) {
if (parseInt(this.ruleForm.question_type) !== 3) { if (parseInt(this.ruleForm.question_type) !== 3) {
console.log(this.$refs.options.datas, '123')
const isValue = this.$refs.options.datas.find(item => item.option === '') const isValue = this.$refs.options.datas.find(item => item.option === '')
if (!isValue) this.ruleForm.question_options = this.$refs.options.datas if (!isValue) this.ruleForm.question_options = this.$refs.options.datas
} }
this.$refs[formName].validate(valid => { this.$refs[formName].validate(valid => {
if (valid) { if (valid) {
// alert('submit!') // console.log(JSON.stringify(this.ruleForm))
addQuestion(this.ruleForm).then(res => { if (this.$router.query.id) {
if (res.code === 0) { updateQuestion(this.ruleForm).then(res => {
this.$router.push({
path: '/question/list'
})
})
} else {
addQuestion(this.ruleForm).then(res => {
this.$router.push({ this.$router.push({
path: '/question/list' path: '/question/list'
}) })
} })
}) }
} else { } else {
console.log('error submit!!') console.log('error submit!!')
return false return false
...@@ -161,9 +177,6 @@ export default { ...@@ -161,9 +177,6 @@ export default {
resetForm(formName) { resetForm(formName) {
this.$refs[formName].resetFields() this.$refs[formName].resetFields()
}, },
changeQuestionType() {
console.log(this.ruleForm.question_type)
},
// 点击选中tree // 点击选中tree
handleNodeClick(data) { handleNodeClick(data) {
this.treeValue.name = data.label this.treeValue.name = data.label
...@@ -213,8 +226,10 @@ export default { ...@@ -213,8 +226,10 @@ export default {
console.log(query) console.log(query)
searchTag({ title: query }).then(res => { searchTag({ title: query }).then(res => {
this.pointOptions = res.data.data this.pointOptions = res.data.data
console.log(res, 'query')
}) })
},
questionTypeChange() {
this.$emit('questionType', this.ruleForm.question_type)
} }
} }
} }
......
<template> <template>
<div class="radio-box"> <div class="radio-box">
<template v-for="(item, index) in datas"> <template v-for="(item, index) in option || datas">
<div class="opt" :key="index"> <div class="opt" :key="index">
<el-checkbox v-model="checkboxValue" :label="index" @change="checkboxChange"> <el-checkbox v-model="checkboxValue" :label="index" @change="checkboxChange">
<el-tag>{{ A_Z()[index] }}</el-tag> <el-tag>{{ A_Z()[index] }}</el-tag>
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
<script> <script>
export default { export default {
props: {
option: {
type: Array
}
},
data() { data() {
return { return {
checkboxValue: [0], checkboxValue: [0],
...@@ -38,6 +43,9 @@ export default { ...@@ -38,6 +43,9 @@ export default {
] ]
} }
}, },
mounted() {
if (this.option) this.datas = this.option
},
methods: { methods: {
add() { add() {
this.datas.push({ option: '', checked: false }) this.datas.push({ option: '', checked: false })
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
<script> <script>
export default { export default {
props: {
option: {
type: Array
}
},
data() { data() {
return { return {
radio: '0', radio: '0',
...@@ -22,6 +27,9 @@ export default { ...@@ -22,6 +27,9 @@ export default {
] ]
} }
}, },
mounted() {
if (this.option) this.datas = this.option
},
methods: { methods: {
radioChange() { radioChange() {
this.datas.map(item => { this.datas.map(item => {
...@@ -29,7 +37,6 @@ export default { ...@@ -29,7 +37,6 @@ export default {
this.datas[this.radio].checked = true this.datas[this.radio].checked = true
return item return item
}) })
console.log(this.datas, 'datas')
} }
} }
} }
......
<template> <template>
<div class="radio-box"> <div class="radio-box">
<template v-for="(item, index) in datas"> <template v-for="(item, index) in option || datas">
<div class="opt" :key="index"> <div class="opt" :key="index">
<el-radio v-model="radioValue" :label="index" @change="radioChange"> <el-radio v-model="radioValue" :label="index" @change="radioChange">
<el-tag>{{ A_Z()[index] }}</el-tag> <el-tag>{{ A_Z()[index] }}</el-tag>
...@@ -10,12 +10,16 @@ ...@@ -10,12 +10,16 @@
<i class="el-icon-circle-plus-outline icon-style" v-else @click="add"></i> <i class="el-icon-circle-plus-outline icon-style" v-else @click="add"></i>
</div> </div>
</template> </template>
<!-- <el-radio v-model="radio" label="1"></el-radio> -->
</div> </div>
</template> </template>
<script> <script>
export default { export default {
props: {
option: {
type: Array
}
},
data() { data() {
return { return {
radioValue: 0, radioValue: 0,
...@@ -36,6 +40,9 @@ export default { ...@@ -36,6 +40,9 @@ export default {
ruleForm: '' ruleForm: ''
} }
}, },
mounted() {
if (this.option) this.datas = this.option
},
methods: { methods: {
add() { add() {
this.datas.push({ option: '', checked: false }) this.datas.push({ option: '', checked: false })
......
<template> <template>
<div> <div>
<el-divider content-position="center" class="divider">子题目1</el-divider> <el-form :model="data" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <div v-for="(ruleForm, index) in dataList" :key="index">
<el-form-item label="子题目类型" prop="desc"> <el-divider content-position="center" class="divider">子题目{{ index + 1 }}</el-divider>
<el-select v-model="ruleForm.desc" disabled placeholder="请选择活动区域"> <el-form-item style="text-align: right;">
<el-option label="单选题" value="questionType1"></el-option> <el-button type="primary" @click="$emit('addChidren')">添加子题目</el-button>
<el-option label="多选题" value="questionType2"></el-option> <el-button type="primary" @click="removeChidren(index)">删除子题目</el-button>
<el-option label="判断题" value="questionType3"></el-option> </el-form-item>
<el-option label="问答题" value="questionType4"></el-option> <el-form-item label="子题目类型" prop="child_question_type">
</el-select> <el-select v-model="ruleForm.child_question_type" disabled placeholder="请选择活动区域">
</el-form-item> <el-option label="单选题" value="1"></el-option>
<el-form-item label="难度等级" prop="desc"> <el-option label="多选题" value="2"></el-option>
<el-select v-model="ruleForm.desc" placeholder="请选择活动区域"> <el-option label="判断题" value="6"></el-option>
<el-option label="单选题" value="questionType1"></el-option> <el-option label="问答题" value="3"></el-option>
<el-option label="多选题" value="questionType2"></el-option> </el-select>
<el-option label="判断题" value="questionType3"></el-option> </el-form-item>
<el-option label="问答题" value="questionType4"></el-option> <el-form-item label="子题目标题" prop="question_title">
</el-select> <el-input v-model="ruleForm.question_title"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="子题目标题" prop="data2"> <el-form-item label="子题目内容" prop="question_content">
<el-input v-model="ruleForm.data2"></el-input> <v-editor v-model="ruleForm.question_content"></v-editor>
</el-form-item> </el-form-item>
<el-form-item label="子题目内容" prop="data2"> <el-form-item label="选项" prop="question_options" v-if="ruleForm.child_question_type != 3">
<v-editor></v-editor> <!-- 单选题 -->
</el-form-item> <radio ref="options" :option="ruleForm.question_options" v-if="ruleForm.child_question_type == 1"></radio>
<el-form-item label="选项"> <!-- 多选题 -->
<radio></radio> <checkbox ref="options" :option="ruleForm.question_options" v-if="ruleForm.child_question_type == 2"></checkbox>
<!-- <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> --> <!-- 判断题 -->
<!-- <el-button @click="resetForm('ruleForm')">重置</el-button> --> <judgment ref="options" :option="ruleForm.question_options" v-if="ruleForm.child_question_type == 6"></judgment>
</el-form-item> </el-form-item>
<el-form-item label="标签"> <el-form-item label="子题目解析" prop="question_analysis">
<el-input v-model="ruleForm.data2"></el-input> <v-editor v-model="ruleForm.question_analysis"></v-editor>
</el-form-item> </el-form-item>
<el-form-item label="子题目解析" prop="data2"> <el-form-item style="text-align: center;" v-if="index + 1 == dataList.length">
<v-editor></v-editor> <el-button type="primary" @click="submitForm">保存</el-button>
</el-form-item> </el-form-item>
<el-form-item label="试题分类" prop="desc"> </div>
<el-select v-model="ruleForm.desc" disabled placeholder="请选择活动区域">
<el-option label="单选题" value="questionType1"></el-option>
<el-option label="多选题" value="questionType2"></el-option>
<el-option label="判断题" value="questionType3"></el-option>
<el-option label="问答题" value="questionType4"></el-option>
</el-select>
</el-form-item>
<el-form-item label="知识点">
<el-input v-model="ruleForm.data2"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">保存子题目</el-button>
<el-button type="primary" @click="resetForm('ruleForm')">删除子题目</el-button>
<!-- <el-input v-model="ruleForm.data2"></el-input> -->
</el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<script> <script>
import Radio from './QTypeRadio.vue' import Radio from './QTypeRadio.vue'
import Checkbox from './QTypeCheckbox.vue'
import Judgment from './QTypeJudgment.vue'
import VEditor from '@/components/tinymce/Index.vue' import VEditor from '@/components/tinymce/Index.vue'
export default { export default {
components: { VEditor, Radio }, components: { VEditor, Radio, Checkbox, Judgment },
props: {
data: {
type: Object
},
chidrenList: {
type: Array
}
},
data() { data() {
return { return {
ruleForm: {} ruleForm: {},
dataList: [],
rules: {
child_question_type: [{ required: true, message: ' ', trigger: 'blur' }],
question_difficulty: [{ required: true, message: ' ', trigger: 'blur' }],
question_title: [{ required: true, message: ' ', trigger: 'blur' }],
question_content: [{ required: true, message: ' ', trigger: 'blur' }],
question_analysis: [{ required: true, message: ' ', trigger: 'blur' }],
question_options: [{ required: true, message: ' ', trigger: 'blur' }]
}
}
},
mounted() {
this.dataList = this.chidrenList
console.log(this.chidrenList)
},
methods: {
removeChidren(n) {
this.dataList.splice(n, 1)
},
submitForm() {
this.$emit('submitForm')
} }
} }
} }
......
<template> <template>
<app-card> <app-card>
<detail></detail> <template v-if="[1, 2, 3, 6].includes(questionTypeNum)">
<template v-if="$route.query.id">
<detail v-if="Object.keys(detailData).length" :detailData="detailData" @questionType="questionType"></detail>
</template>
<detail v-else @questionType="questionType"></detail>
</template>
<template v-else>
<template v-if="$route.query.id">
<situation-question v-if="$route.query.id && Object.keys(detailData).length" :detailData="detailData" :questionTypeNumber="questionTypeNum" @questionType="questionType"></situation-question>
</template>
<situation-question v-else :questionTypeNumber="questionTypeNum" @questionType="questionType"></situation-question>
</template>
</app-card> </app-card>
</template> </template>
<script> <script>
import Detail from '../components/Detail.vue' import Detail from '../components/Detail.vue'
// import VEditor from '@/components/tinymce/Index.vue' import SituationQuestion from '../components/QTypeSituation.vue'
// import Radio from '../components/QTypeRadio.vue' import { questionDetail } from '../api'
// import Checkbox from '../components/QTypeCheckbox.vue'
// import Judgment from '../components/QTypeJudgment.vue'
export default { export default {
components: { Detail } components: { Detail, SituationQuestion },
data() {
return {
questionTypeNum: 1,
detailData: {}
}
},
mounted() {
if (this.$route.query.id) {
questionDetail(this.$route.query.id).then(res => {
this.questionTypeNum = res.data.question_type
res.data.permission = res.data.permission.toString()
res.data.question_difficulty = res.data.question_difficulty.toString()
res.data.question_category = res.data.question_category.category_name
this.detailData = res.data
console.log(this.detailData)
})
}
},
methods: {
questionType(n) {
this.questionTypeNum = n
}
}
} }
</script> </script>
......
<template> <template>
<app-card> <app-card>
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange">
<template v-slot:radio-filter> <template v-slot:radio-filter>
<el-radio v-model="radio" label="1">我的题库</el-radio> <el-radio @change="radioChange" v-model="radio" label="1">我的题库</el-radio>
<el-radio v-model="radio" label="2">公共题库</el-radio> <el-radio @change="radioChange" v-model="radio" label="2">公共题库</el-radio>
</template> </template>
<template v-slot:input-filter> <template v-slot:input-filter>
<div class="filter-input"> <div class="filter-input">
...@@ -16,20 +16,20 @@ ...@@ -16,20 +16,20 @@
>新建试题</el-button >新建试题</el-button
> >
<el-button type="primary" icon="el-icon-plus" @click="visible = true">批量导入试题</el-button> <el-button type="primary" icon="el-icon-plus" @click="visible = true">批量导入试题</el-button>
<el-button type="primary" icon="el-icon-plus" @click="visible = true">批量删除</el-button> <el-button type="primary" icon="el-icon-plus" @click="deleteQuestion()">批量删除</el-button>
</div> </div>
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<el-button type="text" @click="handleView(row)">编辑</el-button> <el-button type="text" @click="handleSettings(row)">编辑</el-button>
<el-button type="text" @click="handleSettings(row)">查看详情</el-button> <el-button type="text" @click="handleView(row)">查看详情</el-button>
<el-button type="text" @click="handleSettings(row)">删除</el-button> <el-button type="text" @click="handleDelete(row.id)">删除</el-button>
</template> </template>
<el-dialog <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
title="提示" <el-tree
:visible.sync="dialogVisible" :data="treeList"
width="30%" :props="defaultProps"
:before-close="handleClose" @node-click="handleNodeClick"
> :expand-on-click-node="false"
<el-tree :data="treeList" :props="defaultProps" @node-click="handleNodeClick" :expand-on-click-node="false"></el-tree> ></el-tree>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取 消</el-button> <el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="dialogConfirm">确 定</el-button> <el-button type="primary" @click="dialogConfirm">确 定</el-button>
...@@ -40,11 +40,12 @@ ...@@ -40,11 +40,12 @@
</template> </template>
<script> <script>
import { getAppList, getQuestionCategory } from '../api' import { getAppList, getQuestionCategory, deleteQuestion } from '../api'
export default { export default {
data() { data() {
return { return {
deleteQuestions: [],
dialogVisible: false, dialogVisible: false,
visible: false, visible: false,
radio: '1', radio: '1',
...@@ -60,6 +61,7 @@ export default { ...@@ -60,6 +61,7 @@ export default {
computed: { computed: {
tableOptions() { tableOptions() {
return { return {
limit: 10,
filters: [ filters: [
{ {
slots: 'radio-filter', slots: 'radio-filter',
...@@ -73,7 +75,7 @@ export default { ...@@ -73,7 +75,7 @@ export default {
options: [ options: [
{ label: '单选题', value: 1 }, { label: '单选题', value: 1 },
{ label: '多选题', value: 2 }, { label: '多选题', value: 2 },
{ label: '答题', value: 3 }, { label: '答题', value: 3 },
{ label: '案例题', value: 5 }, { label: '案例题', value: 5 },
{ label: '判断题', value: 6 }, { label: '判断题', value: 6 },
{ label: '实操题', value: 7 }, { label: '实操题', value: 7 },
...@@ -123,7 +125,7 @@ export default { ...@@ -123,7 +125,7 @@ export default {
const questionType = { const questionType = {
1: '单选题', 1: '单选题',
2: '多选题', 2: '多选题',
3: '答题', 3: '答题',
5: '案例题', 5: '案例题',
6: '判断题', 6: '判断题',
7: '实操题', 7: '实操题',
...@@ -161,6 +163,22 @@ export default { ...@@ -161,6 +163,22 @@ export default {
this.getTreeList() this.getTreeList()
}, },
methods: { methods: {
// 列表选择
handleSelectionChange(data) {
this.deleteQuestions = data.reduce((a, b) => a.push(b.id) && a, [])
},
// 删除试题
handleDelete(id) {
console.log(id)
const ids = id ? [id] : this.deleteQuestions
deleteQuestion({ ids: ids }).then(res => {
this.$message({
message: '删除成功',
type: 'success'
})
this.$refs.list.refetch()
})
},
// 获取tree列表 // 获取tree列表
getTreeList() { getTreeList() {
getQuestionCategory('x1').then(res => { getQuestionCategory('x1').then(res => {
...@@ -201,7 +219,7 @@ export default { ...@@ -201,7 +219,7 @@ export default {
}, },
handleSettings(row) { handleSettings(row) {
// tan ~~~~~ // tan ~~~~~
this.$router.push({ path: '/settings/users', query: { appid: row.id } }) this.$router.push({ path: '/question/create', query: { id: row.id, type: 'edit' } })
}, },
handleNodeClick(data) { handleNodeClick(data) {
this.treeValue.name = data.label this.treeValue.name = data.label
...@@ -216,13 +234,9 @@ export default { ...@@ -216,13 +234,9 @@ export default {
this.dialogVisible = false this.dialogVisible = false
this.filterInput = this.treeValue.name this.filterInput = this.treeValue.name
this.$refs.list.refetch() this.$refs.list.refetch()
} },
}, radioChange() {
watch: { this.$refs.list.refetch()
radio: {
handler() {
this.$refs.list.refetch()
}
} }
} }
} }
......
...@@ -49,7 +49,6 @@ httpRequest.interceptors.request.use( ...@@ -49,7 +49,6 @@ httpRequest.interceptors.request.use(
httpRequest.interceptors.response.use( httpRequest.interceptors.response.use(
function (response) { function (response) {
const { data } = response const { data } = response
console.log(response)
// 正常返回 // 正常返回
if (data.code === 0 || data.type === 'application/vnd.ms-excel') { if (data.code === 0 || data.type === 'application/vnd.ms-excel') {
return data return data
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论