需要实现的业务功能:问卷调查类似,左边编辑题目,右边实时实现题型可视化预览。如下:
调查问卷题型可视化:
考试题目题型可视化:
调查问卷
<template>
<div class="created-form-text">
<div class="content">
<div>
<p>从文本创建调查问卷 <el-button @click="getLeg" link type="primary">查看样例</el-button></p>
<div class="left">
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入内容" v-model="textarea" @input="textChange"> </el-input>
</div>
<p style="text-align: right; margin-top: 20px">
<el-button>取消</el-button>
<el-button type="primary" @click="markSure">确定</el-button>
</p>
</div>
<div>
<p>预览 <el-button link></el-button></p>
<div class="right">
<p v-for="(i, index) in textTitle" :key="index" class="textClass">{{ i }}</p>
<div class="question-box" v-for="(item, index) in questionList" :key="index">
<p style="margin-bottom: 6px">{{ index + 1 }}.{{ item.title }}</p>
<div v-if="item.type === 'radio'">
<el-radio-group v-model="radio">
<el-radio :label="index + 1" v-for="(i, index) in item.ques" :key="index" disabled>{{ i }}</el-radio>
</el-radio-group>
</div>
<div v-else-if="item.type === 'checkbox'">
<el-checkbox-group v-model="checkList">
<el-checkbox :label="i" v-for="(i, index) in item.ques" :key="index" disabled></el-checkbox>
</el-checkbox-group>
</div>
<div v-else-if="item.type === 'input'">
<el-input v-model="inputText" placeholder="请输入内容" disabled></el-input>
</div>
<div v-else-if="item.type === 'texteare'">
<el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="textareaText" disabled> </el-input>
</div>
</div>
</div>
</div>
</div>
<el-dialog title="提示" v-model="isShowLeg" width="40%" :close-on-click-modal="false" destroy-on-close>
<div>
<p style="color: #79bbff; margin-bottom: 20px">格式说明:每道题之间用空白行隔开;用[单选题]、[多选题]、[单行填空题]、[多行填空题]来标注不同的题型</p>
<div class="diaClass">
《安全生产法》问卷调查<br /><br />
问卷简介<br /><br />
本单位安全生产第一责任人是()[单选题]<br />
法人<br />
主要责任人<br />
总经理<br />
总工程师<br /><br />
安全生产事故调查的“四不放过”指的是[多选题]<br />
事故原因未查清不放过<br />
责任人未受到处理不放过<br />
整改措施未落实不放过<br />
有关人员未受到教育不放过<br /><br />
请用一句话描述你对新安全生产法的认识[单行填空题]<br /><br />
请详细描述你对新安全生产法的理解[多行填空题]<br />
</div>
<div class="footer">
<el-button type="primary" @click="isShowLeg = false">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
export default {
data() {
return {
radio: '',
checkList: [],
inputText: '',
textareaText: '',
textarea: '',
questionList: [],
isShowLeg: false,
textTitle: [],
}
},
methods: {
textChange(data) {
if (!data) return
const b = data.replace(new RegExp(' ', 'gm'), '\u3000') //可输入空格
const text = b.split('\n\n') //根据换行题目与题目之间分割
this.questionList = []
this.textTitle = []
text.forEach((i) => {
const a = i.split('\n').filter(Boolean) //将题目答案分割成数组
if (this.quesTypeFun(a[0]) === '[单选题]') {
this.questionList.push({
title: a[0].replace('[单选题]', ''),
ques: a.slice(1),
type: 'radio',
})
} else if (this.quesTypeFun(a[0]) === '[多选题]') {
this.questionList.push({
title: a[0].replace('[多选题]', ''),
ques: a.slice(1),
type: 'checkbox',
})
} else if (this.quesTypeFun(a[0]) === '[单行填空题]') {
this.questionList.push({
title: a[0].replace('[单行填空题]', ''),
type: 'input',
})
} else if (this.quesTypeFun(a[0]) === '[多行填空题]') {
this.questionList.push({
title: a[0].replace('[多行填空题]', ''),
type: 'texteare',
})
} else {
this.textTitle.push(a[0])
}
// console.log(this.questionList)
})
},
//判断题型
quesTypeFun(str) {
if (str) {
//从字符串末尾截取中括号到结尾之间的字符
return str.substring(str.lastIndexOf('['), str.length)
}
// if (str.indexOf('[') != -1 && str.indexOf(']') != -1) {
// let a1 = /\[(.+?)\]/g
// let a2 = str.match(a1).toString()
// var a3 = a2.replace('[', '')
// a3 = a3.replace(']', '')
// // console.log(a3)
// return a3
// }
},
//查看示例
getLeg() {
this.isShowLeg = true
},
},
}
</script>
<style lang="less">
.created-form-text {
padding: 0 1%;
.content {
display: flex;
justify-content: space-between;
.left {
.el-textarea__inner {
height: 100% !important;
box-shadow: none;
border-radius: 10px;
}
}
.right {
padding: 1%;
box-sizing: border-box;
overflow: scroll;
.textClass {
margin-bottom: 20px;
text-align: center;
}
.question-box {
margin-bottom: 20px;
}
.el-radio,
.el-radio-group,
.el-checkbox {
display: block;
}
.el-radio__label,
.el-checkbox__label {
color: #777;
}
.el-checkbox-group {
line-height: unset;
}
}
> div {
width: 49%;
overflow: scroll;
> div {
border: 1px solid #d1dbe5;
border-radius: 10px;
height: 500px;
}
> p {
margin-bottom: 31px;
}
.el-textarea {
height: 100%;
}
}
}
.footer {
text-align: center;
margin: 20px;
}
.diaClass {
border: 1px solid #d1dbe5;
border-radius: 10px;
padding: 10px;
}
}
</style>
考试问卷
<template>
<div class="created-form-text-ks">
<div class="content">
<div>
<p>从文本创建考试问卷 <el-button link type="primary" @click="getLeg">查看样例</el-button></p>
<div class="left">
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入内容" v-model="textarea" @input="textChange"> </el-input>
</div>
<p style="text-align: right; margin-top: 20px">
<el-button>取消</el-button>
<el-button type="primary" @click="markSure">确定</el-button>
</p>
</div>
<div>
<p>预览 <el-button link></el-button></p>
<div class="right">
<p v-for="(i, index) in textTitle" :key="index" class="textClass">
{{ i }}
</p>
<div class="question-box" v-for="(item, index) in questionList" :key="index">
<p style="margin-bottom: 6px">
{{ index + 1 }}.{{ item.title }} (<span style="color: #409eff">分值:{{ item.score }}</span
>)
</p>
<div v-if="item.type === 'radio'">
<el-radio-group v-model="item.value">
<el-radio :label="index + 1" v-for="(i, index) in item.ques" :key="index" disabled>{{ i }}</el-radio>
</el-radio-group>
</div>
<div v-else-if="item.type === 'judge'">
<el-radio-group v-model="item.value" disabled>
<el-radio :label="1">对</el-radio>
<el-radio :label="2">错</el-radio>
</el-radio-group>
</div>
<div v-else-if="item.type === 'checkbox'">
<el-checkbox-group v-model="item.value">
<el-checkbox :label="i" v-for="(i, index) in item.ques" :key="index" disabled></el-checkbox>
</el-checkbox-group>
</div>
<div v-else-if="item.type === 'input'">
<el-input v-model="item.value" placeholder="请输入内容" disabled></el-input>
</div>
<div v-else-if="item.type === 'texteare'">
<el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="item.value" disabled> </el-input>
</div>
</div>
</div>
</div>
</div>
<el-dialog title="提示" v-model="isShowLeg" width="40%" :close-on-click-modal="false" destroy-on-close>
<div>
<p style="color: #79bbff; margin-bottom: 20px">格式说明:每道题之间用空白行隔开;用[单选题]、[判断题]、[多选题]、[填空题]、[简答题]来标注不同的题型,分值与答案之间用,隔开</p>
<div class="diaClass">
《安全生产法》考试<br /><br />
考试问卷简介,该行可以删除<br /><br />
本单位安全生产第一责任人是()[单选题]4分,C<br />
法人<br />
主要责任人<br />
总经理<br />
总工程师<br /><br />
《安全生产法》不仅适用于生产经营单位,同时也适用于国家安全和社会治安方面的管理。[判断题]3分,错<br /><br />
安全生产事故调查的“四不放过”指的是[多选题]5分,ABCD<br />
事故原因未查清不放过<br />
责任人未受到处理不放过<br />
整改措施未落实不放过<br />
有关人员未受到教育不放过<br /><br />
请用一句话描述你对安全生产法的认识[填空题]5分<br />
答案:二十|20<br /><br />
请详细描述你觉得新安全生产法有哪些好处[简答题]10分<br />
参考答案:我认为有这些好处:1...2...3...<br />
</div>
<div class="footer">
<el-button type="primary" @click="isShowLeg = false">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
export default {
data() {
return {
radio: '',
judgeValue: '',
checkList: [],
inputText: '',
textareaText: '',
textarea: '',
questionList: [],
isShowLeg: false,
textTitle: [],
}
},
methods: {
textChange(data) {
if (!data) return
const b = data.replace(new RegExp(' ', 'gm'), '\u3000')
const text = b.split('\n\n')
this.questionList = []
this.textTitle = []
text.forEach((i) => {
const a = i.split('\n').filter(Boolean)
let flag = []
if (a.length > 0) {
//中英文逗号全部转化为英文逗号
flag = a[0].replace(/[\uff0c]/g, ',')
}
if (this.quesTypeFun(a[0]) === '[单选题]') {
this.questionList.push({
title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
ques: a.slice(1),
type: 'radio',
value: this.getAnswerFun(a),
score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
})
} else if (this.quesTypeFun(a[0]) === '[判断题]') {
this.questionList.push({
title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
ques: a.slice(1),
type: 'judge',
value: this.getAnswerFun(a),
score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
})
} else if (this.quesTypeFun(a[0]) === '[多选题]') {
this.questionList.push({
title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
ques: a.slice(1),
type: 'checkbox',
value: this.getAnswerFun(a),
score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
})
} else if (this.quesTypeFun(a[0]) === '[填空题]') {
this.questionList.push({
title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
type: 'input',
value: a[1],
score: a[0].substring(a[0].lastIndexOf(']') + 1, a[0].length),
})
} else if (this.quesTypeFun(a[0]) === '[简答题]') {
this.questionList.push({
title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
type: 'texteare',
value: a[1],
score: a[0].substring(a[0].lastIndexOf(']') + 1, a[0].length),
})
} else {
this.textTitle.push(a[0])
}
// console.log(this.questionList)
})
},
//判断题型
quesTypeFun(str) {
if (str) {
return str.substring(str.lastIndexOf('['), str.lastIndexOf(']') + 1)
} else {
return ''
}
},
//将ABCDE...转化为12345....
reverNum(str, a) {
if (str.length > 1) {
const arrStr = str.split('')
let arr = []
arrStr.forEach((item) => {
arr.push(a[item.charCodeAt() - 64])
})
return arr
} else {
return str.charCodeAt() - 64
}
},
//获取题目答案
getAnswerFun(a) {
const flag = a[0].replace(/[\uff0c]/g, ',')
const value = a[0].substring(flag.lastIndexOf(',') + 1, a[0].length)
if (value === '对') {
return 1
} else if (value === '错') {
return 2
} else {
return this.reverNum(value, a)
}
},
//查看示例
getLeg() {
this.isShowLeg = true
},
},
}
</script>
<style lang="less">
.created-form-text-ks {
padding: 0 1%;
.content {
display: flex;
justify-content: space-between;
.left {
.el-textarea__inner {
height: 100% !important;
box-shadow: none;
border-radius: 10px;
}
}
.right {
padding: 1%;
box-sizing: border-box;
overflow: scroll;
.textClass {
margin-bottom: 20px;
text-align: center;
}
.question-box {
margin-bottom: 20px;
}
.el-radio,
.el-radio-group,
.el-checkbox {
display: block;
}
.el-radio__label,
.el-checkbox__label {
color: #777;
}
.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
background: #409eff;
color: #fff;
&::after {
border-color: #fff;
}
}
.el-checkbox-group {
line-height: unset;
}
}
> div {
width: 49%;
overflow: scroll;
> div {
border: 1px solid #d1dbe5;
border-radius: 10px;
height: 500px;
}
> p {
margin-bottom: 31px;
}
.el-textarea {
height: 100%;
}
}
}
.footer {
text-align: center;
margin: 20px;
}
.diaClass {
border: 1px solid #d1dbe5;
border-radius: 10px;
padding: 10px;
}
}
</style>