shmily1213 1 miesiąc temu
rodzic
commit
27185ebbf4

+ 5 - 0
src/composables/useExam.ts

@@ -200,6 +200,10 @@ export const useExam = () => {
   const setCountDownCallback = (callback: () => void) => {
     countDownCallback.value = callback;
   }
+  const setDuration = (duration: number) => {
+    examDuration.value = duration;
+    practiceDuration.value = duration;
+  }
   const setQuestionList = (list: Study.ApiQuestion[]) => {
     const orders = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
     // 数据预处理
@@ -272,6 +276,7 @@ export const useExam = () => {
     formatPracticeDuration,
     startPracticeDuration,
     stopPracticeDuration,
+    setDuration,
     startExamDuration,
     stopExamDuration,
     setExamDuration,

+ 1 - 1
src/pagesStudy/pages/index/compoentns/index-banner.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="mx-30 mt-40">
-    <ie-image :is-oss="true" src="/banner/index-banner-3.png" :round="10" customClass="w-full h-264" mode="widthFix" />
+    <ie-image :is-oss="true" src="/banner/index-banner-4.png" :round="10" customClass="w-full h-178" mode="widthFix" />
     <view class="mt-32 flex gap-x-30">
       <view class="flex-1 rounded-12 bg-[#F0FFF2] py-40 pl-22 pr-8 flex items-center" @click="handleOpenPlan">
         <!-- /pagesStudy/pages/study-plan-edit/study-plan-edit -->

+ 42 - 20
src/pagesStudy/pages/index/index.vue

@@ -12,40 +12,51 @@
         </view>
       </template>
     </ie-navbar>
+    <view class="mx-30 mt-20 flex items-center bg-[#E3F4FA] rounded-8 py-16 px-16 gap-x-40">
+      <view class="text-24 text-[#34B0D7] flex-1">
+        <text v-if="!hasDirectedSchool">你还未开启定向学习,快来设置吧!</text>
+        <view v-else class="flex items-center">
+          <text class="flex-shrink-0">定向:</text>
+          <text class="min-w-1 ellipsis-1">{{ firstDirectedSchool.universityName }}</text>
+          <uv-icon name="arrow-right" size="14" color="#0DACF5"></uv-icon>
+          <text class="flex-shrink-0">{{ firstDirectedSchool.majorName }}</text>
+        </view>
+      </view>
+      <view class="text-24 text-white bg-gradient-to-r from-[#26C5F7] to-[#0DACF5] rounded-full px-18 py-6"
+        @click="handleSetting">{{ hasDirectedSchool ? '已开启' : '去开启' }}</view>
+    </view>
     <view class="mx-30 mt-20">
       <view class="flex items-center gap-x-28">
-        <view class="bg-[#EBF9FF] border-2 border-[#E6F7FF] flex-1 rounded-15 relative overflow-hidden">
-          <view class="h-70 z-1 relative"></view>
-          <view class="ml-30 mb-32 z-1 relative">
-            <view class="text-28 text-fore-title font-bold">全量刷题</view>
-            <view class="mt-8 text-24 text-fore-tip">根据知识点系统练习</view>
-            <view
-              class="mt-32 w-200 h-56 flex items-center justify-center rounded-full text-26 text-white bg-gradient-to-r from-[#91E0FE] to-[#16AFF5]"
+        <view class="bg-gradient-to-r from-[#0088FE] to-[#31A0FC] flex-1 rounded-15 relative overflow-hidden">
+          <!-- <view class="h-70 z-1 relative"></view> -->
+          <view class="mt-30 p-30 z-1 relative">
+            <view class="text-30 text-white font-bold">全量刷题</view>
+            <view class="mt-8 text-24 text-white">全面刷题,高效备考</view>
+            <view class="mt-32 w-200 h-56 flex items-center justify-center rounded-full text-26 text-primary bg-white"
               @click="handlePracticeAll">
               开始练习
             </view>
           </view>
-          <ie-image :is-oss="true" src="/study-bg1.png" custom-class="absolute bottom-0 right-0 w-212 h-212 z-0"
-            mode="heightFix" />
+          <ie-image :is-oss="true" src="/study-bg13.png" custom-class="absolute bottom-0 left-0 w-full h-full z-0"
+            mode="aspectFill" />
         </view>
-        <view class="bg-[#FFFBEB] border-2 border-[#FEF6DA] flex-1 rounded-15 relative overflow-hidden">
-          <view class="mx-30 h-70 z-1 relative flex items-center gap-x-6" @click="handleSetting">
+        <view class="bg-gradient-to-r from-[#32B5FD] to-[#79DCFD] flex-1 rounded-15 relative overflow-hidden">
+          <!-- <view class="mx-30 h-70 z-1 relative flex items-center gap-x-6" @click="handleSetting">
             <view class="w-fit ellipsis-1 text-[#F59E0B]">
               <text class="text-24 ">{{ firstDirectedSchool.universityName || '请选择定向院校' }}</text>
             </view>
             <ie-image src="/pagesStudy/static/image/icon-edit-pen.png" custom-class="w-28 h-28" mode="aspectFill" />
-          </view>
-          <view class="ml-30 mb-32 z-1 relative">
-            <view class="text-28 text-fore-title font-bold">专项刷题</view>
-            <view class="mt-8 text-24 text-fore-tip">结合考纲考点精准练习</view>
-            <view
-              class="mt-32 w-200 h-56 flex items-center justify-center rounded-full text-26 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F]"
+          </view> -->
+          <view class="mt-30 p-30 z-1 relative">
+            <view class="text-30 text-white font-bold">定向刷题</view>
+            <view class="mt-8 text-24 text-white">紧扣考纲,精准练习</view>
+            <view class="mt-32 w-200 h-56 flex items-center justify-center rounded-full text-26 text-primary bg-white"
               @click="handlePracticeDirected">
               开始练习
             </view>
           </view>
-          <ie-image :is-oss="true" src="/study-bg2.png" custom-class="absolute bottom-0 right-0 w-212 h-212 z-0"
-            mode="heightFix" />
+          <ie-image :is-oss="true" src="/study-bg13.png" custom-class="absolute bottom-0 left-0 w-full h-full z-0"
+            mode="aspectFill" />
         </view>
       </view>
     </view>
@@ -92,7 +103,18 @@ const handlePracticeDirected = () => {
     }
   });
 }
