Jelajahi Sumber

顺序练习逻辑调整

wyling 3 tahun lalu
induk
melakukan
2b012d4212

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

@@ -20,8 +20,8 @@ interface loginRes {
  */
 export async function login(code: LocationQueryValue | LocationQueryValue[]) {
   let res = await request({
-    // url: "/login/code/test",
-    url: "/login/code",
+    url: "/login/code/test",
+    // url: "/login/code",
     method: "post",
     headers: {
       isToken: false,

+ 1 - 1
src/api/modules/pay.ts

@@ -54,7 +54,7 @@ export async function prepareOrder(dictCode: number) {
 /**
  * 获取支付配置,并调起微信支付
  */
-export async function LoopPrepareOrder() {
+export async function loopPrepareOrder() {
   // let res = await request({
   //   url: "/student/wx/prepareOrder-test",
   //   method: "post",

+ 12 - 0
src/hooks/index.ts

@@ -0,0 +1,12 @@
+import { computed } from "vue";
+import { useStore } from "vuex";
+/**
+ * 获取用户会员到期时间
+ */
+export const useExpireTime = () => {
+  const store = useStore();
+  const expireTime = computed(() => store.getters.getUserData.expireTime);
+  return {
+    expireTime,
+  };
+};

+ 0 - 1
src/route/index.ts

@@ -61,7 +61,6 @@ const router = createRouter({
     {
       path: "/",
       redirect: "/login",
-      // component:()=>import('@/views/login/index.vue')
     },
     ...aotuRoutes,
   ],

+ 106 - 72
src/views/exercise/hooks.ts

@@ -1,6 +1,7 @@
-import { ref, watch, onBeforeMount, Ref, computed } from "vue";
+import { ref, watch, onBeforeMount, Ref, computed, nextTick } from "vue";
 import * as API from "@/api";
 import { Howl, Howler } from "howler";
+import { useRoute } from "vue-router";
 
 //答题模式切换
 export function useTopicMode() {
@@ -100,112 +101,145 @@ export function useAudioSet(currentAnswerIndex: Ref<number>) {
   };
 }
 
-//题目展示逻辑
-export function useTopicShow(
-  trueNum: Ref<number>,
-  falseNum: Ref<number>,
-  idIndex: Ref<number>,
-  total: Ref<number>,
-  isJump: Ref<boolean>,
-  query: any
-) {
-  const topicList = ref([]);
-
-  //API请求接口数据
+const useSubjectList = () => {
+  const subjectList = ref<any[]>([]); //题目列表
+  const subjectTotal = ref(0); //题目总数
+  const pageNum = ref(1); //当前请求页码
+  const query = useRoute().query; //路由query参数
   onBeforeMount(async () => {
-    const topicListApiRes = await API.getTopicList({
+    const res = await API.getTopicList({
       ...query,
-      pageNum: 1,
+      pageNum: pageNum.value,
       pageSize: 10,
     });
-    topicList.value = topicListApiRes.list;
-    idIndex.value = currentAnswerIndex.value;
-    total.value = topicListApiRes.total;
+    subjectList.value = res.list;
+    subjectTotal.value = res.total;
   });
-
-  //当前题目数据
-  const currentAnswerIndex = ref(0);
-  onBeforeMount(() => {
-    watch(currentAnswerIndex, async () => {
-      if (currentAnswerIndex.value === topicList.value.length - 1) {
-        const topicListApiRes = await API.getTopicList({
-          ...query,
-          pageNum: 1,
-          pageSize: 10,
-        });
-        topicList.value = topicList.value.concat(topicListApiRes.list);
-      }
-      idIndex.value = currentAnswerIndex.value;
+  //加载下一页数据
+  const loadNewSubject = async () => {
+    if (subjectList.value.length == subjectTotal.value) return;
+    pageNum.value++;
+    const res = await API.getTopicList({
+      ...query,
+      pageNum: pageNum.value,
+      pageSize: 10,
     });
+    subjectList.value = subjectList.value.concat(res.list);
+  };
+  const currentSubjectIndex = ref(0); //当前题目下标
+  //当前题目内容
+  const currentSubject = computed(() => {
+    return subjectList.value[currentSubjectIndex.value];
   });
-  const currentAnswer: any = computed(() => {
-    return topicList.value[currentAnswerIndex.value];
-  });
+  return {
+    subjectList,
+    subjectTotal,
+    loadNewSubject,
+    currentSubject,
+    currentSubjectIndex,
+  };
+};
+
+export const useSubjectShowLogic = () => {
+  const trueNum = ref(0); //正确数量
+  const falseNum = ref(0); //错误数量
+  const isJumpNext = ref(false); //答对跳转下一题
+  const {
+    subjectList,
+    subjectTotal,
+    loadNewSubject,
+    currentSubject,
+    currentSubjectIndex,
+  } = useSubjectList(); //获取题目列表
 
-  //上一题,下一题
-  const currentAnswerIndexBack = () => {
-    if (topicList.value.length == 0) return;
-    currentAnswerIndex.value =
-      (currentAnswerIndex.value - 1 + topicList.value.length) %
-      topicList.value.length;
+  const nextBtnState = ref(true); //下一题数据请求锁
+  /**
+   * 展示下一题
+   */
+  const nextSubject = async () => {
+    if (currentSubjectIndex.value < subjectList.value.length - 1) {
+      currentSubjectIndex.value++;
+    } else {
+      if (nextBtnState.value) {
+        //禁用下一题按钮
+        nextBtnState.value = false;
+        //题目数量不足加载数据
+        await loadNewSubject();
+        //启用按钮
+        nextBtnState.value = true;
+        nextSubject()
+      }
+    }
   };
-  const currentAnswerIndexGo = () => {
-    if (topicList.value.length == 0) return;
-    currentAnswerIndex.value =
-      (currentAnswerIndex.value + 1) % topicList.value.length;
+  /**
+   * 展示上一题
+   */
+  const lastSubject = () => {
+    if (currentSubjectIndex.value > 0) {
+      currentSubjectIndex.value--;
+    }
+  };
+  /**
+   * 题目类型判断
+   * @param type
+   * @returns
+   */
+  const topicType = (type: Number) => {
+    switch (type) {
+      case 0:
+        return "判断题";
+      case 1:
+        return "单选题";
+      case 2:
+        return "多选题";
+    }
   };
 
   //选择答案后
   const userAnswerChange = () => {
-    currentAnswer.value.optsBack = currentAnswer.value.opts.map(
+    currentSubject.value.optsBack = currentSubject.value.opts.map(
       (val: String) => {
         let status;
-        if (currentAnswer.value.answer.includes(val)) {
+        if (currentSubject.value.answer.includes(val)) {
           status = 1;
         } else {
           status = 0;
         }
-        if (currentAnswer.value.userAnswer.includes(val)) {
+        if (currentSubject.value.userAnswer.includes(val)) {
           status += 2;
         }
         return { opt: val, status };
       }
     );
     if (
-      JSON.stringify(currentAnswer.value.answer) ==
-      JSON.stringify(currentAnswer.value.userAnswer)
+      JSON.stringify(currentSubject.value.answer) ==
+      JSON.stringify(currentSubject.value.userAnswer)
     ) {
       console.log("答案正确");
-      currentAnswer.value.isTrue = true;
+      currentSubject.value.isTrue = true;
       trueNum.value++;
-      if (isJump.value)
-        setTimeout(() => {
-          currentAnswerIndexGo();
-        }, 200);
+      if (isJumpNext.value) {
+        nextTick(() => {
+          nextSubject();
+        });
+      }
     } else {
       console.log("错误");
-      currentAnswer.value.isTrue = false;
+      currentSubject.value.isTrue = false;
       falseNum.value++;
     }
   };
-  const topicType = (type: Number) => {
-    switch (type) {
-      case 0:
-        return "判断题";
-      case 1:
-        return "单选题";
-      case 2:
-        return "多选题";
-    }
-  };
 
   return {
-    topicList,
-    currentAnswerIndex,
-    currentAnswer,
-    currentAnswerIndexBack,
-    currentAnswerIndexGo,
+    currentSubject,
+    currentSubjectIndex,
+    subjectTotal,
+    nextSubject,
+    lastSubject,
+    trueNum,
+    falseNum,
+    isJumpNext,
     userAnswerChange,
     topicType,
   };
-}
+};

+ 45 - 51
src/views/exercise/index.vue

@@ -30,21 +30,21 @@
   <div class="divider" />
   <!-- 题目模块 -->
   <!-- 题目预加载 -->
-  <m-empty v-if="!currentAnswer" />
+  <m-empty v-if="!currentSubject" />
   <!-- 题目预加载end -->
   <div class="problem-box" v-else>
     <!-- 题目内容 -->
     <div class="problem">
-      <span class="type">{{ topicType(currentAnswer.type) }}</span>
-      <span class="text">{{ currentAnswer.explain }}</span>
-      <img v-if="currentAnswer.image" :src="currentAnswer.image" class="img" />
+      <span class="type">{{ topicType(currentSubject.type) }}</span>
+      <span class="text">{{ currentSubject.explain }}</span>
+      <img v-if="currentSubject.image" :src="currentSubject.image" class="img" />
     </div>
     <!-- 背题模式展示 -->
     <div v-if="typeParams.answerShow">
       <div>
         <div
           class="answer-box"
-          v-for="(item, index) in currentAnswer.opts"
+          v-for="(item, index) in currentSubject.opts"
           :key="Number(index)"
         >
           <div class="choose-icon">
@@ -52,28 +52,28 @@
           </div>
           <span
             class="answer-text"
-            :class="{ true: currentAnswer.answer.includes(item) }"
+            :class="{ true: currentSubject.answer.includes(item) }"
           >
             {{ item }}
           </span>
         </div>
       </div>
       <div class="checkbox-answer">
-        答案: {{ currentAnswer.answer.toString() }}
+        答案: {{ currentSubject.answer.toString() }}
       </div>
     </div>
     <!-- 背题模式展示end -->
     <!-- 选择内容 -->
-    <div v-else-if="currentAnswer.isTrue === null">
+    <div v-else-if="currentSubject.isTrue === null">
       <!-- 单选 -->
       <van-radio-group
-        v-model="currentAnswer.userAnswer"
-        v-if="currentAnswer.type < 2"
+        v-model="currentSubject.userAnswer"
+        v-if="currentSubject.type < 2"
         @change="userAnswerChange"
         icon-size="35px"
       >
         <van-radio
-          v-for="(item, index) in currentAnswer.opts"
+          v-for="(item, index) in currentSubject.opts"
           :key="Number(index)"
           :name="item"
           class="answer"
@@ -87,9 +87,9 @@
       </van-radio-group>
       <!-- 多选 -->
       <div v-else>
-        <van-checkbox-group v-model="currentAnswer.userAnswer" icon-size="35px">
+        <van-checkbox-group v-model="currentSubject.userAnswer" icon-size="35px">
           <van-checkbox
-            v-for="(item, index) in currentAnswer.opts"
+            v-for="(item, index) in currentSubject.opts"
             :key="Number(index)"
             :name="item"
             class="answer"
@@ -105,7 +105,7 @@
           round
           type="primary"
           class="checkbox-btn"
-          :disabled="currentAnswer.userAnswer.length == 0"
+          :disabled="currentSubject.userAnswer.length == 0"
           @click="userAnswerChange"
           >确定</van-button
         >
@@ -115,7 +115,7 @@
     <div v-else>
       <div>
         <div
-          v-for="(item, index) in currentAnswer.optsBack"
+          v-for="(item, index) in currentSubject.optsBack"
           :key="Number(index)"
           class="answer-box"
         >
@@ -147,7 +147,7 @@
         </div>
       </div>
       <div class="checkbox-answer">
-        答案: {{ currentAnswer.answer.toString() }}
+        答案: {{ currentSubject.answer.toString() }}
       </div>
     </div>
     <!-- 展示答题后选择内容end -->
@@ -163,12 +163,12 @@
     </div>
     <div
       class="function-item"
-      @click="audioPlay([currentAnswer.issuemp3, currentAnswer.answermp3])"
+      @click="audioPlay([currentSubject.issuemp3, currentSubject.answermp3])"
     >
       <m-icon type="a-dtda" size="25px" />
       <span>读题+答案</span>
     </div>
-    <div class="function-item" @click="audioPlay(currentAnswer.issuemp3)">
+    <div class="function-item" @click="audioPlay(currentSubject.issuemp3)">
       <m-icon type="duti" size="25px" />
       <span>读题</span>
     </div>
@@ -183,12 +183,12 @@
     <div class="skills-box" @click.stop>
       <div class="skills">
         <div class="title">技巧讲解</div>
-        <img :src="currentAnswer.explainGif" class="img" />
+        <img :src="currentSubject.explainGif" class="img" />
         <van-divider class="divider">本题速记口诀</van-divider>
-        <div class="text">{{ currentAnswer.explainJq }}</div>
+        <div class="text">{{ currentSubject.explainJq }}</div>
         <div class="btn">
           <span @click="skillsShow = false">关闭</span>
-          <span @click="audioPlay(currentAnswer.explainMp3)">语音重播</span>
+          <span @click="audioPlay(currentSubject.explainMp3)">语音重播</span>
         </div>
       </div>
     </div>
@@ -200,11 +200,11 @@
       <div class="skills">
         <div class="title">官方解释</div>
         <div class="text">
-          {{ currentAnswer.explainJs }}
+          {{ currentSubject.explainJs }}
         </div>
         <div class="btn">
           <span @click="officialShow = false">关闭</span>
-          <span @click="audioPlay(currentAnswer.explainjsmp3)">语音重播</span>
+          <span @click="audioPlay(currentSubject.explainjsmp3)">语音重播</span>
         </div>
       </div>
     </div>
@@ -215,7 +215,7 @@
   <van-popup v-model:show="setShow" position="bottom">
     <van-cell center title="答对跳转下一题">
       <template #right-icon>
-        <van-switch v-model="isJump" size="24" />
+        <van-switch v-model="isJumpNext" size="24" />
       </template>
     </van-cell>
     <van-cell center title="答题音效提示">
@@ -227,7 +227,7 @@
   <!-- 设置操作栏end -->
   <!-- 底部操作栏 -->
   <van-tabbar placeholder route>
-    <van-tabbar-item @click="currentAnswerIndexBack"
+    <van-tabbar-item @click="lastSubject"
       >上一题
       <template #icon>
         <m-icon type="shangyiti" />
@@ -246,7 +246,7 @@
       </template>
     </van-tabbar-item>
     <van-tabbar-item
-      >{{ idIndex }}/{{ total }}
+      >{{ currentSubjectIndex+1 }}/{{ subjectTotal }}
       <template #icon>
         <m-icon type="zongtishu" />
       </template>
@@ -257,7 +257,7 @@
         <m-icon type="gfjs" />
       </template>
     </van-tabbar-item>
-    <van-tabbar-item @click="currentAnswerIndexGo"
+    <van-tabbar-item @click="nextSubject"
       >下一题
       <template #icon>
         <m-icon type="xiayiti" />
@@ -268,51 +268,45 @@
 </template>
 
 <script lang="ts" setup>
-import * as Api from "@/api";
-import { useRoute, useRouter } from "vue-router";
-import { ref, watch, computed, reactive, onBeforeMount, nextTick } from "vue";
-import { useTopicMode, useAudioSet, useTopicShow } from "./hooks";
+import {  useRouter } from "vue-router";
+import { ref } from "vue";
+import {
+  useTopicMode,
+  useAudioSet,
+  useSubjectShowLogic,
+} from "./hooks";
 const router = useRouter();
 const onClickLeft = () => {
   router.back();
 };
 
-const route = useRoute();
-
 //答题模式选择逻辑
 const { answerTypeList, currentType, typeParams } = useTopicMode();
 
-//技巧讲解
 const skillsShow = ref(false); //显示技巧讲解
-
-//官方解释
 const officialShow = ref(false); //显示官方解释
 
 //设置操作栏
 const setShow = ref(false); //显示设置栏
-const isJump = ref(false); //答对跳转下一题
 const isSoundEffect = ref(true); //答题音效
 
-//记录模块
-const trueNum = ref(0); //答对数量
-const falseNum = ref(0); //答错数量
-const idIndex = ref(0); //当前题目标志位
-const total = ref(0); //题目总数量
 
-//题目展示逻辑
 const {
-  topicList,
-  topicType,
-  currentAnswerIndex,
-  currentAnswer,
-  currentAnswerIndexBack,
-  currentAnswerIndexGo,
+  currentSubject,
+  currentSubjectIndex,
+  subjectTotal,
+  nextSubject,
+  lastSubject,
+  trueNum,
+  falseNum,
+  isJumpNext,
   userAnswerChange,
-} = useTopicShow(trueNum, falseNum, idIndex, total, isJump, route.query);
+  topicType,
+} = useSubjectShowLogic();
 
 //音频模块
 const { aotuPlayFlag, audioPlay, audioPause, aotuPlaySet, issueAudioPlay } =
-  useAudioSet(currentAnswerIndex);
+  useAudioSet(currentSubjectIndex);
 </script>
 
 <style lang="scss" scoped>

+ 5 - 4
src/views/home/children/test/components/userData.vue

@@ -15,11 +15,12 @@
   </van-nav-bar>
 </template>
 
+<script lang="ts">
+import { useExpireTime } from "@/hooks";
+</script>
+
 <script lang="ts" setup>
-import { computed } from "vue";
-import { useStore } from "vuex";
-const store = useStore();
-const expireTime = computed(() => store.getters.getUserData.expireTime);
+const { expireTime } = useExpireTime();
 </script>
 
 <style lang="scss" scoped>

+ 6 - 6
src/views/home/children/user/index.vue

@@ -50,13 +50,13 @@
   </div>
 </template>
 
+<script lang="ts">
+import { useExpireTime } from "@/hooks";
+</script>
+
 <script lang="ts" setup>
-import * as API from "@/api";
-import { computed } from "vue";
-const loopPrepareOrder = API.LoopPrepareOrder;
-import { useStore } from "vuex";
-const store = useStore();
-const expireTime = computed(() => store.getters.getUserData.expireTime);
+import { loopPrepareOrder } from "@/api";
+const { expireTime } = useExpireTime();
 </script>
 
 <style scoped lang="scss">