survey-detail.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <template>
  2. <div class="main">
  3. <div class="content">
  4. <sub-header />
  5. <div class="left">
  6. <hero-sub-title :type="4" />
  7. <div class="detail">
  8. <div class="back" @click="$router.go(-1)"></div>
  9. <div class="info">
  10. <!-- {{ details }} -->
  11. <div>
  12. <template v-for="detail in details">
  13. <n-space
  14. vertical
  15. align="start"
  16. justify="center"
  17. style="padding: 1.25rem"
  18. >
  19. <h3>{{ detail.question }}</h3>
  20. <n-radio-group
  21. v-model:value="detail.value"
  22. name="radiogroup"
  23. v-if="
  24. detail.answer &&
  25. JSON.parse(detail.answer).answer &&
  26. Number(detail.type) === 1
  27. "
  28. >
  29. <n-space>
  30. <n-radio
  31. v-for="answer in JSON.parse(detail.answer).answer"
  32. :key="answer.val"
  33. :value="answer.val"
  34. >
  35. {{ answer.name }}
  36. </n-radio>
  37. </n-space>
  38. <n-space
  39. v-if="detail.hasDiy"
  40. align="center"
  41. style="margin-top: 15px; min-width: 450px"
  42. >
  43. <n-radio key="diy" value="diy"> 其他 </n-radio>
  44. <n-input
  45. style="min-width: 450px"
  46. round
  47. maxlength="100"
  48. show-count
  49. placeholder="请输入内容 最多100字"
  50. v-model:value="detail[`custom-${detail['id']}`]"
  51. />
  52. </n-space>
  53. </n-radio-group>
  54. <n-checkbox-group
  55. v-model:value="detail.value"
  56. v-if="
  57. detail.answer &&
  58. JSON.parse(detail.answer).answer &&
  59. Number(detail.type) === 2
  60. "
  61. >
  62. <n-space item-style="display: flex;">
  63. <n-checkbox
  64. v-for="answer in JSON.parse(detail.answer).answer"
  65. :value="answer.val"
  66. :label="answer.name"
  67. />
  68. </n-space>
  69. <n-space
  70. v-if="detail.hasDiy"
  71. align="center"
  72. style="margin-top: 15px; min-width: 450px"
  73. >
  74. <n-checkbox key="diy" value="diy"> 其他 </n-checkbox>
  75. <n-input
  76. style="min-width: 450px"
  77. round
  78. maxlength="100"
  79. show-count
  80. placeholder="请输入内容 最多100字"
  81. v-model:value="detail[`custom-${detail['id']}`]"
  82. />
  83. </n-space>
  84. </n-checkbox-group>
  85. </n-space>
  86. </template>
  87. </div>
  88. <div class="btn">
  89. <n-button
  90. class="submit"
  91. size="large"
  92. type="primary"
  93. @click="submit"
  94. >
  95. 提交
  96. </n-button>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. <side-menu />
  102. </div>
  103. </div>
  104. </template>
  105. <script setup>
  106. import { watchEffect, ref, onMounted, computed } from "vue";
  107. import { useMessage } from "naive-ui";
  108. import subHeader from "../components/subHeader";
  109. import sideMenu from "../components/sideMenu";
  110. import heroSubTitle from "../components/heroSubTitle";
  111. import { useSurveyStore } from "../store/survey";
  112. const surveyStore = useSurveyStore();
  113. const title = ref("问卷调查");
  114. const message = useMessage();
  115. const details = computed(() => surveyStore.details);
  116. const props = defineProps({
  117. id: {
  118. type: [String, Number],
  119. default: () => null,
  120. required: true,
  121. },
  122. });
  123. watchEffect(() => {
  124. document.title = title.value;
  125. if (props.id) {
  126. surveyStore.getDetail(props.id);
  127. }
  128. });
  129. const submit = async () => {
  130. const lastAnswers = details.value.map((detail) => {
  131. const mapper = {};
  132. mapper["otherDesc"] = detail.value;
  133. mapper["questionId"] = detail.id;
  134. mapper["questionnaireId"] = detail.questionnaireId;
  135. mapper["type"] = detail.type;
  136. return mapper;
  137. });
  138. console.log("lastAnswers", lastAnswers);
  139. try {
  140. await surveyStore.sendAnswer(lastAnswers);
  141. } catch (error) {
  142. message.warning("提交服务器失败!");
  143. }
  144. };
  145. </script>
  146. <style lang="scss" scoped>
  147. .detail {
  148. --main-show-case-background: #ddd5d5;
  149. --main-detail-margin: 30px;
  150. --main-detail-padding: 30px;
  151. margin: var(--main-detail-margin);
  152. margin-bottom: 0;
  153. flex: 1;
  154. border-radius: 13px;
  155. padding: 32px 48px 64px 48px;
  156. overflow-y: scroll;
  157. background-image: var(--main-detail-background-img);
  158. background-size: cover;
  159. background-position: top center;
  160. background-repeat: no-repeat;
  161. display: inline-flex;
  162. .back {
  163. background-image: url("/img/back_arrow.png");
  164. width: 120px;
  165. height: 30px;
  166. background-repeat: no-repeat;
  167. background-size: contain;
  168. margin-bottom: 12px;
  169. }
  170. .info {
  171. max-width: 1069px;
  172. margin: 0 auto;
  173. font-size: 1.25rem;
  174. display: flex;
  175. flex-direction: column;
  176. justify-content: space-between;
  177. flex: 1;
  178. :deep(.n-radio) {
  179. --n-font-size: 1.125rem !important;
  180. }
  181. .title {
  182. font-size: 30px;
  183. line-height: 60px;
  184. margin: 19.2px 0;
  185. }
  186. .text {
  187. font-weight: 400;
  188. color: #6e6e6e;
  189. line-height: 34px;
  190. font-size: 20px;
  191. }
  192. .btn {
  193. width: 100%;
  194. display: flex;
  195. justify-content: center;
  196. align-items: center;
  197. :deep(.n-button) {
  198. font-size: 1.25rem;
  199. padding: 1.5625rem 3.125rem;
  200. border-radius: 1.1875rem;
  201. }
  202. }
  203. }
  204. .show-case {
  205. max-width: 1069px;
  206. height: 547px;
  207. background: var(--main-show-case-background);
  208. }
  209. }
  210. </style>