123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <script setup lang="ts">
- import QuestionIndex from "./QuestionIndex.vue";
- import QuestionBody from "./QuestionBody.vue";
- import QuestionViewSingle from "./QuestionViewSingle.vue";
- import { store } from "@/store/store";
- import { httpApp } from "@/plugins/axiosApp";
- import { watch } from "vue";
- import { ExamQuestion } from "@/types/student-client";
- import SplitPane from "@/components/SplitPane.vue";
- import { Star, StarOutline } from "@vicons/ionicons5";
- let parentPaneHeight = $ref(50);
- watch(
- () => store.exam.currentQuestion?.order,
- async () => {
- store.exam.currentQuestion && (await updateQuestion());
- },
- { immediate: true }
- );
- function transferWellNumber(body: string | null) {
- if (body === null) return null;
- //将题干中的三个#替换为下划线
- //将题干中的两个##数字##替换为下划线
- return body
- .replace(new RegExp("###", "g"), "_______")
- .replace(/##(\d+)##/g, function (a, b: string) {
- return "__" + parseInt(b) + "__";
- });
- }
- type QuestionUnitContent = Pick<
- ExamQuestion,
- "answerType" | "body" | "questionOptionList" | "questionType" | "rightAnswer"
- >;
- async function updateQuestion() {
- const currentExamQuestion = store.exam.currentQuestion; // 避免以后执行时,this.examQuestion换掉了
- const examRecordDataId = store.exam.examRecordDataId;
- const { order, questionId } = currentExamQuestion;
- let qContentRes: {
- body: string;
- hasAudios: boolean;
- questionUnitList: QuestionUnitContent[];
- };
- try {
- qContentRes = (
- await httpApp.get(
- `/api/ecs_oe_student/examQuestion/getQuestionContent?questionId=${questionId}&exam_record_id=${examRecordDataId}`,
- { "axios-retry": { retries: 5, retryDelay: () => 3000 } }
- )
- ).data;
- } catch (e) {
- logger({
- cnl: ["server"],
- pgu: "AUTO",
- act: "获取试题内容失败",
- possibleError: e,
- });
- return;
- }
- if (!qContentRes) return;
- // Object.assign(currentExamQuestion, qContentRes.data);
- let i = 0;
- //判断是否为套题
- const isNestedQuestion = qContentRes.questionUnitList.length > 1;
- store.exam.examQuestionList.forEach((q) => {
- if (q.questionId === questionId) {
- q.gotQuestionContent = true;
- let qc = qContentRes.questionUnitList[i++];
- q.answerType = qc.answerType;
- q.parentBody = transferWellNumber(qContentRes.body);
- q.body = transferWellNumber(qc.body)!;
- q.questionOptionList = qc.questionOptionList;
- q.questionType = qc.questionType;
- q.rightAnswer = qc.rightAnswer;
- q.isNestedQuestion = isNestedQuestion;
- }
- });
- {
- // cache next question content
- if (order < store.exam.examQuestionList.length) {
- void httpApp.get(
- "/api/ecs_oe_student/examQuestion/getQuestionContent?questionId=" +
- store.exam.examQuestionList[order].questionId +
- "&exam_record_id=" +
- examRecordDataId,
- { noErrorMessage: true }
- );
- }
- }
- // 对于某些图片套题,会导致高度计算错误,需多次nextTick
- // 从非套题进入套题时,会根据套题的内容动态调整套题的默认高度
- const parentQuestion = document.getElementsByClassName("parent-question")[0];
- if (parentQuestion) {
- parentPaneHeight =
- 5 +
- (100 * parentQuestion.clientHeight) / (document.body.clientHeight - 160);
- if (parentPaneHeight > 60) {
- parentPaneHeight = 60;
- }
- }
- }
- function toggleSign() {
- store.updateExamQuestion({
- order: store.exam.currentQuestion.order,
- isStarred: !store.exam.currentQuestion.isStarred,
- });
- }
- </script>
- <template>
- <div
- v-if="store.exam.currentQuestion.gotQuestionContent"
- class="question-container"
- >
- <div class="question-header">
- <n-icon
- :component="store.exam.currentQuestion.isStarred ? Star : StarOutline"
- class="star"
- @click="toggleSign"
- />
- <question-index />
- </div>
- <div v-if="store.exam.currentQuestion.parentBody" class="tw-flex-grow">
- <SplitPane layout="vertical">
- <template #left>
- <div class="question-view parent-question tw-h-full">
- <QuestionBody
- :questionBody="store.exam.currentQuestion.parentBody"
- />
- </div>
- </template>
- <template #right>
- <QuestionViewSingle class="tw-h-full" />
- </template>
- </SplitPane>
- </div>
- <QuestionViewSingle v-else />
- </div>
- <div v-else>试题获取中...</div>
- </template>
- <style scoped>
- .question-container {
- overflow: auto;
- display: flex;
- flex-direction: column;
- }
- .question-view {
- padding: 20px 30px;
- font-size: 16px;
- text-align: left;
- overflow: auto;
- }
- .question-header {
- display: flex;
- align-items: center;
- }
- .star {
- font-size: 36px;
- color: #ffcc00;
- align-self: flex-start;
- }
- .star:hover {
- cursor: pointer;
- }
- div.hr {
- border-bottom: 1px dashed gray;
- }
- </style>
|