添加题库管理流程
This commit is contained in:
parent
b413c2f0f2
commit
d161492fed
@ -38,6 +38,7 @@
|
||||
"three": "^0.107.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-i18n": "^8.12.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "^3.1.6",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuex": "^3.1.0",
|
||||
|
10
src/api/questionBank.js
Normal file
10
src/api/questionBank.js
Normal file
@ -0,0 +1,10 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/** 推送通知消息*/
|
||||
export function listQuestionPage(data) {
|
||||
return request({
|
||||
// url: `/api/pushMessage`,
|
||||
// method: 'post',
|
||||
// data: data
|
||||
});
|
||||
}
|
116
src/components/QuillEditor/index.vue
Normal file
116
src/components/QuillEditor/index.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<quill-editor
|
||||
ref="editor"
|
||||
v-model="content"
|
||||
:options="options"
|
||||
:style="{height: height+'px', 'margin-bottom': '80px'}"
|
||||
@change="onChange"
|
||||
@blur="onBlur"
|
||||
@focus="onFocus"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { quillEditor } from 'vue-quill-editor';
|
||||
import 'quill/dist/quill.snow.css';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
quillEditor
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
options: {
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[],
|
||||
[],
|
||||
[{'list': 'ordered'}, {'list': 'bullet'}],
|
||||
[{'script': 'sub'}, {'script': 'super'}],
|
||||
[{'indent': '-1'}, {'indent': '+1'}],
|
||||
[{'direction': 'rtl'}],
|
||||
[{'size': ['small', 'large', 'huge']}],
|
||||
[{'color': [], 'background': []}],
|
||||
[{'font': []}],
|
||||
[{'align': []}],
|
||||
['clean']
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
editor() {
|
||||
return this.$refs.editor.quill;
|
||||
},
|
||||
titleConfig () {
|
||||
return {
|
||||
'ql-bold': '加粗',
|
||||
'ql-color': '颜色',
|
||||
'ql-font': '字体',
|
||||
'ql-code': '插入代码',
|
||||
'ql-italic': '斜体',
|
||||
'ql-link': '添加链接',
|
||||
'ql-background': '背景颜色',
|
||||
'ql-size': '字体大小',
|
||||
'ql-strike': '删除线',
|
||||
'ql-script': '上标/下标',
|
||||
'ql-underline': '下划线',
|
||||
'ql-blockquote': '引用',
|
||||
'ql-header': '标题',
|
||||
'ql-indent': '缩进',
|
||||
'ql-list': '列表',
|
||||
'ql-align': '文本对齐',
|
||||
'ql-direction': '文本方向',
|
||||
'ql-code-block': '代码块',
|
||||
'ql-formula': '公式',
|
||||
'ql-image': '图片',
|
||||
'ql-video': '视频',
|
||||
'ql-clean': '清除字体样式'
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'value': function(val) {
|
||||
this.$nextTick(() => {
|
||||
if (val != this.$escapeHTML(this.content)) {
|
||||
this.editor.enable(false);
|
||||
this.content = val;
|
||||
this.editor.enable(true);
|
||||
this.editor.blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.content = this.value;
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.$emit('input', this.$escapeHTML(this.content));
|
||||
},
|
||||
onBlur(e) {
|
||||
},
|
||||
onFocus(e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -82,5 +82,6 @@ export default {
|
||||
homeJsxt: '首页',
|
||||
examDetail: '考试详情',
|
||||
raceManage: '竞赛管理',
|
||||
recaList: '报名列表'
|
||||
recaList: '报名列表',
|
||||
bankManage: '题库列表'
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import 'normalize.css/normalize.css'; // A modern alternative to CSS resets
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import '@/styles/index.scss'; // global css
|
||||
import 'quill/dist/quill.snow.css';
|
||||
|
||||
import LangStorage from '@/utils/lang';
|
||||
import App from './App';
|
||||
|
@ -123,6 +123,9 @@ const DeviceManage = () => import('@/views/system/deviceManage/index');
|
||||
const MapSort = () => import('@/views/publish/publishMap/mapSort');
|
||||
const StudentManage = () => import('@/views/studentManage');
|
||||
const RaceManage = () => import('@/views/competitionManage/index');
|
||||
const BankManage = () => import('@/views/competitionManage/bankList/index');
|
||||
const QuestionCreatePage = () => import('@/views/competitionManage/bankList/question-create-page');
|
||||
const QuestionUpdatePage = () => import('@/views/competitionManage/bankList/question-update-page');
|
||||
|
||||
const CompetitionDetail = () => import('@/views/jsxt/competition/examDetail');
|
||||
const CompetitionManage = () => import('@/views/jsxt/competition/index');
|
||||
@ -914,11 +917,10 @@ export const asyncRouter = [
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/design/race',
|
||||
redirect: '/design/race/manage',
|
||||
path: '/design/race', // 竞赛管理
|
||||
component: Layout,
|
||||
meta: {
|
||||
i18n: 'route.raceManage',
|
||||
i18n: 'router.raceManage',
|
||||
roles: [admin]
|
||||
},
|
||||
children: [
|
||||
@ -929,6 +931,24 @@ export const asyncRouter = [
|
||||
i18n: 'router.raceManage',
|
||||
icon: 'design'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'bank',
|
||||
component: BankManage,
|
||||
meta: {
|
||||
i18n: 'router.bankManage',
|
||||
icon: 'design'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'questionCreate',
|
||||
component: QuestionCreatePage,
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'questionUpdate/:questionId',
|
||||
component: QuestionUpdatePage,
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -147,6 +147,10 @@ export default {
|
||||
{ label: '控制模式', value: 'ControlConvertMenu' },
|
||||
{ label: '车次窗', value: 'TrainWindow' }
|
||||
],
|
||||
QuestionTypeList: [
|
||||
{ label: '选择题', value: 'select' },
|
||||
{ label: '判断题', value: 'judge' }
|
||||
],
|
||||
// 新版的产品类型枚举
|
||||
prdType:[
|
||||
{ enlabel: 'ATS local workstation', label: 'ATS现地工作站', value: '01'},
|
||||
|
@ -2312,5 +2312,9 @@ export const UrlConfig = {
|
||||
draft: '/trainingPlatform/draft',
|
||||
pay: '/trainingPlatform/pay',
|
||||
runPlan: '/trainingPlatform/runPlan/manage'
|
||||
},
|
||||
bank: {
|
||||
questionCreate: '/design/race/questionCreate',
|
||||
questionUpdate: '/design/race/questionUpdate'
|
||||
}
|
||||
};
|
||||
|
@ -5,11 +5,13 @@ import TurnbackBar from '@/components/TurnbackBar';
|
||||
import ConstConfig from '@/scripts/ConstConfig';
|
||||
import Dictionary from '@/scripts/DictionaryData';
|
||||
import Theme from '@/jmapNew/theme/factory';
|
||||
import QuillEditor from '@/components/QuillEditor/index';
|
||||
|
||||
// 全局组件
|
||||
Vue.component('DataForm', DataForm);
|
||||
Vue.component('QueryListPage', QueryListPage);
|
||||
Vue.component('TurnbackBar', TurnbackBar);
|
||||
Vue.component('QuillEditor', QuillEditor);
|
||||
|
||||
Vue.prototype.$ConstSelect = (function() {
|
||||
ConstConfig.ConstSelect.translate = function(value, codeName) {
|
||||
@ -116,7 +118,7 @@ Vue.prototype.$copyClone = function(obj1, obj2 = {}) {
|
||||
};
|
||||
|
||||
Vue.prototype.$escapeHTML = function (context) {
|
||||
const pattern = /<\w*>(.*)<\/\w*>/;
|
||||
const pattern = /<\p>(.*)<\/\p>/;
|
||||
|
||||
if (pattern.test(context)) {
|
||||
context = pattern.exec(context)[1];
|
||||
|
77
src/views/competitionManage/bankList/dialog-detail.vue
Normal file
77
src/views/competitionManage/bankList/dialog-detail.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="860px" :close-on-click-modal="false" :before-close="doClose">
|
||||
<div class="ql-editor" v-html="$escapeHTML(`${form.topic}`)" />
|
||||
<template v-if="checkType(form, 'judge')">
|
||||
<div class="answer">
|
||||
答 案:
|
||||
<template v-for="(el,i) in options">
|
||||
<span v-if="el.correct" :key="i">{{ el.content }} </span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template v-else-if="checkType(form, 'select')">
|
||||
<div v-for="(el,i) in options" :key="i" class="option" :label="$str2number(el.id)">
|
||||
<span>{{ $asc2chart(i+65) }}. </span>
|
||||
<div class="ql-editor" style="display: inline; padding: 0" v-html="$escapeHTML(el.content)" />
|
||||
</div>
|
||||
<div class="answer">
|
||||
答 案:
|
||||
<template v-for="(el,i) in options">
|
||||
<span v-if="el.correct" :key="i">{{ $asc2chart(i+65) }} </span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="show = false">关闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
form: {
|
||||
optionList: []
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return '详 情';
|
||||
},
|
||||
options() {
|
||||
return this.form.optionList;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkType(option, type) {
|
||||
return option.type == type;
|
||||
},
|
||||
appendIndex(str, index) {
|
||||
return `${index+1}. ${str}`;
|
||||
},
|
||||
doShow(node) {
|
||||
this.form = node.row||{};
|
||||
this.show = true;
|
||||
},
|
||||
doClose(done) {
|
||||
this.show = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.option {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.answer {
|
||||
line-height: 32px;
|
||||
padding-left: 0;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
46
src/views/competitionManage/bankList/dialog-modify-rich.vue
Normal file
46
src/views/competitionManage/bankList/dialog-modify-rich.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="40%" :close-on-click-modal="false" :before-close="doClose">
|
||||
<quill-editor v-model="content" placeholder="请输入内容" />
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="doInput">确 定</el-button>
|
||||
<el-button @click="show = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
content: '',
|
||||
node: {
|
||||
model: {},
|
||||
prop: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return '富文本输入';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doShow(node) {
|
||||
this.node = node;
|
||||
this.content = (node.model || {})[node.prop] || '';
|
||||
this.show = true;
|
||||
},
|
||||
doClose(done) {
|
||||
this.show = false;
|
||||
},
|
||||
doInput() {
|
||||
const node = this.node;
|
||||
node.model[node.prop] = this.content;
|
||||
this.$emit('update', node.model);
|
||||
this.doClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="40%" :close-on-click-modal="false" :before-close="doClose">
|
||||
<div class="ql-editor notes" v-html="$escapeHTML(`${formParam.topic}`)" />
|
||||
<item-answer v-model="formParam.answer" :option-list="optionList" :type="formParam.type" @change="onAnswerChnage" />
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="doUpdate">确 定</el-button>
|
||||
<el-button @click="show = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ItemAnswer from './item-answer';
|
||||
import { getOptionsByQuestionId} from '@/api/questionBank.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ItemAnswer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
content: '',
|
||||
optionList: [],
|
||||
formParam: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return '更新答案';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doShow({index, row}) {
|
||||
this.formParam = row;
|
||||
this.content = row.topic;
|
||||
getOptionsByQuestionId(row.id).then(resp => {
|
||||
this.optionList = resp.data;
|
||||
this.optionList.forEach((el, i) => {
|
||||
if (el.correct) {
|
||||
this.formParam.answer = i;
|
||||
}
|
||||
});
|
||||
});
|
||||
this.show = true;
|
||||
},
|
||||
doClose(done) {
|
||||
this.show = false;
|
||||
},
|
||||
onAnswerChnage(answer) {
|
||||
this.optionList.forEach((el, i) => { el.correct = i == answer; });
|
||||
},
|
||||
doUpdate() {
|
||||
const index = this.optionList.findIndex((el, i) => { return i == this.formParam.answer; });
|
||||
if (index >= 0) {
|
||||
const answer = this.optionList[index];
|
||||
this.$emit('updateAnswer', {questionId: answer.questionId, id: answer.id, correct: answer.correct});
|
||||
}
|
||||
this.doClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notes {
|
||||
padding: 0 0 20px 0;
|
||||
color: #6666;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<el-dialog v-dialogDrag :close-on-click-moda="false" :title="title" :visible.sync="show" width="40%" :close-on-click-modal="false" :before-close="doClose">
|
||||
<quill-editor v-model="content" placeholder="请输入内容" />
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="doInput">确 定</el-button>
|
||||
<el-button @click="show = false">取 消</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
content: '',
|
||||
formParam: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return '更新题目';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doShow({index, row}) {
|
||||
this.formParam = row;
|
||||
this.content = row.topic;
|
||||
this.show = true;
|
||||
},
|
||||
doClose(done) {
|
||||
this.show = false;
|
||||
},
|
||||
doInput() {
|
||||
this.formParam.topic = this.content;
|
||||
this.$emit('updateQuestion', this.formParam);
|
||||
this.doClose();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
207
src/views/competitionManage/bankList/index.vue
Normal file
207
src/views/competitionManage/bankList/index.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div>
|
||||
<query-list-page ref="user" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
|
||||
<dialog-update-question ref="question" @updateQuestion="updateQuestion" />
|
||||
<dialog-update-answer ref="answer" @updateAnswer="updateAnswer" />
|
||||
<dialog-detail ref="detail" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { UrlConfig } from '@/scripts/ConstDic';
|
||||
import { listQuestionPage } from '@/api/questionBank.js';
|
||||
import DialogUpdateQuestion from './dialog-update-question';
|
||||
import DialogUpdateAnswer from './dialog-update-answer';
|
||||
import DialogDetail from './dialog-detail';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DialogUpdateQuestion,
|
||||
DialogUpdateAnswer,
|
||||
DialogDetail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pagerConfig: {
|
||||
pageSize: 'pageSize',
|
||||
pageIndex: 'pageNum'
|
||||
},
|
||||
queryForm: {
|
||||
reset: true,
|
||||
labelWidth: '80px',
|
||||
queryObject: {
|
||||
type: {
|
||||
type: 'select',
|
||||
label: '类 型',
|
||||
config: {
|
||||
data: this.$ConstSelect.QuestionTypeList
|
||||
}
|
||||
},
|
||||
topic: {
|
||||
type: 'text',
|
||||
label: '题 目'
|
||||
}
|
||||
}
|
||||
},
|
||||
queryList: {
|
||||
query: listQuestionPage,
|
||||
selectCheckShow: false,
|
||||
indexShow: true,
|
||||
columns: [
|
||||
{
|
||||
title: '类 型',
|
||||
prop: 'type',
|
||||
type: 'tag',
|
||||
width: '120',
|
||||
columnValue: (row) => { return this.$ConstSelect.translate(row.type, 'QuestionTypeList'); },
|
||||
tagType: (row) => {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '题 目',
|
||||
prop: 'topic'
|
||||
},
|
||||
{
|
||||
title: '答 案',
|
||||
prop: 'answer',
|
||||
type: 'tagMore',
|
||||
width: '100',
|
||||
columnValue: (row) => { return this.answerTags(row); },
|
||||
tagType: (row) => {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
prop: 'createUserName',
|
||||
width: '100'
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
title: '操 作',
|
||||
width: '420',
|
||||
buttons: [
|
||||
{
|
||||
name: '更新题目',
|
||||
handleClick: this.doUpdateQuestion,
|
||||
showControl: (row) => { return row.createUserId == this.userId; },
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
name: '更新选项',
|
||||
handleClick: this.doupdateAnswers,
|
||||
showControl: (row) => { return row.createUserId == this.userId && row.type != 'judge'; },
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
name: '更新答案',
|
||||
handleClick: this.doUpdateAnswer,
|
||||
showControl: (row) => { return row.createUserId == this.userId; },
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
name: '删 除',
|
||||
handleClick: this.doDelete,
|
||||
showControl: (row) => { return row.createUserId == this.userId; },
|
||||
type: 'danger'
|
||||
},
|
||||
{
|
||||
name: '详 情',
|
||||
handleClick: this.doDetail,
|
||||
showControl: (row) => { return row.createUserId != this.userId; }
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{ text: '添 加', handler: this.doCreate }
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
userId() {
|
||||
return this.$store.state.user.id;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doCreate() {
|
||||
this.$router.push({path: `${UrlConfig.bank.questionCreate}`});
|
||||
},
|
||||
|
||||
doUpdate(index, row) {
|
||||
this.$router.push({path: `${UrlConfig.bank.questionModify}/${row.id}`});
|
||||
},
|
||||
|
||||
doUpdateQuestion(index, row) {
|
||||
this.$refs.question.doShow({index, row});
|
||||
},
|
||||
|
||||
doupdateAnswers(index, row) {
|
||||
this.$router.push({path: `${UrlConfig.bank.questionUpdate}/${row.id}`});
|
||||
},
|
||||
|
||||
doUpdateAnswer(index, row) {
|
||||
this.$refs.answer.doShow({index, row});
|
||||
},
|
||||
|
||||
doDelete(index, row) {
|
||||
this.$confirm('删除试题,是否继续?', '提 示', {
|
||||
confirmButtonText: '确 定',
|
||||
cancelButtonText: '取 消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
// deleteQuestion(row.id).then(resp => {
|
||||
// this.reloadTable();
|
||||
// }).catch(error => {
|
||||
// this.$message.error(`删除试题失败: ${error.message}`);
|
||||
// });
|
||||
}).catch( () => { });
|
||||
},
|
||||
|
||||
doDetail(index, row) {
|
||||
this.$refs.detail.doShow({index, row});
|
||||
},
|
||||
|
||||
updateQuestion(form) {
|
||||
// updateQuestion(form.id, form).then(resp => {
|
||||
// this.reloadTable();
|
||||
// }).catch(error => {
|
||||
// this.$message.error(`修改问题失败: ${error.message}`);
|
||||
// });
|
||||
},
|
||||
|
||||
updateAnswer(form) {
|
||||
// updateAnswer(form.questionId, form).then(resp => {
|
||||
// this.reloadTable();
|
||||
// }).catch(error => {
|
||||
// this.$message.error(`修改答案失败: ${error.message}`);
|
||||
// });
|
||||
|
||||
},
|
||||
answerTags(row) {
|
||||
const answer = [];
|
||||
row.optionList.forEach((el, i) => {
|
||||
switch (row.type) {
|
||||
case 'select':
|
||||
if (el.correct) {
|
||||
answer.push(this.$asc2chart(i + 65));
|
||||
}
|
||||
break;
|
||||
case 'judge':
|
||||
if (el.correct) {
|
||||
answer.push(el.content);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
return answer;
|
||||
},
|
||||
|
||||
reloadTable() {
|
||||
this.queryList.reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
55
src/views/competitionManage/bankList/item-answer.vue
Normal file
55
src/views/competitionManage/bankList/item-answer.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="type=='select'">
|
||||
<el-radio-group v-model="active" @change="onChange">
|
||||
<el-radio v-for="(el,i) in optionList" :key="i" :label="i"> 选项-{{ $asc2chart(65+i) }} </el-radio>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<template v-if="type=='judge'">
|
||||
<el-radio-group v-model="active" @change="onChange">
|
||||
<el-radio :label="0"> √ </el-radio>
|
||||
<el-radio :label="1"> × </el-radio>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
optionList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.active = val;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.$emit('input', e);
|
||||
this.$emit('change', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
62
src/views/competitionManage/bankList/item-options.vue
Normal file
62
src/views/competitionManage/bankList/item-options.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="option">
|
||||
<template v-if="type=='select'">
|
||||
<div v-for="(el,i) in optionList" :key="i" class="option__item">
|
||||
<div> 选项-{{ $asc2chart(65+i) }} </div>
|
||||
<item-rich v-model="el.content" :remove="remove" @modify="doModify(el)" @remove="doRemove(i)" />
|
||||
</div>
|
||||
<el-button v-if="add" class="item__button" type="primary" size="mini" icon="el-icon-plus" @click="doAppend" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ItemRich from './item-rich';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ItemRich
|
||||
},
|
||||
props: {
|
||||
optionList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
add: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
remove: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
doModify(el) {
|
||||
this.$emit('modify', {model: el, prop: 'content'});
|
||||
},
|
||||
doRemove(index) {
|
||||
this.$emit('remove', index);
|
||||
},
|
||||
doAppend() {
|
||||
this.$emit('append');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.option {
|
||||
&__item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
55
src/views/competitionManage/bankList/item-rich.vue
Normal file
55
src/views/competitionManage/bankList/item-rich.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="item no-select" :style="{height: height+'px'}">
|
||||
<div class="ql-editor item__text" @click="doModify" v-html="$escapeHTML(`${value}`)" />
|
||||
<el-button class="item__button" type="primary" size="mini" icon="el-icon-edit" circle @click="doModify" />
|
||||
<el-button v-if="remove" class="item__button" type="danger" size="mini" icon="el-icon-delete" circle @click="doRemove" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 60
|
||||
},
|
||||
remove: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doModify() {
|
||||
this.$emit('modify', this.value);
|
||||
},
|
||||
doRemove() {
|
||||
this.$emit('remove', this.value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&__text {
|
||||
flex: 1;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
&__button {
|
||||
width: 32px;
|
||||
margin-left: 10px;
|
||||
place-self: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
109
src/views/competitionManage/bankList/question-create-page.vue
Normal file
109
src/views/competitionManage/bankList/question-create-page.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="page__container">
|
||||
<el-card class="page__container-body">
|
||||
<question-form ref="info" :option="formModel" :remove="true" @modify="doModify" />
|
||||
</el-card>
|
||||
<div class="page__container-footer">
|
||||
<el-button type="primary" :is-create="true" @click="create">提 交</el-button>
|
||||
<el-button @click="back">返 回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<dialog-modify-rich ref="rich" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QuestionForm from './question-form.vue';
|
||||
import DialogModifyRich from './dialog-modify-rich';
|
||||
import { createQuestion } from '@/api/questionBank.js';
|
||||
import * as authUtils from '@/utils/auth.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
QuestionForm,
|
||||
DialogModifyRich
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
formModel: {
|
||||
id: '',
|
||||
topic: '',
|
||||
type: 'select',
|
||||
answer: 0,
|
||||
optionList: []
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
deviceId() {
|
||||
return this.$route.params.deviceId;
|
||||
},
|
||||
path() {
|
||||
return this.$route.path;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const value = authUtils.getSessionStorage(this.path);
|
||||
if (value) {
|
||||
const model = JSON.parse(value);
|
||||
this.formModel.type = model.type;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doBack() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
doModify(node) {
|
||||
this.$refs.rich.doShow(node);
|
||||
},
|
||||
create() {
|
||||
this.$refs.info.validate().then(valid => {
|
||||
if (valid) {
|
||||
createQuestion(this.formModel).then(resp => {
|
||||
authUtils.setSessionStorage(this.path, JSON.stringify({
|
||||
type: this.formModel.type
|
||||
}));
|
||||
this.doBack();
|
||||
}).catch(error => {
|
||||
this.$message.error(`创建试题失败: ${error.message}`);
|
||||
});
|
||||
}
|
||||
}).catch(error => { this.$message.warning(error.message); });
|
||||
},
|
||||
back() {
|
||||
this.$router.go(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
width: 100%;
|
||||
&__container {
|
||||
width: 55%;
|
||||
margin: auto;
|
||||
&-header {
|
||||
margin-bottom: 10px;
|
||||
.step-group {
|
||||
margin: 10px 0;
|
||||
.box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-body {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
129
src/views/competitionManage/bankList/question-form.vue
Normal file
129
src/views/competitionManage/bankList/question-form.vue
Normal file
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="form" :model="option" :rules="rules" label-width="80px">
|
||||
<el-form-item label="类 型" prop="type">
|
||||
<el-select v-model="option.type" :disabled="disabled" placeholder="请选择试题类型" @change="onTypeChnage">
|
||||
<el-option v-for="it in QuestionTypeList" :key="it.value" :label="it.label" :value="it.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="问 题" prop="topic">
|
||||
<item-rich v-model="option.topic" @modify="onModify({model: option, prop: 'topic'})" />
|
||||
</el-form-item>
|
||||
<template v-if="isCreate">
|
||||
<el-form-item v-if="option.type != 'judge'" label="选 项" prop="optionList">
|
||||
<item-options :option-list="optionList" :type="option.type" :add="isSelect" :remove="remove" @remove="onRemove" @modify="onModify" @append="onAppend" />
|
||||
</el-form-item>
|
||||
<el-form-item label="答 案" prop="answer">
|
||||
<item-answer v-model="option.answer" :option-list="optionList" :type="option.type" @change="onAnswerChnage" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ItemRich from './item-rich';
|
||||
import ItemOptions from './item-options';
|
||||
import ItemAnswer from './item-answer';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ItemRich,
|
||||
ItemOptions,
|
||||
ItemAnswer
|
||||
},
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isCreate: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
remove: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isSelect() {
|
||||
return this.remove && this.option.type == 'select';
|
||||
},
|
||||
templateMap() {
|
||||
return {
|
||||
select: function() {
|
||||
return [
|
||||
{ content: '', correct: true },
|
||||
{ content: '', correct: false },
|
||||
{ content: '', correct: false },
|
||||
{ content: '', correct: false }
|
||||
];
|
||||
},
|
||||
judge: function() {
|
||||
return [
|
||||
{ content: '√', correct: true },
|
||||
{ content: '×', correct: false }
|
||||
];
|
||||
}
|
||||
};
|
||||
},
|
||||
optionList() {
|
||||
return this.option.optionList;
|
||||
},
|
||||
QuestionTypeList() {
|
||||
return this.$ConstSelect.QuestionTypeList;
|
||||
},
|
||||
rules() {
|
||||
return {
|
||||
topic: [
|
||||
{ required: true, message: '请输入试题内容', trigger: 'blur' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请输入试题类型', trigger: 'change' }
|
||||
],
|
||||
answer: [
|
||||
{ required: true, message: '请选择正确答案', trigger: 'change' }
|
||||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.onTypeChnage(this.option.type);
|
||||
},
|
||||
methods: {
|
||||
validate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
},
|
||||
onTypeChnage(type) {
|
||||
if (this.templateMap[type]) {
|
||||
this.option.optionList = this.templateMap[type]();
|
||||
}
|
||||
},
|
||||
onAnswerChnage(answer) {
|
||||
this.option.optionList.forEach((el, i) => { el.correct = i == answer; });
|
||||
},
|
||||
onModify(node) {
|
||||
this.$emit('modify', node);
|
||||
},
|
||||
onAppend() {
|
||||
this.option.optionList.push({content: '', correct: false});
|
||||
},
|
||||
onRemove(index) {
|
||||
this.option.optionList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
104
src/views/competitionManage/bankList/question-update-page.vue
Normal file
104
src/views/competitionManage/bankList/question-update-page.vue
Normal file
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="page__container">
|
||||
<el-card class="page__container-body">
|
||||
<item-options :option-list="optionList" :type="formModel.type" @modify="doModify" />
|
||||
</el-card>
|
||||
</div>
|
||||
<div class="page__container-footer">
|
||||
<el-button @click="back">返 回</el-button>
|
||||
</div>
|
||||
<dialog-modify-rich ref="rich" @update="update" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ItemOptions from './item-options';
|
||||
import DialogModifyRich from './dialog-modify-rich';
|
||||
import { getQuestionInfo, getOptionsByQuestionId, updateOption } from '@/api/questionBank.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ItemOptions,
|
||||
DialogModifyRich
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formModel: {
|
||||
id: '',
|
||||
topic: '',
|
||||
type: '',
|
||||
answer: 0
|
||||
},
|
||||
optionList: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
questionId() {
|
||||
return this.$route.params.questionId;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$router': function() {
|
||||
this.loadInitData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadInitData();
|
||||
},
|
||||
methods: {
|
||||
loadInitData() {
|
||||
getQuestionInfo(this.questionId).then(resp => {
|
||||
this.formModel = resp.data;
|
||||
getOptionsByQuestionId(this.questionId).then(resp => {
|
||||
this.optionList = resp.data;
|
||||
});
|
||||
});
|
||||
},
|
||||
doBack() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
doModify(node) {
|
||||
this.$refs.rich.doShow(node);
|
||||
},
|
||||
update(data) {
|
||||
updateOption(data.id, data).then(resp => {
|
||||
}).catch(error => {
|
||||
this.$message.error(`更新选项失败: ${error.message}`);
|
||||
});
|
||||
},
|
||||
back() {
|
||||
this.$router.go(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
width: 100%;
|
||||
&__container {
|
||||
width: 55%;
|
||||
margin: auto;
|
||||
&-header {
|
||||
margin-bottom: 10px;
|
||||
.step-group {
|
||||
margin: 10px 0;
|
||||
.box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-body {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,15 +1,10 @@
|
||||
<template>
|
||||
<div class="menuTrainListOut">
|
||||
<div v-if="drawer" class="menuTrainListBtn" @click="clickBtn"><i
|
||||
class="el-icon-more"
|
||||
style="font-size: 20px;margin-top: 9px;transform-origin: 50% 50%;transform: rotate(90deg);margin-left: -10px;"
|
||||
/></div>
|
||||
<div class="menuTrainListOut" :class="{'xian_01' : lineCode == '11'}">
|
||||
<div v-if="drawer" class="menuTrainListBtn" @click="clickBtn">
|
||||
<i class="el-icon-more" style="font-size: 20px;margin-top: 9px;transform-origin: 50% 50%;transform: rotate(90deg);margin-left: -10px;" /></div>
|
||||
<div v-else class="menuTrainListBtn1" @click="clickBtn">
|
||||
<div class="menuTrainListBtn1In">
|
||||
<i
|
||||
class="el-icon-more"
|
||||
style="font-size: 20px;margin-top: 9px;transform-origin: 50% 50%;transform: rotate(90deg);"
|
||||
/>
|
||||
<i class="el-icon-more" style="font-size: 20px;margin-top: 9px;transform-origin: 50% 50%;transform: rotate(90deg);" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -38,18 +33,23 @@ export default {
|
||||
oldDevice: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
lineCode() {
|
||||
return this.$route.query.lineCode;
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
'$store.state.map.trainListUpdate': function (val) {
|
||||
this.trainList = this.$store.state.map.map.trainList.filter((train)=>{
|
||||
return train.serviceNumber != '' && train.serviceNumber != undefined;
|
||||
});
|
||||
console.log(this.trainList);
|
||||
},
|
||||
'$store.state.map.runPlanStatus': function (val) {
|
||||
if (!val) {
|
||||
this.trainList = [];
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
@ -67,29 +67,7 @@ export default {
|
||||
// 设置显示中心
|
||||
setCenter(code) {
|
||||
this.$emit('setCenter', code);
|
||||
// const device = this.$store.getters['map/getDeviceByCode'](code);
|
||||
// this.deviceHighLight(this.oldDevice, false);
|
||||
// this.deviceHighLight(device, true);
|
||||
// this.oldDevice = device;
|
||||
}
|
||||
// 高亮设备
|
||||
// deviceHighLight(device, flag) {
|
||||
// if (device && device.instance && typeof device.instance.drawSelected === 'function' ) {
|
||||
// if (device._type === 'Section' && device.type === '04') {
|
||||
// device.relevanceSectionList.forEach(item => {
|
||||
// const sectionModel = this.$store.getters['map/getDeviceByCode'](item);
|
||||
// sectionModel && sectionModel.instance.drawSelected(flag);
|
||||
// });
|
||||
// } else if (device._type === 'Section' && device.type === '01' && device.logicSectionCodeList && device.logicSectionCodeList.length) {
|
||||
// device.logicSectionCodeList.forEach(item => {
|
||||
// const sectionModel = this.$store.getters['map/getDeviceByCode'](item);
|
||||
// sectionModel && sectionModel.instance.drawSelected(flag);
|
||||
// });
|
||||
// } else {
|
||||
// device.instance.drawSelected(flag);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <turnback-bar :title="turnbackBarTitle"></turnback-bar> -->
|
||||
<QueryListPage ref="queryListPage" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
|
||||
<div class="draft">
|
||||
<el-button-group>
|
||||
@ -102,12 +101,6 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
// computed: {
|
||||
// turnbackBarTitle() {
|
||||
// return this.dic.name + '(' + this.dic.code + ')'
|
||||
// }
|
||||
// },
|
||||
|
||||
created() {
|
||||
this.dicId = this.$route.query.id;
|
||||
getData(this.dicId).then(response => {
|
||||
|
Loading…
Reference in New Issue
Block a user