-const handleSetting = () => {
+const handleSetting = async () => {
+  if (hasDirectedSchool.value) {
+    const notice = firstDirectedSchool.value.notice;
+    if (notice) {
+      await uni.$ie.showModal({
+        title: '提示',
+        content: notice,
+        showCancel: false,
+        confirmText: '知道了'
+      });
+    }
+  }
   transferTo('/pagesStudy/pages/targeted-setting/targeted-setting');
 }
 const loadData = async () => {

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

@@ -105,7 +105,7 @@ const { prevData, transferBack } = useTransferPage();
 const { setQuestionList, questionList, groupedQuestionList, stateQuestionList, questionTypeDesc, favoriteList, notKnowList, markList, currentIndex,
   totalCount, doneCount, notDoneCount, notKnowCount, markCount, isAllDone, nextQuestion, prevQuestion, nextQuestionQuickly, prevQuestionQuickly, swiperDuration,
   formatPracticeDuration, formatExamDuration, practiceDuration, startPracticeDuration, stopPracticeDuration,
-  examDuration, startExamDuration, stopExamDuration, setExamDuration, setCountDownCallback, changeIndex, reset } = useExam();
+  examDuration, startExamDuration, stopExamDuration, setExamDuration, setCountDownCallback, changeIndex, setDuration, reset } = useExam();
 
 provide(NEXT_QUESTION, nextQuestion);
 provide(PREV_QUESTION, prevQuestion);
@@ -175,9 +175,8 @@ const handleFavorite = async () => {
     currentQuestion.value.isFavorite = false;
     uni.$ie.showToast('取消收藏成功');
   }
-  
-  // currentQuestion.value.isFavorite = !currentQuestion.value.isFavorite;
 };
+
 const handleMark = () => {
   currentQuestion.value.isMark = !currentQuestion.value.isMark;
 };
