Quellcode durchsuchen

完善问题解析

shmily1213 vor 2 Wochen
Ursprung
Commit
87c707a727

+ 2 - 2
src/api/modules/study.ts

@@ -203,6 +203,6 @@ export function correctQuestion(params: { questionid: number, remark: string })
  * @param params 
  * @returns 
  */
-export function getPracticeHistory() {
-  return flyio.get('/front/student/record/practice', {}) as Promise<ApiResponseList<PracticeHistory>>;
+export function getPracticeHistory(params: { directed: boolean }) {
+  return flyio.get('/front/student/record/practice', params) as Promise<ApiResponseList<PracticeHistory>>;
 }

+ 22 - 6
src/composables/useExam.ts

@@ -186,18 +186,32 @@ export const useExam = () => {
     // }
     return qs.answers && qs.answers.filter(item => !!item).length > 0 || !!qs.isNotKnow;
   }
-  const isCorrect = (qs: Study.ExamineeQuestion): boolean => {
+  const isQuestionCorrect = (qs: Study.ExamineeQuestion): boolean => {
     const { answers, answer1, answer2, typeId } = qs;
+    if ([EnumQuestionType.SINGLE_CHOICE, EnumQuestionType.JUDGMENT].includes(typeId)) {
+      return answer1?.includes(answers[0]);
+    } else if ([EnumQuestionType.MULTIPLE_CHOICE].includes(typeId)) {
+      return answers?.length === answer1?.length && answers?.every(item => answer1?.includes(item));
+    } else if (typeId === EnumQuestionType.SUBJECTIVE) {
+      // 主观题 A 对 B 错
+      return answers?.includes('A') && !answers?.includes('B');
+    }
     if (!answer1) {
       return false;
     }
+    return false;
+  };
+  const isOptionCorrect = (question: Study.Question, option: Study.QuestionOption) => {
+    const { answers, answer1, typeId } = question;
     if ([EnumQuestionType.SINGLE_CHOICE, EnumQuestionType.JUDGMENT].includes(typeId)) {
-      return answer1.includes(answers[0]);
+      return answer1?.includes(option.no);
     } else if ([EnumQuestionType.MULTIPLE_CHOICE].includes(typeId)) {
-      return answers.length === answer1.length && answers.every(item => answer1.includes(item));
+      return answer1?.includes(option.no);
+    } else if (typeId === EnumQuestionType.SUBJECTIVE) {
+      return answers?.includes(option.no) && option.no === 'A';
     }
     return false;
-  };
+  }
   const nextQuestion = () => {
     if (currentIndex.value >= questionList.value.length - 1) {
       return;
@@ -304,7 +318,7 @@ export const useExam = () => {
           } as Study.QuestionOption
         }) || [],
         isDone: false,
-        isCorrect: isCorrect(item)
+        isCorrect: isQuestionCorrect(item)
       } as Study.Question
     }
     const parseQuestion = (qs: Study.Question, parentIndex: number) => {
@@ -401,6 +415,8 @@ export const useExam = () => {
     setCountDownCallback,
     setQuestionList,
     changeIndex,
-    reset
+    reset,
+    isQuestionCorrect,
+    isOptionCorrect
   }
 }

+ 14 - 9
src/hooks/useTransferPage.ts

@@ -1,11 +1,14 @@
+import { Transfer } from "@/types";
 import { onLoad } from "@dcloudio/uni-app";
