| | |
| | | <template> |
| | | <div class="questionnaire"> |
| | | <div class="CONTENT" v-if="!accomplish"> |
| | | <div class="preview-left"> |
| | | <div class="toptitle"> |
| | | <div class="title">{{ taskname ? taskname : "问卷" }}</div> |
| | | <div style="font-size: 22px; margin-bottom: 20px; line-height: 1.5"> |
| | | {{ |
| | | kcb |
| | | ? kcb |
| | | : "亲爱的患者-家属,您好!我们是无锡儿童医院的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,完成这份随访问卷。" |
| | | }} |
| | | <!-- 亲爱的患者/家属您好,为了更好的了解您出院后的康复情况,给您适当及时的健康指导,请您抽一点宝贵时间,完成这份出院随访问卷调查。 --> |
| | | <div class="questionnaire-optimized"> |
| | | <div class="content-wrapper" v-if="!accomplish"> |
| | | <div class="questionnaire-container"> |
| | | <!-- 问卷标题区域 --> |
| | | <div class="questionnaire-header"> |
| | | <h1 class="questionnaire-title">{{ taskname ? taskname : "问卷" }}</h1> |
| | | <div class="questionnaire-description"> |
| | | {{ kcb ? kcb : "亲爱的患者-家属,我们是医院的医护人员,为了更好地了解您的康复情况,请您抽一点宝贵时间,完成这份随访问卷。" }} |
| | | </div> |
| | | </div> |
| | | <el-divider></el-divider> |
| | | <!-- 单选 --> |
| | | <div |
| | | class="topic-dev" |
| | | v-for="(item, index) in questionList" |
| | | :key="item.aaa" |
| | | > |
| | | <div class="scriptTopic-dev" :key="index" v-if="item.scriptType == 1"> |
| | | <div class="dev-text"> |
| | | {{ index + 1 }}、<span style="line-height: 1.5" |
| | | >{{ item.scriptContent }} |
| | | <span style="color: #3ba2f7">[单选]</span></span |
| | | > |
| | | |
| | | <el-divider class="custom-divider"></el-divider> |
| | | |
| | | <!-- 问卷题目区域 --> |
| | | <div class="questions-section"> |
| | | <div |
| | | class="question-item" |
| | | v-for="(item, index) in visibleQuestions" |
| | | :key="item.id" |
| | | :class="{ 'has-warning': item.prompt && (item.scriptResult && (item.scriptType !== 2 || item.scriptResult.length > 0)) }" |
| | | > |
| | | <!-- 题目题干 --> |
| | | <div class="question-stem"> |
| | | <span class="question-number">{{ getVisibleQuestionIndex(index) }}.</span> |
| | | <span class="question-text">{{ item.scriptContent }}</span> |
| | | <span class="question-type-tag"> |
| | | {{ item.scriptType === 1 ? '[单选]' : item.scriptType === 2 ? '[多选]' : '[问答]' }} |
| | | </span> |
| | | </div> |
| | | <div class="dev-xx"> |
| | | <el-radio-group |
| | | class="custom-radio" |
| | | v-model="item.scriptResult" |
| | | @change="handleOptionChange($event, index, item)" |
| | | > |
| | | |
| | | <!-- 单选题目 --> |
| | | <div class="question-options" v-if="item.scriptType == 1 && !item.ishide"> |
| | | <el-radio-group class="options-group" v-model="item.scriptResult"> |
| | | <el-radio |
| | | border |
| | | v-for="(items, index) in item.svyLibTemplateTargetoptions" |
| | | :class=" |
| | | items.isabnormal && item.scriptResult == items.optioncontent |
| | | ? 'red-star' |
| | | : '' |
| | | " |
| | | :key="index" |
| | | :label="items.optioncontent" |
| | | >{{ items.optioncontent }}</el-radio |
| | | v-for="(option, optionIndex) in item.svyTaskTemplateTargetoptions" |
| | | :key="optionIndex" |
| | | :label="option.optioncontent" |
| | | :class="{ |
| | | 'abnormal-option': option.isabnormal && item.scriptResult == option.optioncontent |
| | | }" |
| | | @click.native.prevent="handleRadioToggle(item, index, item.svyTaskTemplateTargetoptions, option.optioncontent)" |
| | | class="option-radio" |
| | | > |
| | | <span class="option-text">{{ option.optioncontent }}</span> |
| | | <span v-if="option.isabnormal" class="abnormal-indicator">*</span> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </div> |
| | | <div v-show="item.prompt"> |
| | | <el-alert :title="item.prompt" type="warning"> </el-alert> |
| | | </div> |
| | | </div> |
| | | <!-- 多选 --> |
| | | <div class="scriptTopic-dev" :key="index" v-if="item.scriptType == 2"> |
| | | <div class="dev-text"> |
| | | {{ index + 1 }}、<span style="line-height: 1.5" |
| | | >{{ item.scriptContent }} |
| | | <span style="color: #3ba2f7">[多选]</span></span |
| | | > |
| | | </div> |
| | | <div class="dev-xx"> |
| | | <el-checkbox-group |
| | | class="custom-radio" |
| | | v-model="item.scriptResult" |
| | | @change="updateScore($event, index, item)" |
| | | > |
| | | |
| | | <!-- 多选题目 --> |
| | | <div class="question-options" v-if="item.scriptType == 2"> |
| | | <el-checkbox-group class="options-group" v-model="item.scriptResult"> |
| | | <el-checkbox |
| | | border |
| | | v-for="(option, optionIndex) in item.svyTaskTemplateTargetoptions" |
| | | :key="optionIndex" |
| | | :label="option.optioncontent" |
| | | :class="{ |
| | | 'abnormal-option': option.isabnormal |
| | | }" |
| | | @change="$forceUpdate()" |
| | | v-for="(items, indexs) in item.svyLibTemplateTargetoptions" |
| | | :key="indexs" |
| | | :label="items.optioncontent" |
| | | class="option-checkbox" |
| | | > |
| | | {{ items.optioncontent }} |
| | | <span class="option-text">{{ option.optioncontent }}</span> |
| | | <span v-if="option.isabnormal" class="abnormal-indicator">*</span> |
| | | </el-checkbox> |
| | | </el-checkbox-group> |
| | | </div> |
| | | <!-- :class="items.isabnormal ? 'red-star' : ''" --> |
| | | <div v-show="item.prompt && item.scriptResult[0]"> |
| | | <el-alert :title="item.prompt" type="warning"> </el-alert> |
| | | </div> |
| | | </div> |
| | | <!-- 填空 --> |
| | | <div class="scriptTopic-dev" :key="index" v-if="item.scriptType == 4"> |
| | | <div class="dev-text"> |
| | | {{ index + 1 }}、<span style="line-height: 1.5" |
| | | >{{ item.scriptContent |
| | | }}<span style="color: #3ba2f7">[问答]</span></span |
| | | > |
| | | </div> |
| | | <div class="dev-xx"> |
| | | |
| | | <!-- 填空题目 --> |
| | | <div class="question-input" v-if="item.scriptType == 4"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | placeholder="请输入答案" |
| | | placeholder="请输入您的回答" |
| | | v-model="item.scriptResult" |
| | | clearable |
| | | > |
| | | </el-input> |
| | | class="answer-textarea" |
| | | ></el-input> |
| | | </div> |
| | | |
| | | <!-- 提示信息 --> |
| | | <div class="question-warning" v-show="item.prompt && item.scriptResult && (item.scriptType !== 2 || item.scriptResult.length > 0)"> |
| | | <el-alert :title="item.prompt" type="warning" :closable="false" class="warning-alert"></el-alert> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="bottom-fixed"> |
| | | |
| | | <!-- 提交按钮 --> |
| | | <div class="submit-section"> |
| | | <el-button |
| | | type="primary" |
| | | style="width: 80%; font-size: 20px" |
| | | @click="cache(true)" |
| | | >提交问卷</el-button |
| | | class="submit-button" |
| | | > |
| | | 提交问卷 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="CONTENT" v-else> |
| | | <div class="preview-lefts"> |
| | | <div |
| | | style=" |
| | | text-align: center; |
| | | padding-top: 50px; |
| | | font-size: 24px; |
| | | color: #175997; |
| | | font-weight: 600; |
| | | margin-bottom: 10px; |
| | | " |
| | | > |
| | | 感谢您的配合! |
| | | </div> |
| | | <div style="font-size: 20px"> |
| | | {{ |
| | | jsy |
| | | ? jsy |
| | | : "生活上要劳逸结合,注意休息和营养,适当锻炼,戒烟限酒,保持心情舒畅,定期复诊。那本次回访就到这里,祝您身体健康!" |
| | | }} |
| | | </div> |
| | | |
| | | <!-- 完成页面 --> |
| | | <div class="completion-page" v-else> |
| | | <div class="completion-content"> |
| | | <div class="completion-icon">✓</div> |
| | | <h2 class="completion-title">感谢您的配合!</h2> |
| | | <p class="completion-message"> |
| | | {{ jsy ? jsy : "生活上要劳逸结合,注意休息和营养,适当锻炼,戒烟限酒,保持心情舒畅,定期复诊。那本次回访就到这里,祝您身体健康!" }} |
| | | </p> |
| | | </div> |
| | | </div> |
| | | <!-- <el-dialog |
| | | :visible.sync="dialogVisible" |
| | | width="50%" |
| | | > |
| | | <div> |
| | | <el-alert :title="jsy" type="success"> </el-alert> |
| | | </div> |
| | | </el-dialog> --> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | patid: 265823, |
| | | kcb: "", |
| | | excep: "", |
| | | questionList: [ |
| | | // { |
| | | // scriptType: 1, |
| | | // scriptContent: "您的年龄范围是?", |
| | | // scriptResult: null, |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "18-25", value: "18-25", isabnormal: true }, |
| | | // { optioncontent: "26-35", value: "26-35" }, |
| | | // { optioncontent: "36-45", value: "36-45" }, |
| | | // { optioncontent: "46-55", value: "46-55" }, |
| | | // { optioncontent: "56+", value: "56+" }, |
| | | // ], |
| | | // required: true, |
| | | // }, |
| | | // { |
| | | // scriptType: 1, |
| | | // scriptContent: "您的职业是什么?", |
| | | // scriptResult: null, |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "学生", value: "student" }, |
| | | // { optioncontent: "教师", value: "teacher" }, |
| | | // { optioncontent: "工程师", value: "engineer" }, |
| | | // { optioncontent: "医生", value: "doctor" }, |
| | | // { optioncontent: "其他", value: "other" }, |
| | | // ], |
| | | // required: false, |
| | | // }, |
| | | // { |
| | | // scriptType: 2, |
| | | // scriptContent: "您感兴趣的活动有哪些?", |
| | | // scriptResult: [], |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "旅游", value: "travel", isabnormal: true }, |
| | | // { optioncontent: "阅读", value: "reading", isabnormal: true }, |
| | | // { optioncontent: "运动", value: "sports", isabnormal: true }, |
| | | // { optioncontent: "音乐", value: "music" }, |
| | | // { optioncontent: "电影", value: "movies" }, |
| | | // ], |
| | | // required: false, |
| | | // }, |
| | | // { |
| | | // scriptType: 1, |
| | | // scriptContent: "您的职业是什么?", |
| | | // scriptResult: null, |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "学生", value: "student" }, |
| | | // { optioncontent: "教师", value: "teacher" }, |
| | | // { optioncontent: "工程师", value: "engineer" }, |
| | | // { optioncontent: "医生", value: "doctor" }, |
| | | // { optioncontent: "其他", value: "other" }, |
| | | // ], |
| | | // required: false, |
| | | // }, |
| | | // { |
| | | // scriptType: 1, |
| | | // scriptContent: "您的职业是什么?", |
| | | // scriptResult: null, |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "学生", value: "student" }, |
| | | // { optioncontent: "教师", value: "teacher" }, |
| | | // { optioncontent: "工程师", value: "engineer", isabnormal: true }, |
| | | // { optioncontent: "医生", value: "doctor" }, |
| | | // { optioncontent: "其他", value: "other" }, |
| | | // ], |
| | | // required: false, |
| | | // }, |
| | | // { |
| | | // scriptType: 1, |
| | | // scriptContent: "您的职业是什么?", |
| | | // scriptResult: null, |
| | | // svyLibTemplateTargetoptions: [ |
| | | // { optioncontent: "学生", value: "student" }, |
| | | // { optioncontent: "教师", value: "teacher" }, |
| | | // { optioncontent: "工程师", value: "engineer" }, |
| | | // { optioncontent: "医生", value: "doctor" }, |
| | | // { optioncontent: "其他", value: "other" }, |
| | | // ], |
| | | // required: false, |
| | | // }, |
| | | // { |
| | | // scriptType: 4, |
| | | // scriptContent: "您的姓名是什么?", |
| | | // scriptResult: "name", |
| | | // required: true, |
| | | // scriptResult: null, |
| | | // }, |
| | | ], |
| | | taskname: "", |
| | | questionList: [], |
| | | jsy: null, |
| | | dialogVisible: false, |
| | | Endornot: true, |
| | |
| | | }; |
| | | }, |
| | | mounted() { |
| | | window.addEventListener("beforeunload", this.cache); |
| | | // window.addEventListener("beforeunload", this.cache); |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener("beforeunload", this.cache); |
| | | // window.removeEventListener("beforeunload", this.cache); |
| | | }, |
| | | created() { |
| | | this.geturlinfo(); |
| | | }, |
| | | computed: { |
| | | // 计算属性:获取所有可见的题目 |
| | | visibleQuestions() { |
| | | return this.questionList.filter((question) => !question.ishide); |
| | | }, |
| | | }, |
| | | methods: { |
| | | // 解析urlid |
| | | geturlinfo() { |
| | | // let url = window.location.href; |
| | | let url = this.$route.query.p; |
| | | console.log(url,"url"); |
| | | // let url = window.location.href; |
| | | let url = this.$route.query.p; |
| | | console.log(url, "url"); |
| | | // let url = 'http://218.108.11.22:8093/sf/003'; |
| | | // let urlid = this.extractLastSegmentFromUrl(url); |
| | | |
| | | geturlinfo( url ).then((res) => { |
| | | if (res.code==200) { |
| | | this.getQuestionnaire(res.data.param1,res.data.param2,res.data.param3,res.data.param5,) |
| | | } |
| | | geturlinfo(url).then((res) => { |
| | | if (res.code == 200) { |
| | | this.getQuestionnaire( |
| | | res.data.param1, |
| | | res.data.param2, |
| | | res.data.param3, |
| | | res.data.param5 |
| | | ); |
| | | } |
| | | }); |
| | | }, |
| | | // extractLastSegmentFromUrl(url) { |
| | | // // 找到最后一个'/'的位置 |
| | | // const lastSlashIndex = url.lastIndexOf('/'); |
| | | // // 如果找到了'/',截取其后的所有字符 |
| | | // if (lastSlashIndex !== -1) { |
| | | // return url.substring(lastSlashIndex + 1); |
| | | // } |
| | | // // 如果没有找到'/',返回空字符串 |
| | | // return ''; |
| | | // }, |
| | | // extractLastSegmentFromUrl(url) { |
| | | // // 找到最后一个'/'的位置 |
| | | // const lastSlashIndex = url.lastIndexOf('/'); |
| | | // // 如果找到了'/',截取其后的所有字符 |
| | | // if (lastSlashIndex !== -1) { |
| | | // return url.substring(lastSlashIndex + 1); |
| | | // } |
| | | // // 如果没有找到'/',返回空字符串 |
| | | // return ''; |
| | | // }, |
| | | |
| | | // 获取数据 |
| | | getQuestionnaire(param1,param2,param3) { |
| | | getQuestionnaire(param1, param2, param3) { |
| | | this.taskid = decodeURIComponent(param1); |
| | | this.patid = decodeURIComponent(param2); |
| | | this.taskname = decodeURIComponent(param3); |
| | |
| | | param1: this.taskid, |
| | | param2: this.patid, |
| | | excep: this.excep, |
| | | isabnormal: this.excep, |
| | | serviceSubtaskDetailList: [], |
| | | }; |
| | | const arr = structuredClone(this.questionList); |
| | |
| | | let form = { |
| | | param1: this.taskid, |
| | | param2: this.patid, |
| | | svyLibTemplateScriptVOS: [], |
| | | svyTaskTemplateScriptVOS: [], |
| | | }; |
| | | const arr = structuredClone(this.questionList); |
| | | console.log(arr, "srr"); |
| | | arr.forEach((item, index) => { |
| | | var obj = item.svyLibTemplateTargetoptions.find( |
| | | (items) => items.optioncontent == item.scriptResult |
| | | ); |
| | | if (obj.isabnormal) { |
| | | console.log(obj.isabnormal); |
| | | form.excep = 1; |
| | | this.excep = 1; |
| | | if (item.scriptType == 1 && item.scriptResult) { |
| | | var obj = item.svyTaskTemplateTargetoptions.find( |
| | | (items) => items.optioncontent == item.scriptResult |
| | | ); |
| | | console.log(item); |
| | | |
| | | console.log(obj, "obj"); |
| | | if (obj.sendTaskid) { |
| | | item.sendTaskname = obj.sendTaskname; |
| | | item.sendTaskid = obj.sendTaskid; |
| | | console.log(String(obj.sendTaskid).split(",")); |
| | | item.sendTaskids = String(obj.sendTaskid).split(","); |
| | | } |
| | | if (obj) { |
| | | if (obj.isabnormal) { |
| | | console.log(obj.isabnormal); |
| | | form.excep = obj.isabnormal; |
| | | this.excep = obj.isabnormal; |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | |
| | | item.scriptResult = JSON.stringify(item.scriptResult); |
| | | } |
| | | }); |
| | | form.svyLibTemplateScriptVOS = arr; |
| | | form.svyTaskTemplateScriptVOS = arr; |
| | | form.type = 2; |
| | | Cachequestionnaire(form).then((res) => { |
| | | if (res.code == 200) { |
| | | if (subm) { |
| | |
| | | } |
| | | }); |
| | | }, |
| | | // 处理单选选项 |
| | | handleOptionChange(selectedvalue, index, arr) { |
| | | // 查找选中的选项对象 |
| | | const selectedOption = arr.svyLibTemplateTargetoptions.find( |
| | | (option) => option.optioncontent == selectedvalue |
| | | // 获取可见题目的正确序号(解决跳题后序号不连续的问题) |
| | | getVisibleQuestionIndex(index) { |
| | | return index + 1; |
| | | }, |
| | | // 新增的切换选中/取消选中方法 |
| | | handleRadioToggle(questionItem, index, options, optionValue) { |
| | | // 保存当前状态以便后续比较 |
| | | const previousState = JSON.parse(JSON.stringify(this.questionList)); |
| | | |
| | | // 原有的处理逻辑 |
| | | if (questionItem.scriptResult === optionValue) { |
| | | questionItem.scriptResult = ""; |
| | | questionItem.isabnormal = false; |
| | | questionItem.showAppendInput = false; |
| | | } else { |
| | | questionItem.scriptResult = optionValue; |
| | | this.handleOptionChange(optionValue, index, options, questionItem); |
| | | } |
| | | |
| | | // 处理完成后,确保重新计算可见题目的序号 |
| | | this.$forceUpdate(); |
| | | }, |
| | | |
| | | // 在methods部分,修改handleOptionChange方法: |
| | | handleOptionChange(selectedOption, questionIndex, options, a) { |
| | | console.log(selectedOption, questionIndex, options, a, "888"); |
| | | |
| | | if (document.activeElement) { |
| | | document.activeElement.blur(); |
| | | } |
| | | |
| | | // 找到被选中的选项对象 |
| | | const selectedOptionObj = options.find( |
| | | (item) => item.optioncontent == selectedOption |
| | | ); |
| | | if (selectedOption) { |
| | | // 将选中的选项对象的 id 赋值给 obj.sonId |
| | | this.questionList[index].nextScriptno = selectedOption.nextQuestion; |
| | | this.questionList[index].score = selectedOption.score; |
| | | this.questionList[index].prompt = selectedOption.prompt; |
| | | this.questionList[questionIndex].nextScriptno = |
| | | selectedOption.nextQuestion; |
| | | this.questionList[questionIndex].score = selectedOption.score; |
| | | this.questionList[questionIndex].prompt = selectedOption.prompt; |
| | | } |
| | | }, |
| | | // 处理多选选项 |
| | | updateScore(selectedvalues, index, arr) { |
| | | // ��加分数 |
| | | let score = 0; |
| | | selectedvalues.forEach((value) => { |
| | | const selectedOption = arr.svyLibTemplateTargetoptions.find( |
| | | (option) => option.optioncontent == value |
| | | ); |
| | | if (selectedOption) { |
| | | score += Number(selectedOption.score); |
| | | // 处理异常状态高亮 |
| | | this.questionList[questionIndex].isabnormal = |
| | | !!selectedOptionObj.isabnormal; |
| | | // 处理附加输入框显示 |
| | | |
| | | this.questionList[questionIndex].showAppendInput = |
| | | selectedOptionObj.appendflag == 1; |
| | | console.log(this.questionList); |
| | | |
| | | // if (!this.questionList[questionIndex].showAppendInput) { |
| | | // this.questionList[questionIndex].answerps = ""; // 清除附加信息 |
| | | // } |
| | | // 保存当前题目之前已经隐藏的题目状态 |
| | | const previouslyHiddenBeforeCurrent = this.questionList |
| | | .slice(0, questionIndex) |
| | | .map((item, index) => (item.ishide ? index : -1)) |
| | | .filter((index) => index !== -1); |
| | | |
| | | // 保存之前因nextQuestion=0而隐藏的题目范围 |
| | | const previouslyHiddenByEnd = this.questionList |
| | | .map((item, index) => (item.hiddenByEnd ? index : -1)) |
| | | .filter((index) => index !== -1); |
| | | |
| | | // 如果branchFlag为1,处理题目跳转 |
| | | if (a.branchFlag == 1) { |
| | | if (selectedOptionObj.nextQuestion == 0) { |
| | | // 结束问答 - 隐藏后面所有题目并标记 |
| | | this.questionList = this.questionList.map((item, index) => ({ |
| | | ...item, |
| | | ishide: index > questionIndex, |
| | | hiddenByEnd: index > questionIndex, // 标记这些题目是被结束问答隐藏的 |
| | | })); |
| | | } else { |
| | | // 正常跳转逻辑 |
| | | const nextQuestionIndex = selectedOptionObj.nextQuestion - 1; |
| | | |
| | | this.questionList = this.questionList.map((item, index) => { |
| | | // 保留当前题目之前的隐藏状态 |
| | | if (index < questionIndex) { |
| | | return { |
| | | ...item, |
| | | ishide: previouslyHiddenBeforeCurrent.includes(index), |
| | | hiddenByEnd: false, // 清除结束标记 |
| | | }; |
| | | } |
| | | |
| | | // 当前题目总是可见 |
| | | if (index === questionIndex) { |
| | | return { ...item, ishide: 0, hiddenByEnd: false }; |
| | | } |
| | | |
| | | // 显示目标下一题 |
| | | if (index === nextQuestionIndex) { |
| | | return { ...item, ishide: 0, hiddenByEnd: false }; |
| | | } |
| | | |
| | | // 如果是之前被结束问答隐藏的题目,现在应该恢复显示 |
| | | if (item.hiddenByEnd) { |
| | | return { ...item, ishide: 0, hiddenByEnd: false }; |
| | | } |
| | | |
| | | // 隐藏当前题和目标题之间的题目 |
| | | if (index > questionIndex && index < nextQuestionIndex) { |
| | | return { ...item, ishide: 1, hiddenByEnd: false }; |
| | | } |
| | | |
| | | // 其他情况保持原状 |
| | | return item; |
| | | }); |
| | | } |
| | | } else { |
| | | // 如果没有跳转,只需确保下一题可见 |
| | | this.questionList = this.questionList.map((item, index) => ({ |
| | | ...item, |
| | | ishide: index === questionIndex + 1 ? 0 : item.ishide, |
| | | hiddenByEnd: index === questionIndex + 1 ? false : item.hiddenByEnd, |
| | | })); |
| | | } |
| | | |
| | | // 在处理完题目显示/隐藏后,强制更新视图以确保序号正确 |
| | | this.$nextTick(() => { |
| | | this.$forceUpdate(); |
| | | }); |
| | | this.questionList[index].score = score; |
| | | }, |
| | | // 处理单选选项 |
| | | // handleOptionChange(selectedvalue, index, arr) { |
| | | // // 查找选中的选项对象 |
| | | // const selectedOption = arr.svyTaskTemplateTargetoptions.find( |
| | | // (option) => option.optioncontent == selectedvalue |
| | | // ); |
| | | // if (selectedOption) { |
| | | // this.questionList[index].nextScriptno = selectedOption.nextQuestion; |
| | | // this.questionList[index].score = selectedOption.score; |
| | | // this.questionList[index].prompt = selectedOption.prompt; |
| | | // } |
| | | // }, |
| | | // 处理多选选项 |
| | | // updateScore(selectedvalues, index, arr) { |
| | | // // ��加分数 |
| | | // let score = 0; |
| | | // selectedvalues.forEach((value) => { |
| | | // const selectedOption = arr.svyTaskTemplateTargetoptions.find( |
| | | // (option) => option.optioncontent == value |
| | | // ); |
| | | // if (selectedOption) { |
| | | // score += Number(selectedOption.score); |
| | | // } |
| | | // }); |
| | | // this.questionList[index].score = score; |
| | | // }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .questionnaire { |
| | | // background-image: url("../assets/images/chainbackground.jpg"); |
| | | background-color: #f9f9fb; |
| | | background-size: cover; |
| | | background-attachment: fixed; /* 保持背景固定 */ |
| | | background-position: center; |
| | | font-family: Arial, sans-serif; |
| | | .questionnaire-optimized { |
| | | min-height: 100vh; |
| | | margin: 0; |
| | | padding: 0; |
| | | .CONTENT { |
| | | .title { |
| | | color: #3769f3; |
| | | font-size: 22px; |
| | | font-weight: bold; |
| | | margin-bottom: 20px; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | .preview-left { |
| | | margin: 10px; |
| | | margin-bottom: 60px; |
| | | background-color: #fff; |
| | | border-radius: 5px; |
| | | // margin: 20px; |
| | | padding: 10px; |
| | | height: 100%; |
| | | // background: #ffff; |
| | | border: 1px solid #dcdfe6; |
| | | -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), |
| | | 0 0 6px 0 rgba(0, 0, 0, 0.04); |
| | | .topic-dev { |
| | | margin-bottom: 25px; |
| | | font-size: 20px !important; |
| | | .dev-text { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | } |
| | | .preview-lefts { |
| | | margin: 10px; |
| | | background-color: #fff; |
| | | border-radius: 5px; |
| | | // margin: 20px; |
| | | padding: 10px; |
| | | height: 95vh; // background: #ffff; |
| | | border: 1px solid #dcdfe6; |
| | | -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), |
| | | 0 0 6px 0 rgba(0, 0, 0, 0.04); |
| | | .topic-dev { |
| | | margin-bottom: 25px; |
| | | font-size: 20px !important; |
| | | .dev-text { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%); |
| | | padding: 20px 0; |
| | | font-family: "PingFang SC", "Microsoft YaHei", sans-serif; |
| | | } |
| | | |
| | | .red-star { |
| | | ::v-deep.el-radio__label { |
| | | position: relative; |
| | | padding-right: 10px; /* 根据需要调整 */ |
| | | } |
| | | ::v-deep.el-radio__label::after { |
| | | content: "*"; |
| | | color: red; |
| | | position: absolute; |
| | | right: -5px; /* 根据需要调整 */ |
| | | top: 0; |
| | | } |
| | | ::v-deep.el-checkbox__label { |
| | | position: relative; |
| | | padding-right: 10px; /* 根据需要调整 */ |
| | | } |
| | | ::v-deep.el-checkbox__label::after { |
| | | content: "*"; |
| | | color: red; |
| | | position: absolute; |
| | | right: -5px; /* 根据需要调整 */ |
| | | top: 0; |
| | | } |
| | | } |
| | | ::v-deep.el-checkbox-group { |
| | | font-size: 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin: 5px 0; |
| | | } |
| | | ::v-deep.el-checkbox.is-bordered + .el-checkbox.is-bordered { |
| | | margin-left: 0; |
| | | .content-wrapper { |
| | | max-width: 800px; |
| | | margin: 0 auto; |
| | | padding: 0 15px; |
| | | } |
| | | |
| | | ::v-deep.el-radio-group { |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin: 5px 0; |
| | | } |
| | | ::v-deep.el-radio.is-bordered + .el-radio.is-bordered { |
| | | /* margin-left: 10px; */ |
| | | margin-left: 0; |
| | | } |
| | | ::v-deep.custom-radio .el-radio { |
| | | margin: 2px 0; |
| | | .questionnaire-container { |
| | | background: #ffffff; |
| | | border-radius: 12px; |
| | | box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08); |
| | | padding: 30px; |
| | | margin-bottom: 30px; |
| | | } |
| | | |
| | | .radio-option { |
| | | flex: none; /* 不让选项自动填充空间 */ |
| | | white-space: nowrap; /* 防止选项文本换行 */ |
| | | margin: 0 10px; /* 设置选项左右的间隔 */ |
| | | font-size: 20px; /* 增大字体大小 */ |
| | | } |
| | | |
| | | .el-radio__label { |
| | | font-size: 20px; /* 增大标签文字大小 */ |
| | | } |
| | | .toptitle { |
| | | } |
| | | .bottom-fixed { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | .questionnaire-header { |
| | | text-align: center; |
| | | padding: 10px 0; /* 根据需要调整内边距 */ |
| | | background: #fff; /* 根据需要调整背景颜色 */ |
| | | box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1); /* 可选的阴影效果 */ |
| | | z-index: 1000; /* 确保按钮在页面最上层 */ |
| | | margin-bottom: 25px; |
| | | } |
| | | ::v-deep.el-alert--warning.is-light { |
| | | background-color: #fbf9f3; |
| | | color: #ffba00; |
| | | |
| | | .questionnaire-title { |
| | | color: #175997; |
| | | font-size: 28px; |
| | | font-weight: 700; |
| | | margin-bottom: 15px; |
| | | line-height: 1.3; |
| | | } |
| | | ::v-deep { |
| | | .el-alert__title { |
| | | font-size: 20px; |
| | | line-height: 18px; |
| | | |
| | | .questionnaire-description { |
| | | font-size: 18px; |
| | | color: #5a6c84; |
| | | line-height: 1.6; |
| | | max-width: 700px; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | .custom-divider { |
| | | margin: 25px 0; |
| | | background-color: #eaeef2; |
| | | } |
| | | |
| | | .questions-section { |
| | | margin-bottom: 40px; |
| | | } |
| | | |
| | | .question-item { |
| | | margin-bottom: 35px; |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | border: 1px solid #eaeef2; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | border-color: #d1e0f0; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | &.has-warning { |
| | | border-left: 4px solid #e6a23c; |
| | | } |
| | | } |
| | | ::v-deep.el-radio--medium.is-bordered .el-radio__label { |
| | | font-size: 20px; |
| | | |
| | | .question-stem { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | margin-bottom: 20px; |
| | | font-size: 18px; |
| | | } |
| | | ::v-deep.el-radio--medium.is-bordered { |
| | | padding: 5px 20px 0px 10px; |
| | | border-radius: 4px; |
| | | height: 36px; |
| | | |
| | | .question-number { |
| | | font-weight: 600; |
| | | color: #175997; |
| | | margin-right: 8px; |
| | | min-width: 24px; |
| | | } |
| | | ::v-deep.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label { |
| | | line-height: 17px; |
| | | font-size: 20px; |
| | | |
| | | .question-text { |
| | | flex: 1; |
| | | line-height: 1.5; |
| | | color: #2c3e50; |
| | | font-weight: 500; |
| | | } |
| | | ::v-deep.el-checkbox { |
| | | margin-right: 0px; |
| | | |
| | | .question-type-tag { |
| | | color: #3ba2f7; |
| | | font-size: 14px; |
| | | margin-left: 10px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .question-options { |
| | | margin: 15px 0; |
| | | } |
| | | |
| | | .options-group { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 12px; |
| | | } |
| | | |
| | | .option-radio, |
| | | .option-checkbox { |
| | | margin: 0; |
| | | padding: 12px 15px; |
| | | border-radius: 6px; |
| | | border: 1px solid #e0e0e0; |
| | | transition: all 0.2s; |
| | | |
| | | &:hover { |
| | | border-color: #c0c4cc; |
| | | background-color: #f8fafc; |
| | | } |
| | | } |
| | | |
| | | :deep(.option-radio .el-radio__label), |
| | | :deep(.option-checkbox .el-checkbox__label) { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .option-text { |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | .abnormal-indicator { |
| | | color: #f56c6c; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .abnormal-option { |
| | | :deep(.el-radio__inner) { |
| | | border-color: #f56c6c; |
| | | } |
| | | |
| | | :deep(.el-checkbox__inner) { |
| | | border-color: #f56c6c; |
| | | } |
| | | } |
| | | |
| | | .question-input { |
| | | margin: 15px 0; |
| | | } |
| | | |
| | | .answer-textarea { |
| | | :deep(.el-textarea__inner) { |
| | | font-size: 16px; |
| | | line-height: 1.5; |
| | | } |
| | | } |
| | | |
| | | .question-warning { |
| | | margin-top: 15px; |
| | | } |
| | | |
| | | .warning-alert { |
| | | :deep(.el-alert__title) { |
| | | font-size: 15px; |
| | | line-height: 1.4; |
| | | } |
| | | } |
| | | |
| | | .submit-section { |
| | | text-align: center; |
| | | padding: 20px 0 10px; |
| | | } |
| | | |
| | | .submit-button { |
| | | width: 100%; |
| | | max-width: 300px; |
| | | height: 50px; |
| | | font-size: 18px; |
| | | font-weight: 500; |
| | | border-radius: 8px; |
| | | background: linear-gradient(135deg, #175997 0%, #2a77c9 100%); |
| | | border: none; |
| | | box-shadow: 0 4px 12px rgba(23, 89, 151, 0.3); |
| | | transition: all 0.3s; |
| | | |
| | | &:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 6px 16px rgba(23, 89, 151, 0.4); |
| | | } |
| | | |
| | | &:active { |
| | | transform: translateY(0); |
| | | } |
| | | } |
| | | |
| | | .completion-page { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | min-height: 70vh; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .completion-content { |
| | | text-align: center; |
| | | max-width: 600px; |
| | | padding: 40px; |
| | | background: #ffffff; |
| | | border-radius: 12px; |
| | | box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08); |
| | | } |
| | | |
| | | .completion-icon { |
| | | font-size: 80px; |
| | | color: #52c41a; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .completion-title { |
| | | color: #175997; |
| | | font-size: 32px; |
| | | font-weight: 700; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .completion-message { |
| | | font-size: 18px; |
| | | color: #5a6c84; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .content-wrapper { |
| | | padding: 0 10px; |
| | | } |
| | | |
| | | .questionnaire-container { |
| | | padding: 20px 15px; |
| | | } |
| | | |
| | | .questionnaire-title { |
| | | font-size: 24px; |
| | | } |
| | | |
| | | .questionnaire-description { |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .question-stem { |
| | | font-size: 16px; |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | } |
| | | |
| | | .question-type-tag { |
| | | margin-left: 0; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | .question-item { |
| | | padding: 15px; |
| | | } |
| | | |
| | | .completion-content { |
| | | padding: 30px 20px; |
| | | } |
| | | |
| | | .completion-title { |
| | | font-size: 28px; |
| | | } |
| | | |
| | | .completion-message { |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width: 480px) { |
| | | .questionnaire-title { |
| | | font-size: 22px; |
| | | } |
| | | |
| | | .completion-title { |
| | | font-size: 24px; |
| | | } |
| | | |
| | | .completion-icon { |
| | | font-size: 60px; |
| | | } |
| | | } |
| | | </style> |