<template> <div class="app-container"> <el-card shadow="never"> <el-row :gutter="20" type="flex" justify="space-between"> <el-col :span="12" style="display: flex;align-items: center;"> <div style="margin-right: 30px;">科室:{{ baseForm.title }}</div> <el-button type="primary" @click="handleAddTopic">增加题目</el-button> </el-col> <el-col :span="12" style="display: flex;align-items: center;"> <div style="margin-right: 30px;"> <span>状态:</span> <el-radio v-model="baseForm.enable" :label="true" border size="medium" >启用</el-radio > <el-radio v-model="baseForm.enable" :label="false" border size="medium" >禁用</el-radio > </div> <el-button @click="handlePreview" type="primary" style="margin-right: 30px;" >保存并预览</el-button > <el-button type="primary" style="margin-right: 30px;" @click="handleSubmit" >保 存</el-button > </el-col> </el-row> </el-card> <el-form :model="baseForm" ref="baseForm" label-width="100px" class="demo-dynamic" > <div v-for="(item, index) in baseForm.questions" :key="index"> <el-card shadow="never" style="margin-top: 20px;"> <el-form-item :label="`第${index + 1}题`"> <el-button type="primary" @click="handleMoveUpTopic(index)" >上移</el-button > <el-button type="primary" @click="handleMoveDownTopic(index)" >下移</el-button > <el-button type="danger" @click="handleDelTopic(index, item)" >删除</el-button > </el-form-item> <el-row> <el-col :span="8"> <el-form-item :prop="'questions.' + index + '.question'" label="标题" :rules="[ { required: true, message: '请输入标题', trigger: 'blur' } ]" > <el-input v-model="item.question" type="textarea" maxlength="64" show-word-limit style="width: 400px;" ></el-input> </el-form-item> </el-col> <el-col :span="5"> <el-form-item :prop="'questions.' + index + '.questionType'" label="题型" :rules="[ { required: true, message: '请选择题型', trigger: 'change' } ]" > <el-radio-group v-model="item.questionType" @input="handleQuestionType"> <el-radio label="SINGLE">单选题</el-radio> <el-radio label="MULTI">多选题</el-radio> </el-radio-group> </el-form-item> </el-col> </el-row> <div v-for="(itemA, indexA) in item.answers"> <el-row type="flex"> <el-form-item :key="indexA" :label="`选项${indexA + 1}`" :rules="{ required: true, message: '选项不能为空', trigger: 'blur' }" > <el-input v-model="item.answers[indexA].answer" maxlength="64" show-word-limit style="width: 400px;" ></el-input> <el-button type="primary" plain @click="handleMoveUpOption(index, indexA)" >上移</el-button > <el-button type="primary" plain @click="handleMoveDownOption(index, indexA)" >下移</el-button > <el-button type="danger" plain @click="handleDelOption(index, indexA, itemA)" >删除</el-button > </el-form-item> <el-form-item prop="motifQuestionId" label="题目跳转" v-if="item.questionType == 'SINGLE'"> <el-tooltip content="设置选项跳转指定题目,未设置时默认跳转下一题,如需实现题目跳转关联请所有选项都关联同一题" placement="top" > <i class="el-icon-warning"></i> </el-tooltip> <el-select v-model="item.answers[indexA].subproblemQuestionId" placeholder="请选择" style="width: 200px;" clearable :disabled="baseForm.questions.length - 1 == index" @focus="handleMotifQuestionFocus(index)" > <el-option v-for="(item, j) in questionsListNew" :key="j" :label="item.question" :value="item.questionId" :disabled="item.disabled" > </el-option> </el-select> </el-form-item> </el-row> </div> <el-form-item> <el-button type="primary" plain @click="handleAddOption(index)" >新增选项</el-button > </el-form-item> </el-card> </div> </el-form> <preview ref="preview" :dialogVisible="dialogVisible" :questionnaireId="baseForm.questionnaireId" @close="close"></preview> </div> </template> <script> import { questionnaireInfoApi, questionnaireUpdateApi, questionnaireDeleteApi, questionnaireAnswerDeleteApi } from "@/api/hospital/department"; import preview from "./preview.vue"; export default { name: "diseaseInvestigationEdit", components:{preview}, data() { return { dialogVisible:false, motifQuestionIdList: [], questionsList: [], questionsListNew: [], baseForm: { enable: true, questionnaireId: null, questions: [ { question: "", questionType: "SINGLE", motifQuestionId: null, answers: [ { answer: "" } ] } ] } }; }, created() { console.log(this.$route.query.questionnaireId); if (this.$route.query.questionnaireId) { this.baseForm.questionnaireId = this.$route.query.questionnaireId; } this.getDetails(); }, watch: { "baseForm.questions": { handler(newValue, oldValue) { // 处理值变化 this.questionsList = newValue; console.log(this.questionsList, "监听题目变化"); this.questionsListNew = this.questionsList; }, deep: true, immediate: true } }, methods: { handleMotifQuestionFocus(index) { this.questionsListNew = []; this.questionsList.forEach((obj, indexA) => { if (indexA <= index) { obj.disabled = true; } else { obj.disabled = false; } }); this.questionsListNew = this.questionsList; console.log(this.questionsListNew); }, // 获取详情 getDetails() { questionnaireInfoApi({ questionnaireId: this.baseForm.questionnaireId }).then(res => { this.baseForm = res.data; for (var i of this.baseForm.questions) { i.disabled = false; } }); }, // 新增选项 handleAddOption(index) { this.baseForm.questions[index].answers.push({ answer: "", subproblemQuestionIndex: null, subproblemQuestionId: null }); }, // 删除选项 handleDelOption(index, indexA, itemA) { if (this.baseForm.questions[index].answers.length == 1) { this.$message.warning("至少保留一条选项"); return; } else { if (itemA.answerId) { this.$confirm("此操作将永久删除该选项, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }) .then(() => { questionnaireAnswerDeleteApi([itemA.answerId]) .then(res => { this.$message.success(res.message); this.baseForm.questions[index].answers.splice(indexA, 1); this.getDetails(); }) .catch(err => { this.$message.error(err.message); }); }) .catch(() => {}); } else { this.baseForm.questions[index].answers.splice(indexA, 1); } } }, // 选项上移 handleMoveUpOption(index, indexA) { console.log(indexA); if (indexA == 0) { this.$message.warning("已经在第一条了"); return; } let optionList = this.baseForm.questions[index].answers; optionList.splice( indexA - 1, 1, ...optionList.splice(indexA, 1, optionList[indexA - 1]) ); }, // 选项下移 handleMoveDownOption(index, indexA) { let optionList = this.baseForm.questions[index].answers; optionList.splice( indexA, 1, ...optionList.splice(indexA + 1, 1, optionList[indexA]) ); }, // 新增题目 handleAddTopic() { this.baseForm.questions.push({ disabled: false, question: "", questionType: "SINGLE", motifQuestionId: null, answers: [ { answer: "", subproblemQuestionIndex: null, subproblemQuestionId: null } ] }); }, // 题目上移 handleMoveUpTopic(index) { if (index == 0) { this.$message.warning("已经在第一条了"); return; } let topicList = this.baseForm.questions; topicList.splice( index - 1, 1, ...topicList.splice(index, 1, topicList[index - 1]) ); }, // 题目下移 handleMoveDownTopic(index) { for (var i of this.baseForm.questions[index].answers) { i.subproblemQuestionIndex = null; i.subproblemQuestionId = null; } let topicList = this.baseForm.questions; topicList.splice( index, 1, ...topicList.splice(index + 1, 1, topicList[index]) ); }, // 删除题目 handleDelTopic(index, item) { if (this.baseForm.questions.length == 1) { this.$message.warning("至少保留一条题目"); return; } else { if (item.questionId) { this.$confirm("此操作将永久删除该题目, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }) .then(() => { questionnaireDeleteApi([item.questionId]) .then(res => { this.$message.success(res.message); this.baseForm.questions.splice(index, 1); this.getDetails(); }) .catch(err => { this.$message.error(err.message); }); }) .catch(() => {}); } else { this.baseForm.questions.splice(index, 1); } } }, // 提交 handleSubmit() { console.log(this.baseForm); this.$refs["baseForm"].validate(valid => { if (valid) { questionnaireUpdateApi(this.baseForm) .then(res => { this.$message.success(res.message); this.getDetails(); }) .catch(err => { this.$message.error(err.message); }); } else { return false; } }); }, // 保存预览 handlePreview(){ this.$refs["baseForm"].validate(valid => { if (valid) { questionnaireUpdateApi(this.baseForm) .then(res => { this.$message.success(res.message); this.getDetails(); this.dialogVisible = true this.$refs.preview.questionsArr = [] this.$refs.preview.getDetails() }) .catch(err => { this.$message.error(err.message); }); } else { return false; } }); }, close(){ this.dialogVisible = false }, handleQuestionType(val){ console.log(val) } } }; </script> <style lang="scss"></style>
预览功能preview.vue
<template> <div> <el-dialog title="预览" :visible.sync="dialogVisible" width="30%" :before-close="handleClose" > <div class="upDownBtn"> <div> <el-button type="primary" icon="el-icon-arrow-up" circle @click="handleScrollTop"></el-button> </div> <div> <el-button type="primary" icon="el-icon-arrow-down" circle style="margin-top: 10px;" @click="handleScrollBottom"></el-button> </div> </div> <div class="container" ref="scrollDiv"> <div class="list"> <div class="headImg"></div> <div class="content"> 你好,我将咨询您一系列问题,请如实回答,以帮助我更快做出诊断 </div> </div> <div v-for="(item, index) in questionsArr" :key="index"> <!-- 单选 --> <div class="list" v-if="item.questionType == 'SINGLE'"> <div class="headImg"></div> <div class="question"> <div class="title">{{ item.question }}</div> <div class="option" v-for="(itemA, indexA) in item.answers" :key="indexA" @click="handleCheckSingleAnswer(itemA, indexA, item, index)" :class="{ singleChecked: itemA.answerId == item.answerCheckId, disSelect: item.disSelect }" > {{ itemA.answer }} </div> </div> </div> <!-- 多选 --> <div class="list" v-if="item.questionType == 'MULTI'"> <div class="headImg"></div> <div class="question"> <div class="title"> {{ item.question + "(多选)" }} </div> <div class="option" v-for="(itemB, indexB) in item.answers" :key="indexB" @click="handleCheckMultiAnswer(itemB, indexB, item, index)" :class="{ singleChecked: itemB.check == true, disSelect: item.disSelect }" > {{ itemB.answer }} </div> <div class="check" @click="handleCheckMulti(item, index)" :class="{ disSelectBtn: item.disSelect }" > 选好了 </div> </div> </div> </div> </div> </el-dialog> </div> </template> <script> import { questionnaireInfoApi } from "@/api/hospital/department"; export default { props: { dialogVisible: { type: Boolean, default: false }, questionnaireId: { type: String, default: "" } }, data() { return { baseForm: {}, questionsArr: [], questionIndex: null }; }, methods: { // 滚动到顶部 handleScrollTop() { this.$nextTick(() => { let scrollElem = this.$refs.scrollDiv; scrollElem.scrollTo({ top: 0, behavior: "smooth" }); }); }, // 滚动到底部 handleScrollBottom() { this.$nextTick(() => { let scrollElem = this.$refs.scrollDiv; scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: "smooth" }); }); }, handleClose() { this.$emit("close"); }, // 获取详情 getDetails() { questionnaireInfoApi({ questionnaireId: this.questionnaireId }).then(res => { this.baseForm = res.data; this.baseForm.questions.forEach(val => { val.answerCheckId = ""; if (val.questionType == "MULTI") { val.answers.forEach(e => { e.check = false; }); } }); this.questionsArr.push(this.baseForm.questions[0]); console.log(this.questionsArr); }); }, // 单选 handleCheckSingleAnswer(itemA, indexA, item, index) { console.log(itemA, indexA, item, index); item.answerCheckId = itemA.answerId; item.disSelect = true; this.$set(this.questionsArr, index, item); //关键代码,当数组数据发生变化时,页面中动态绑定的样式没有变化 // 判断跳题 if (itemA.subproblemQuestionId) { var obj = this.baseForm.questions.find(function(item) { return item.questionId == itemA.subproblemQuestionId; }); this.questionIndex = this.baseForm.questions.findIndex( i => i.questionId == obj.questionId ); this.questionsArr.push(obj); } else { if (this.questionIndex + 1 >= this.baseForm.questions.length) { console.log("最后一道题了"); this.$message({ message: "恭喜你,已成功做完本次调研", type: "success" }); } else { this.questionIndex += 1; this.questionsArr.push(this.baseForm.questions[this.questionIndex]); this.handleScrollBottom(); } } console.log(this.questionIndex, this.baseForm.questions.length); }, // 多选 handleCheckMultiAnswer(itemB, indexB, item, index) { itemB.check = !itemB.check; this.$set(this.questionsArr, index, item); }, // 多选选好了 handleCheckMulti(item, index) { console.log(item) var isCheck = item.answers.some(function(e) { return e.check; }); console.log(isCheck) if(isCheck == false){ this.$message({ message: "请至少选择一个选项", type: "warning" }); return } item.disSelect = true; this.questionIndex = this.baseForm.questions.findIndex( i => i.questionId == item.questionId ); console.log(this.questionIndex); if (this.questionIndex + 1 >= this.baseForm.questions.length) { console.log("最后一道题了"); this.$message({ message: "恭喜你,已成功做完本次调研", type: "success" }); } else { this.questionIndex += 1; this.questionsArr.push(this.baseForm.questions[this.questionIndex]); this.handleScrollBottom(); } } } }; </script> <style lang="scss" scoped> .container { width: 375px; height: 720px; border: 1px solid #ccc; margin: 0 auto; padding: 12px; overflow-y: scroll; border-radius: 6px; .list { display: flex; margin-bottom: 12px; } .headImg { width: 39px; height: 39px; background: #d8d8d8; border-radius: 8px; margin-right: 9px; } .content { flex: 1; background: #f0f4f8; border-radius: 0px 19px 19px 19px; padding: 10px 15px; font-size: 15px; } .question { flex: 1; background: #f0f4f8; border-radius: 0px 19px 19px 19px; padding: 20px; .title { font-size: 16px; font-weight: 600; color: #191b21; margin-bottom: 16px; } .option { width: 100%; background: rgba(255, 255, 255, .4); border-radius: 8px; opacity: 0.4; border: 1px solid #e1e2e6; padding: 13px 16px; margin-bottom: 12px; text-align: center; } .check { font-size: 15px; color: #3d7ef0; text-align: center; } } .singleChecked { border: 2px solid #73d8c0 !important; font-size: 15px; background: #FFFFFF !important; color: #191B21; } .disSelect { pointer-events: none; } .disSelectBtn { pointer-events: none; color: rgba(61, 126, 240, 0.3) !important; } } .upDownBtn { position: absolute; right: 20px; bottom: 30px; display: flex; flex-direction: column; } </style>
标签:index,题目,baseForm,上移,indexA,item,questions,下移,message From: https://www.cnblogs.com/zcm1688/p/17705620.html