PreviewQuestionnaire.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <div class="main_container">
  3. <TopBackNav>
  4. <template #topRight>
  5. <el-button class="button_refresh" @click="$router.go(-1)">关闭预览</el-button>
  6. </template>
  7. </TopBackNav>
  8. <div class="page_jg_20" style="flex-shrink: 0;"></div>
  9. <div class="page_item questionnaire">
  10. <!-- 问卷头部 -->
  11. <div class="questionnaire_head">
  12. <h1 class="head_title">{{ questionaireMsg?.assessmentTitle }}</h1>
  13. <p class="head_desc">{{ questionaireMsg?.assessmentIllustrate }}</p>
  14. </div>
  15. <!-- 预览内容列表 -->
  16. <ul class="question_list">
  17. <li
  18. v-for="(item, index) in questionaireMsg?.questionData"
  19. :key="item.id"
  20. class="question_card">
  21. <!-- 题目行 -->
  22. <div class="question_header">
  23. <span class="q_title" :class="{required_mark:isRequired(item)}">{{ index + 1 }}.{{ item.questionTitleName }}</span>
  24. <span class="q_type_tag">[{{ qustionTypeToName(item.questionType) }}]</span>
  25. </div>
  26. <!-- 题目内容区域 -->
  27. <div class="question_body">
  28. <QuestionTypeShow
  29. :isHorizontal="item.extraConfig.includes('isHorizontal')"
  30. :questionType="Number(item.questionType)"
  31. :questionSubOptions="item.options"
  32. :evaluationType="Number(item.evaluationType)"
  33. :questionScore="Number(item.questionScore)"
  34. ></QuestionTypeShow>
  35. </div>
  36. </li>
  37. </ul>
  38. </div>
  39. </div>
  40. </template>
  41. <script setup lang="ts">
  42. import { onMounted,ref } from 'vue';
  43. import { useRouter,useRoute } from 'vue-router';
  44. import TopBackNav from '@/components/TopBackNav.vue';
  45. import {qustionTypeToName} from '@/components/questionConfig/questionTypeList'
  46. import QuestionTypeShow from '@/components/QuestionTypeShow.vue';
  47. import {getQuestionnaireDetailApi} from '@/api/surveyManagement'
  48. const route = useRoute()
  49. // 问卷信息
  50. const questionaireMsg = ref()
  51. // 辅助函数:判断是否必填
  52. const isRequired = (item) => {
  53. return item.extraConfig && item.extraConfig.includes('required');
  54. };
  55. // 获取问卷详细信息
  56. const GetQuestionnaireDetail =async ()=>{
  57. let res = await getQuestionnaireDetailApi(route.query.id)
  58. if(res?.code == 200){
  59. const {questionData} = res.data
  60. let addedQuestionList = questionData.map(item=>{
  61. let options = item.answerData.map(opt=>{
  62. return{
  63. content: opt.answerName,
  64. score: opt.answerScore,
  65. id: opt.questionId
  66. }
  67. })
  68. let extraConfig = []
  69. if(Number(item.questionAnswerType) === 1){
  70. extraConfig.push('required')
  71. }
  72. if(Number(item.questionSortRole) === 1){
  73. extraConfig.push('isHorizontal')
  74. }
  75. return {
  76. ...item,
  77. id:item.assessmentId,
  78. extraConfig, // 是否必答 required, 是否横排 isHorizontal
  79. options
  80. }
  81. })
  82. questionaireMsg.value = {...res.data,questionData:addedQuestionList}
  83. }
  84. }
  85. onMounted( async ()=>{
  86. // 从问卷列表访问的预览
  87. if(route.query.id){
  88. await GetQuestionnaireDetail()
  89. // 从问卷编辑页访问的预览
  90. }else{
  91. // 拿取本地存储
  92. questionaireMsg.value = JSON.parse(sessionStorage.getItem('questionnaireTmpMsg') || '{}')
  93. }
  94. })
  95. </script>
  96. <style lang="scss" scoped>
  97. .questionnaire {
  98. max-width: 800px;
  99. margin: 0 auto;
  100. padding:20px 0;
  101. /* --- 头部样式 --- */
  102. .questionnaire_head {
  103. text-align: center;
  104. margin-bottom: 40px;
  105. .head_title {
  106. font-size: 24px;
  107. font-weight: bold;
  108. color: #000;
  109. margin-bottom: 16px;
  110. }
  111. .head_desc {
  112. font-size: 14px;
  113. color: #999999;
  114. line-height: 1.6;
  115. margin: 0;
  116. padding:0 60px;
  117. }
  118. }
  119. .question_list{
  120. display: flex;
  121. flex-direction: column;
  122. gap:20px;
  123. /* --- 题目卡片样式 --- */
  124. .question_card {
  125. padding: 10px 20px;
  126. .question_header {
  127. display: flex;
  128. align-items: baseline;
  129. margin-bottom: 15px;
  130. font-size: 14px;
  131. color: #000;
  132. .q_title {
  133. &.required_mark {
  134. padding-right: 6px;
  135. position: relative;
  136. &::after{
  137. position: absolute;
  138. right: 0;
  139. content:'*';
  140. width: 5px;
  141. color: #f56c6c;
  142. margin-left: 2px;
  143. font-size: 18px;
  144. }
  145. }
  146. }
  147. .q_type_tag {
  148. color: #2E64FA;
  149. font-size: 14px;
  150. margin-left: 8px;
  151. font-weight: normal;
  152. }
  153. }
  154. &:hover{
  155. box-shadow: 0px 10px 20px 0px rgba(46,100,250,0.1),
  156. 0px -10px 20px 0px rgba(46,100,250,0.1);
  157. }
  158. }
  159. }
  160. }
  161. </style>