@@ -299,7 +298,6 @@ const handleSubmit = (tempSave: boolean = false) => {
 }
 
 const handleUpdateQuestion = (question: Study.Question) => {
-  // questionList.value[currentIndex.value] = question;
   if (currentIndex.value === questionList.value.length - 1) {
     autoSubmit();
   }
@@ -318,7 +316,7 @@ const restoreQuestion = (savedQuestion: Study.ExamineeQuestion[], fullQuestion:
     const savedQs = savedQuestion.find(q => q.id === item.id);
     if (savedQs) {
       if (savedQs.answers) {
-        item.answers = savedQs.answers.filter(ans => ans.trim()); 
+        item.answers = savedQs.answers.filter(ans => ans.trim());
       }
       item.isMark = savedQs.isMark;
       item.isFavorite = savedQs.isFavorite;
@@ -347,13 +345,12 @@ const loadData = async () => {
       type: prevData.value.paperType,
       id: data.paperId
     });
-    // const savedQuestionList = res.data.questions;
+
     uni.$ie.hideLoading();
     paperData.value = res.data;
     paperData.value.questions = restoreQuestion(data.questions, res.data.questions);
-    setQuestionList(paperData.value.questions)
-    console.log(123, paperData.value.questions)
-    // loadExamData(prevData.value.paperType, data.paperId);
+    setQuestionList(paperData.value.questions);
+    setDuration(data.duration || 0);
   }
   isReady.value = true;
   setCountDownCallback(() => {

+ 25 - 13
src/pagesStudy/pages/study-plan/components/page-calendar.vue

@@ -21,19 +21,18 @@
 <script lang="ts" setup>
 import { STUDY_PLAN_STATS, STUDY_PLAN } from '@/types/injectionSymbols';
 import { Study } from '@/types';
-const studyPlanRef = inject(STUDY_PLAN);
-const studyPlanStatsRef = inject(STUDY_PLAN_STATS);
+const studyPlan = inject(STUDY_PLAN) || ref({} as Study.StudyPlan);
+const studyPlanStats = inject(STUDY_PLAN_STATS) || ref({} as Study.StudyPlanStats);
 
 let selectDate = ref(uni.$uv.timeFormat(new Date(), 'yyyy-mm-dd'));
 const stat = computed(() => {
-  const studyPlan = studyPlanRef?.value;
   let todayData = {} as Study.StudyStats;
-  const questionCnt = studyPlan?.questionCnt;
-  const videoTime = studyPlan?.videoTime;
-  if (studyPlanStatsRef?.value?.studyList?.length) {
-    const index = studyPlanStatsRef?.value?.studyList.findIndex(item => item.date === selectDate.value);
+  const questionCnt = studyPlan.value.questionCnt;
+  const videoTime = studyPlan.value.videoTime;
+  if (studyPlanStats.value?.studyList?.length) {
+    const index = studyPlanStats?.value?.studyList.findIndex(item => item.date === selectDate.value);
     if (index !== -1) {
-      todayData = studyPlanStatsRef?.value?.studyList[index].data;
+      todayData = studyPlanStats.value?.studyList[index].data;
     } else {
       todayData = {} as Study.StudyStats;
     }
@@ -66,13 +65,26 @@ const stat = computed(() => {
     }
   ]
 });
-const selected = ref([])
+const selected = computed(() => {
+  if (!studyPlanStats.value?.studyList?.length) {
+    return [];
+  }
+  return studyPlanStats.value?.studyList.map(item => {
+    const { date, data } = item;
+    return {
+      date: date,
+      info: {
+        isFinish: data.questionCnt >= data.questionPlan && data.videoTime >= data.videoPlan
+      }
+    }
+  });
+});
+
 const endDate = ref('')
 const todayPlanFinish = computed(() => {
-  const studyPlan = studyPlanRef?.value;
-  const todayData = studyPlanStatsRef?.value?.today;
-  const questionCnt = studyPlan?.questionCnt;
-  const videoTime = studyPlan?.videoTime;
+  const todayData = studyPlanStats?.value?.today;
+  const questionCnt = studyPlan.value.questionCnt;
+  const videoTime = studyPlan.value.videoTime;
 
   if (
     getValue(todayData?.questionCnt) >= getValue(questionCnt) &&

+ 57 - 47
src/pagesStudy/pages/targeted-setting/targeted-setting.vue

@@ -15,49 +15,52 @@
         <ie-image src="/pagesStudy/static/image/icon-edit-pen.png" custom-class="w-24 h-24" mode="aspectFill" />
       </view> -->
     </view>
-    <view v-if="hasDirectedSchool" class="px-30">
-      <l-drag ref="dragRef" :list="directedSchoolList" :column="1" gridHeight="104px" :touchHandle="touchHandle" ghost
-        handle @change="changeSort">
-        <!-- // 每一项的插槽 grid 的 content 您传入的数据 -->
-        <template #grid="{ active, content, index }">
-          <!-- // grid.active 是否为当前拖拽项目 根据自己需要写样式 -->
-          <view class="bg-white rounded-10 py-28 pl-30 pr-20 relative flex items-center gap-x-16 mb-20"
-            :class="{ 'border border-solid border-primary': active }">
-            <view class="w-44 text-64 text-primary font-bold absolute top-6 left-14 italic leading-[1] opacity-30 z-1">
-              {{ index + 1 }}
-            </view>
-            <view slot="handle" @touchstart="touchHandle = true" @touchend="touchHandle = false">
-              <ie-image src="/pagesStudy/static/image/icon-drag.png" custom-class="w-46 h-46" mode="aspectFill" />
-            </view>
-            <view class="flex-1 min-w-1 flex items-center gap-x-20">
-              <ie-image :src="content.universityLogo" custom-class="w-96 h-96" mode="aspectFill" />
-              <view class="flex-1 min-w-1">
-                <view class="text-28 text-fore-title font-bold">{{ content.universityName }}</view>
-                <view class="mt-8 w-fit text-20 text-primary border border-solid border-primary rounded-4 px-10 py-4">
-                  {{ content.majorName }}
-                </view>
-                <view class="flex items-center justify-between text-20">
-                  <view class="mt-8  text-fore-light">{{ content.majorAncestors }}</view>
-                  <view v-if="index === 0"
-                    class="flex items-center gap-x-4 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F] rounded-full px-12 py-4">
-                    <ie-image src="/pagesStudy/static/image/icon-check-white.png" custom-class="w-24 h-24" />
-                    <text>定向学习中</text>
+    <view class="relative">
+      <view class="px-30">
+        <l-drag ref="dragRef" :list="sortList" :column="1" gridHeight="104px" :touchHandle="touchHandle" ghost handle
+          @change="changeSort">
+          <!-- // 每一项的插槽 grid 的 content 您传入的数据 -->
+          <template #grid="{ active, content, index }">
+            <!-- // grid.active 是否为当前拖拽项目 根据自己需要写样式 -->
+            <view class="bg-white rounded-10 py-28 pl-30 pr-20 relative flex items-center gap-x-16 mb-20"
+              :class="{ 'border border-solid border-primary': active }">
+              <view
+                class="w-44 text-64 text-primary font-bold absolute top-6 left-14 italic leading-[1] opacity-30 z-1">
+                {{ index + 1 }}
+              </view>
+              <view slot="handle" @touchstart="touchHandle = true" @touchend="touchHandle = false">
+                <ie-image src="/pagesStudy/static/image/icon-drag.png" custom-class="w-46 h-46" mode="aspectFill" />
+              </view>
+              <view class="flex-1 min-w-1 flex items-center gap-x-20">
+                <ie-image :src="content.universityLogo" custom-class="w-96 h-96" mode="aspectFill" />
+                <view class="flex-1 min-w-1">
+                  <view class="text-28 text-fore-title font-bold">{{ content.universityName }}</view>
+                  <view class="mt-8 w-fit text-20 text-primary border border-solid border-primary rounded-4 px-10 py-4">
+                    {{ content.majorName }}
                   </view>
-                  <view v-else class="flex items-center gap-x-4 text-22 text-primary px-12 py-4"
-                    @click="handleSetDirectedSchool(content, index)">
-                    <text>设置定向</text>
+                  <view class="flex items-center justify-between text-20">
+                    <view class="mt-8  text-fore-light">{{ content.majorAncestors }}</view>
+                    <view v-if="index === 0"
+                      class="flex items-center gap-x-4 text-white bg-gradient-to-r from-[#FED448] to-[#F9942F] rounded-full px-12 py-4">
+                      <ie-image src="/pagesStudy/static/image/icon-check-white.png" custom-class="w-24 h-24" />
+                      <text>定向学习中</text>
+                    </view>
+                    <view v-else class="flex items-center gap-x-4 text-22 text-primary px-12 py-4"
+                      @click="handleSetDirectedSchool(content, index)">
+                      <text>设置定向</text>
+                    </view>
                   </view>
                 </view>
               </view>
             </view>
-          </view>
-        </template>
-        <template #ghots></template>
-      </l-drag>
-    </view>
-    <view v-else class="flex-1 flex flex-col items-center justify-center gap-y-50">
-      <ie-image src="/pagesStudy/static/image/icon-empty.png" custom-class="w-364 h-252 mx-auto" mode="aspectFill" />
-      <text class="text-30 text-fore-light text-center">目前暂无定向院校~</text>
+          </template>
+          <template #ghots></template>
+        </l-drag>
+      </view>
+      <view v-if="sortList.length === 0" class="flex-1 flex flex-col items-center justify-center gap-y-50">
+        <ie-image src="/pagesStudy/static/image/icon-empty.png" custom-class="w-364 h-252 mx-auto" mode="aspectFill" />
+        <text class="text-30 text-fore-light text-center">目前暂无定向院校~</text>
+      </view>
     </view>
     <ie-safe-toolbar v-if="directedSchoolList.length < 3" :height="84" :shadow="false">
       <view class="px-46 pt-24">
@@ -74,6 +77,7 @@ import { getDirectedSchool, saveDirectedSchool } from '@/api/modules/study';
 const { transferTo } = useTransferPage();
 const loading = ref(true);
 const directedSchoolList = ref<DirectedSchool[]>([]);
+const sortList = ref<DirectedSchool[]>([]);
 const touchHandle = ref(false)
 const hasDirectedSchool = computed(() => directedSchoolList.value.length > 0);
 const handleSetDirectedSchool = async (item: DirectedSchool, index: number) => {
@@ -90,18 +94,18 @@ const handleAdd = () => {
     }
   }).then(async res => {
     if (res) {
-
+      uni.$ie.showLoading();
+      directedSchoolList.value.push({
+        ...res,
+        code: (res as SelectedUniversityMajor).universityId
+      } as DirectedSchool);
       setTimeout(() => {
         dragRef.value.push({
           ...res,
           code: (res as SelectedUniversityMajor).universityId
         } as DirectedSchool);
-        // directedSchoolList.value = [...directedSchoolList.value, {
-        //   ...res,
-        //   code: (res as SelectedUniversityMajor).universityId
-        // } as DirectedSchool];
-        // save(directedSchoolList.value);
-      }, 500);
+        uni.$ie.hideLoading();
+      }, 300);
     }
   });
 }
@@ -113,14 +117,20 @@ const changeSort = (e: any) => {
 const save = async (list: DirectedSchool[]) => {
   uni.$ie.showLoading();
   await saveDirectedSchool(list);
-  await loadData();
+  await refresh();
   uni.$ie.hideLoading();
   uni.$ie.showSuccess('设置成功');
   loading.value = false;
 }
-const loadData = async () => {
+const refresh = async () => {
   const { data } = await getDirectedSchool();
   directedSchoolList.value = data || [];
+  sortList.value = [...directedSchoolList.value];
+}
+const loadData = async () => {
+  uni.$ie.showLoading();
+  await refresh();
+  uni.$ie.hideLoading();
 }
 loadData();
 </script>

+ 2 - 0
src/types/study.ts

@@ -63,6 +63,8 @@ export interface StudyStats {
   videoTime: number; // 课程学习数量
   videoTimes: number; // 学习时长
   rightRate: number; // 正确率
+  questionPlan: number; // 计划答题数
+  videoPlan: number; // 计划课程学习时长
 }
 export interface StudyStatsHistory {
   date: string; // 日期 2025-10-12

+ 1 - 1
src/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue

@@ -23,7 +23,7 @@
       }">{{ weeks.date }}</text>
       <view class="uni-calendar-item__weeks-info-text-box">
         <view v-if="weeks.extraInfo && weeks.extraInfo.info" class="uni-calendar-item__weeks-info-text-box-content"
-          :class="[weeks.extraInfo.info > 2 ? 'uni-calendar-item__weeks-info-text-box--active' : 'uni-calendar-item__weeks-info-text-box--inactive']">
+          :class="[weeks.extraInfo.info.isFinish ? 'uni-calendar-item__weeks-info-text-box--active' : 'uni-calendar-item__weeks-info-text-box--inactive']">
         </view>
       </view>
     </view>