-export const useTransferPage = () => {
+export const useTransferPage = <T1 = any, T2 = any>() => {
   const funcMap = {
-    redirect: uni.redirectTo,
+    redirectTo: uni.redirectTo,
     reLaunch: uni.reLaunch,
-    switchTab: uni.switchTab
-  };
-  let prevData = ref<Record<string, any>>({});
+    switchTab: uni.switchTab,
+    // navigateTo: uni.navigateTo,
+    // navigateBack: uni.navigateBack
+  } as const;
+  let prevData = ref<T1>({} as T1);
   let transferResolver: ((value: unknown) => void) | null = null;
   let eventChannel: UniApp.EventChannel | null = null;
   // onMounted(() => {
@@ -17,8 +20,8 @@ export const useTransferPage = () => {
   // });
   type Callback = (() => void) | null;
   type TransferOptions = {
-    data?: Record<string, any> | null,
-    type?: string,
+    data?: T2 | null,
+    type?: Transfer.TransferType,
     bigData?: Record<string, any> | null,
     callback?: Callback
   }
@@ -85,7 +88,7 @@ export const useTransferPage = () => {
     return queryString ? `${baseUrl}?${queryString}` : baseUrl;
   }
 
-  function transferTo(url: string, { data = null, type = 'navigate', bigData = null, callback = null }: TransferOptions = {}) {
+  function transferTo(url: string, { data = null, type = 'navigateTo', bigData = null, callback = null }: TransferOptions = {}) {
     return new Promise((resolve, reject) => {
       transferResolver = resolve;
       if (bigData) {
@@ -95,7 +98,8 @@ export const useTransferPage = () => {
         uni.removeStorageSync('transferBigData');
       }
       const nextUrl = getTransferUrl(url, data, bigData);
-      if (type === 'navigate') {
+      // 单独处理,函数签名不一样
+      if (type === 'navigateTo') {
         uni.navigateTo({
           url: nextUrl,
           events: {
@@ -114,6 +118,7 @@ export const useTransferPage = () => {
         });
       } else {
         const routeFunc = funcMap[type as keyof typeof funcMap];
+        console.log(routeFunc, type)
         routeFunc({
           url: nextUrl,
           fail: (err) => {

+ 4 - 3
src/pagesMain/pages/index/components/index-banner.vue

@@ -17,12 +17,13 @@
 import { useTransferPage } from '@/hooks/useTransferPage';
 const { transferTo } = useTransferPage();
 import { useUserStore } from '@/store/userStore';
+import { Transfer } from '@/types';
 const userStore = useUserStore();
 type MenuItem = {
   name: string;
   icon: string;
   pageUrl: string;
-  navigateType?: string;
+  navigateType?: Transfer.TransferType;
   noLogin?: boolean
 }
 const menus: MenuItem[] = [
@@ -77,12 +78,12 @@ const navigateTo = async (item: MenuItem) => {
     const isLogin = await userStore.checkLogin();
     if (isLogin) {
       transferTo(pageUrl, {
-        type: navigateType || 'navigate',
+        type: navigateType || 'navigateTo',
       });
     };
   } else {
     transferTo(pageUrl, {
-      type: navigateType || 'navigate',
+      type: navigateType || 'navigateTo',
     });
   }
 }

+ 18 - 13
src/pagesStudy/pages/exam-start/components/question-item.vue

@@ -19,7 +19,7 @@
             </view>
           </template>
           <view v-else>
-            <uv-icon v-if="isOptionCorrect(option)" name="checkmark-circle-fill" color="#2CC6A0" size="22" />
+            <uv-icon v-if="isOptionCorrect(question, option)" name="checkmark-circle-fill" color="#2CC6A0" size="22" />
             <uv-icon v-else-if="isOptionIncorrect(option)" name="close-circle-fill" color="#FF5B5C" size="22" />
             <view v-else class="question-option-index">{{ option.no }}</view>
           </view>
@@ -52,17 +52,20 @@
             class="absolute top-0 left-1/2 -translate-x-1/2 w-222 h-64" />
           <ie-image v-else src="/pagesStudy/static/image/icon-answer-incorrect.png"
             class="absolute top-0 left-1/2 -translate-x-1/2 w-240 h-64" />
-          <view class="flex-1">
+          <view v-if="!isOnlySubjective" class="flex-1">
             <view class="text-34 text-[#2CC6A0] font-bold">{{ question.answer1 }}</view>
             <view class="mt-4 text-26">正确答案</view>
           </view>
           <view class="h-40 w-1 bg-back"></view>
-          <view class="flex-1">
+          <view v-if="!isOnlySubjective" class="flex-1">
             <view class="text-34 font-bold" :class="[question.isCorrect ? 'text-[#2CC6A0]' : 'text-[#FF5B5C]']">
               {{ question.answers.join('') || (question.isNotKnow ? '不会' : '未答') }}
             </view>
             <view class="mt-4 text-26">我的答案</view>
           </view>
+          <view v-if="isOnlySubjective" class="text-left mt-10 px-20">
+            <uv-parse :content="'正确答案:' + question.answer2"></uv-parse>
+          </view>
         </view>
       </template>
       <view v-if="(readonly && question.parse) || (!readonly && question.showParse)" class="mt-40">
@@ -95,7 +98,7 @@ import { Study } from '@/types';
 import { useExam } from '@/composables/useExam';
 import { EnumQuestionType } from '@/common/enum';
 import { NEXT_QUESTION, PREV_QUESTION, NEXT_QUESTION_QUICKLY, PREV_QUESTION_QUICKLY, SHOW_SUBMIT_CONFIRM, IS_ALL_DONE } from '@/types/injectionSymbols';
-const { questionTypeDesc } = useExam();
+const { questionTypeDesc, isOptionCorrect } = useExam();
 const props = defineProps<{
   question: Study.Question;
   readonly?: boolean;
@@ -154,15 +157,17 @@ const getStyleClass = (option: Study.QuestionOption) => {
   // console.log(props.question, option)
   return customClass;
 };
-const isOptionCorrect = (option: Study.QuestionOption) => {
-  const { answers, answer1, answer2 } = props.question;
-  if ([EnumQuestionType.SINGLE_CHOICE, EnumQuestionType.JUDGMENT].includes(props.question.typeId)) {
-    return answer1.includes(option.no);
-  } else if ([EnumQuestionType.MULTIPLE_CHOICE].includes(props.question.typeId)) {
-    return answer1.includes(option.no);
-  }
-  return false;
-}
+// const isOptionCorrect = (option: Study.QuestionOption) => {
+//   const { answers, answer1, answer2 } = props.question;
+//   if ([EnumQuestionType.SINGLE_CHOICE, EnumQuestionType.JUDGMENT].includes(props.question.typeId)) {
+//     return answer1.includes(option.no);
+//   } else if ([EnumQuestionType.MULTIPLE_CHOICE].includes(props.question.typeId)) {
+//     return answer1.includes(option.no);
+//   } else if (props.question.typeId === EnumQuestionType.SUBJECTIVE) {
+//     return answers.includes(option.no);
+//   }
+//   return false;
+// }
 const isOptionIncorrect = (option: Study.QuestionOption) => {
   const { answers, answer1 } = props.question;
   return answers.includes(option.no) && !answer1.includes(option.no);

+ 25 - 6
src/pagesStudy/pages/exam-start/exam-start.vue

@@ -123,7 +123,7 @@ import { NEXT_QUESTION, PREV_QUESTION, NEXT_QUESTION_QUICKLY, PREV_QUESTION_QUIC
 
 const userStore = useUserStore();
 // import { Examinee, ExamPaper, ExamPaperSubmit } from '@/types/study';
-const { prevData, transferBack } = useTransferPage();
+const { prevData, transferBack, transferTo } = useTransferPage();
 const { setQuestionList, questionList, groupedQuestionList, questionTypeDesc,
   currentIndex, totalCount, virtualCurrentIndex, virtualTotalCount, subQuestionIndex, setSubQuestionIndex,
   doneCount,
@@ -384,11 +384,27 @@ const handleSubmit = (tempSave: boolean = false) => {
     } as Study.ExamPaperSubmit;
     console.log(params, 123)
     commitExamineePaper(params);
-    setTimeout(async () => {
-      uni.$ie.hideLoading();
-      await nextTick();
-      uni.navigateBack();
-    }, isExam.value && !tempSave ? 2500 : 0);
+    if (isExam.value) {
+      setTimeout(async () => {
+        uni.$ie.hideLoading();
+        await nextTick();
+        uni.navigateBack();
+      }, !tempSave ? 2500 : 0);
+    } else {
+      setTimeout(async () => {
+        uni.$ie.hideLoading();
+        await nextTick();
+        transferTo('/pagesStudy/pages/knowledge-practice-detail/knowledge-practice-detail', {
+          data: {
+            examineeId: examineeId.value,
+            name: prevData.value.practiceInfo.name,
+            directed: prevData.value.practiceInfo.directed
+          },
+          type: 'redirectTo'
+        });
+      }, !tempSave ? 2500 : 0);
+    }
+
   }, 1000);
 }
 
@@ -489,8 +505,10 @@ const combinePaperData = async (examinee: Study.Examinee, paperType: EnumPaperTy
     setQuestionList(paperData.value.questions);
     setDuration(examinee.duration || 0);
     await nextTick();
+    // TODO:子题跳转
     const questionIndex = prevData.value.questionId ? paperData.value.questions.findIndex(item => item.id === prevData.value.questionId) : 0;
     changeIndex(questionIndex);
+    console.log(groupedQuestionList.value, 123)
     await new Promise(resolve => setTimeout(resolve, 50));
     await nextTick();
     isReady.value = true;
@@ -528,6 +546,7 @@ const loadData = async () => {
   }
 };
 onLoad(() => {
+  console.log(prevData.value)
   loadData();
 });
 </script>

+ 19 - 11
src/pagesStudy/pages/knowledge-practice-detail/knowledge-practice-detail.vue

@@ -6,7 +6,7 @@
         <rate-chart :value="rightRate" />
         <view class="h-1 bg-[#E6E6E6] my-20"></view>
         <view>
-          <view v-if="prevData.isDirected" class="my-20 flex items-center justify-between text-24">
+          <view v-if="prevData.directed" class="my-20 flex items-center justify-between text-24">
             <ie-image src="/pagesStudy/static/image/icon-house.png" custom-class="w-24 h-24" mode="aspectFill" />
             <text class="ml-10 text-fore-light flex-1">练习科目</text>
             <text class="text-fore-title">{{ examineeData.collegeName }}-{{ examineeData.majorName }}</text>
@@ -41,10 +41,10 @@
 import RateChart from '@/pagesStudy/pages/simulation-analysis/components/rate-chart.vue';
 import ExamStat from '@/pagesStudy/pages/simulation-analysis/components/exam-stat.vue';
 import { useTransferPage } from '@/hooks/useTransferPage';
-import { Study } from '@/types';
+import { Study, Transfer } from '@/types';
 import { getExamineeResult } from '@/api/modules/study';
 import { EnumPaperType } from '@/common/enum';
-const { prevData, transferTo } = useTransferPage();
+const { prevData, transferTo } = useTransferPage<Transfer.PracticeResult, {}>();
 
 
 const rightRate = computed(() => {
@@ -56,7 +56,8 @@ const paperName = computed(() => {
 });
 const examineeData = ref<Study.Examinee>({} as Study.Examinee);
 const pageTitle = computed(() => {
-  return prevData.value.isDirected ? '定向练习结果' : '全量练习结果';
+  // return prevData.value.directed ? '定向练习结果' : '全量练习结果';
+  return '练习结果';
 });
 const formatTime = (time: number) => {
   if (!time) {
@@ -87,12 +88,18 @@ const handleDetail = (item: Study.ExamineeQuestion) => {
   });
 }
 const handleStartPractice = () => {
-  console.log(examineeData)
-  // transferTo('/pagesStudy/pages/simulation-analysis/simulation-analysis', {
-  //   data: {
-  //     examineeId: examineeData.value.id
-  //   }
-  // });
+  const { knowledgeId } = examineeData.value;
+  transferTo('/pagesStudy/pages/exam-start/exam-start', {
+    data: {
+      name: paperName.value,
+      paperType: EnumPaperType.PRACTICE,
+      practiceInfo: {
+        name: prevData.value.name,
+        relateId: knowledgeId,
+        directed: prevData.value.directed ? 1 : 0
+      },
+    }
+  });
 }
 const handleViewAnalysis = () => {
   transferTo('/pagesStudy/pages/exam-start/exam-start', {
@@ -109,7 +116,7 @@ const handleViewAnalysis = () => {
 const loadData = async () => {
   uni.$ie.showLoading();
   try {
-    const res = await getExamineeResult(prevData.value.id);
+    const res = await getExamineeResult(prevData.value.examineeId);
     examineeData.value = res.data;
     console.log(examineeData.value)
   } finally {
@@ -117,6 +124,7 @@ const loadData = async () => {
   }
 }
 onLoad(() => {
+  console.log(prevData.value)
   loadData();
 });
 </script>

+ 8 - 5
src/pagesStudy/pages/knowledge-practice-history/knowledge-practice-history.vue

@@ -27,26 +27,28 @@ import { useNavbar } from '@/hooks/useNavbar';
 import { useTransferPage } from '@/hooks/useTransferPage';
 import { getPracticeHistory } from '@/api/modules/study';
 import { Study } from '@/types';
-const { transferTo } = useTransferPage();
+import { Transfer } from '@/types';
+const { prevData, transferTo } = useTransferPage<{}, Transfer.PracticeResult>();
 const { baseStickyTop } = useNavbar();
 const historyList = ref<Study.PracticeHistory[]>([]);
 const handleViewHistory = (value: Study.PracticeHistory) => {
   transferTo('/pagesStudy/pages/knowledge-practice-detail/knowledge-practice-detail', {
     data: {
-      id: value.examineeId,
+      examineeId: value.examineeId,
       name: value.paperName,
-      isDirected: value.directed === 1
+      directed: value.directed === 1
     }
   });
 }
 const loadData = async () => {
   uni.$ie.showLoading();
   try {
-    const { rows } = await getPracticeHistory();
+    const { rows } = await getPracticeHistory({
+      directed: true
+    });
     historyList.value = rows.map(item => {
       return {
         ...item,
-        isDirected: item.directed === 1,
         endTime: uni.$uv.timeFormat(item.endTime, 'yyyy-mm-dd hh:MM:ss')
       } as Study.PracticeHistory;
     });
@@ -55,6 +57,7 @@ const loadData = async () => {
   }
 }
 onLoad(() => {
+  console.log(prevData.value)
   loadData();
 });
 </script>

+ 5 - 1
src/pagesStudy/pages/knowledge-practice/knowledge-practice.vue

@@ -46,7 +46,11 @@ const handleChangeTab = (item: any) => {
   currentSubjectIndex.value = item.index;
 }
 const handleViewHistory = () => {
-  transferTo('/pagesStudy/pages/knowledge-practice-history/knowledge-practice-history');
+  transferTo('/pagesStudy/pages/knowledge-practice-history/knowledge-practice-history', {
+    data: {
+      directed: prevData.value.directed
+    }
+  });
 }
 const loadKnowledgeList = async () => {
   if (!currentSubjectId.value) {

+ 6 - 12
src/pagesStudy/pages/simulation-analysis/components/exam-stat.vue

@@ -49,8 +49,10 @@
 <script lang="ts" setup>
 import { EnumPaperType, EnumQuestionType } from '@/common/enum';
 import { useTransferPage } from '@/hooks/useTransferPage';
+import { useExam } from '@/composables/useExam';
 import { Study } from '@/types';
 const { transferTo } = useTransferPage();
+const { isQuestionCorrect } = useExam();
 const emit = defineEmits<{
   (e: 'detail', item: Study.ExamineeQuestion): void;
 }>();
@@ -75,7 +77,7 @@ const totalQuestions = computed(() => {
 const filterTypes = ref<('correct' | 'incorrect' | 'unanswered')[]>(['correct', 'incorrect', 'unanswered']);
 const questionList = computed(() => {
   const list: QuestionItem[] = [];
-  let offset = 0 ;
+  let offset = 0;
   (props.data.questions || []).forEach((item, index) => {
     if (item.subQuestions && item.subQuestions.length > 0) {
       item.subQuestions.forEach((subItem, subIndex) => {
@@ -83,7 +85,7 @@ const questionList = computed(() => {
         list.push({
           ...subItem,
           originalIndex: index + subIndex + 1, // 保存原始序号
-          isRight: judgeCorrect(subItem),
+          isRight: isQuestionCorrect(subItem),
           isNotAnswer: !subItem.answers.filter(item => item !== ' ').length
         });
       });
@@ -91,7 +93,7 @@ const questionList = computed(() => {
       list.push({
         ...item,
         originalIndex: index + offset + 1, // 保存原始序号
-        isRight: judgeCorrect(item),
+        isRight: isQuestionCorrect(item),
         isNotAnswer: !item.answers.filter(item => item !== ' ').length
       });
     }
@@ -112,15 +114,7 @@ const questionList = computed(() => {
     return false;
   });
 });
-const judgeCorrect = (qs: Study.ExamineeQuestion) => {
-  if (qs.typeId === EnumQuestionType.SINGLE_CHOICE
-    || qs.typeId === EnumQuestionType.JUDGMENT) {
-    return qs.answers.includes(qs.answer1);
-  } else if (qs.typeId === EnumQuestionType.MULTIPLE_CHOICE) {
-    const rightAnswers = qs.answer1.split('').filter(item => item !== ' ');
-    return rightAnswers.length === qs.answers.length && rightAnswers.every(item => qs.answers.includes(item));
-  }
-}
+
 const handleFilter = (type: 'correct' | 'incorrect' | 'unanswered') => {
   if (filterTypes.value.includes(type)) {
     filterTypes.value = filterTypes.value.filter(item => item !== type);

+ 2 - 1
src/types/index.ts

@@ -1,6 +1,7 @@
 import * as Study from "./study";
 import * as User from "./user";
 import * as News from "./news";
+import * as Transfer from "./transfer";
 import { VipCardInfo } from "./user";
 
 /// 接口响应
@@ -110,4 +111,4 @@ export interface ConfigItem {
 
 
 
-export { Study, User, News };
+export { Study, User, News, Transfer };

+ 7 - 0
src/types/transfer.ts

@@ -0,0 +1,7 @@
+export type TransferType = 'redirectTo' | 'reLaunch' | 'switchTab' | 'navigateTo' | 'navigateBack';
+
+export interface PracticeResult {
+  examineeId: number;
+  name: string;
+  directed: boolean;
+}