QuestionBody.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <script setup lang="ts">
  2. import { store } from "@/store/store";
  3. import { watch } from "vue";
  4. import QuestionAudio from "./QuestionAudio.vue";
  5. const props = defineProps<{ questionBody: string }>();
  6. const examQuestion = $computed(() => store.exam.currentQuestion);
  7. let questionSegements: {
  8. text: string;
  9. audios: { src: string; name: string }[];
  10. } | null = $ref(null);
  11. watch(
  12. [() => store.exam.currentQuestion?.order, () => props.questionBody],
  13. () => parseQuestion(),
  14. { immediate: true }
  15. );
  16. function parseQuestion() {
  17. let questionText = "";
  18. let capAudios: { name: string; src: string }[] = [];
  19. if (props.questionBody.includes("question-audio")) {
  20. questionText = props.questionBody.replace(
  21. /<a.*?name="([^"]*)".*?question-audio.*?url="([^"]*)".*?\/a>/g,
  22. function (_, name, src) {
  23. capAudios.push({ name, src });
  24. return "";
  25. }
  26. );
  27. } else {
  28. questionText = props.questionBody;
  29. }
  30. questionSegements = { text: questionText, audios: capAudios };
  31. }
  32. function played(name: string) {
  33. if (!store.exam.currentQuestion.limitedPlayTimes) {
  34. // 如果没有设置音频播放次数,可无限播放
  35. return false;
  36. }
  37. logger({
  38. cnl: ["server"],
  39. lvl: "debug",
  40. pgu: "AUTO",
  41. act: "开始播放音频",
  42. });
  43. // 正在播放中
  44. store.updateQuestionAudioPlayTimes(name);
  45. }
  46. function getAudioPlayedTimes(name: string) {
  47. const playedTimes =
  48. store.exam.allAudioPlayTimes.find((a) => a.audioName === name)?.times ?? 0;
  49. return Math.max(examQuestion.limitedPlayTimes - playedTimes, 0);
  50. }
  51. </script>
  52. <template>
  53. <div v-if="questionSegements" class="question-body">
  54. <div v-html="questionSegements.text" />
  55. <div
  56. v-for="(item, index) in questionSegements.audios"
  57. :key="index"
  58. style="
  59. position: relative;
  60. font-size: 18px;
  61. word-break: break-word;
  62. background-color: lightblue;
  63. border-radius: 4px;
  64. padding-left: 2px;
  65. padding-top: 2px;
  66. "
  67. class="audio-div"
  68. >
  69. <QuestionAudio
  70. :name="item.name"
  71. :src="item.src"
  72. :playCount="
  73. examQuestion.limitedPlayTimes ? getAudioPlayedTimes(item.name) : 1
  74. "
  75. @played="played(item.name)"
  76. />
  77. <span v-if="examQuestion.limitedPlayTimes">
  78. (<span class="tw-text-red-700">请点击播放</span
  79. >按钮听音作答。已播次数:<span class="tw-text-red-700">{{
  80. examQuestion.limitedPlayTimes - getAudioPlayedTimes(item.name)
  81. }}</span
  82. >,剩余播放次数:<span class="tw-text-red-700"
  83. >{{ getAudioPlayedTimes(item.name) }} </span
  84. >)
  85. </span>
  86. </div>
  87. </div>
  88. <div v-else>试题解析中...</div>
  89. </template>
  90. <style>
  91. .question-body {
  92. font-size: 18px;
  93. }
  94. .question-body img {
  95. display: inline-block;
  96. }
  97. .audio-div {
  98. display: inline-flex;
  99. align-items: center;
  100. margin-right: 4px;
  101. margin-bottom: 4px;
  102. }
  103. </style>