Просмотр исходного кода

河南对口招生页面适配

shmily1213 2 недель назад
Родитель
Сommit
b2be248c48
24 измененных файлов с 489 добавлено и 161 удалено
  1. 6 1
      src/components/ie-table/ie-table.vue
  2. 34 0
      src/pagesStudy/components/henan-exam-item.vue
  3. 0 0
      src/pagesStudy/components/hunan-exam-item.vue
  4. 16 14
      src/pagesStudy/components/knowledge-table.vue
  5. 9 5
      src/pagesStudy/components/teacher-class-view.vue
  6. 50 0
      src/pagesStudy/pages/index/compoentns/henan-exam.vue
  7. 38 0
      src/pagesStudy/pages/index/compoentns/hunan-exam.vue
  8. 9 3
      src/pagesStudy/pages/index/compoentns/index-banner.vue
  9. 0 28
      src/pagesStudy/pages/index/compoentns/index-exam-record.vue
  10. 3 1
      src/pagesStudy/pages/index/compoentns/index-menu.vue
  11. 5 10
      src/pagesStudy/pages/index/index.vue
  12. 9 54
      src/pagesStudy/pages/study-history/components/exam-history.vue
  13. 43 0
      src/pagesStudy/pages/study-history/components/henan-exam-history-student.vue
  14. 93 0
      src/pagesStudy/pages/study-history/components/henan-exam-history-teacher.vue
  15. 49 0
      src/pagesStudy/pages/study-history/components/henan-exam-history.vue
  16. 8 5
      src/pagesStudy/pages/study-history/components/hunan-exam-history-student.vue
  17. 0 0
      src/pagesStudy/pages/study-history/components/hunan-exam-history-teacher.vue
  18. 63 0
      src/pagesStudy/pages/study-history/components/hunan-exam-history.vue
  19. 1 1
      src/pagesStudy/pages/study-history/components/knowledge-history-teacher.vue
  20. 9 7
      src/pagesStudy/pages/study-history/components/knowledge-history.vue
  21. 21 17
      src/pagesStudy/pages/study-history/components/practice-history.vue
  22. 3 2
      src/pagesStudy/pages/study-history/components/student-stat-table.vue
  23. 12 10
      src/pagesStudy/pages/study-history/components/video-history.vue
  24. 8 3
      src/pagesStudy/pages/study-history/study-history.vue

+ 6 - 1
src/components/ie-table/ie-table.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="">
-    <view class="table-header">
+    <view class="table-header" :class="{ 'fixed': props.headerFixed }">
       <view class="table-header-cell" v-for="item in tableColumns" :key="item.prop" :style="getHeaderStyle(item)">
         {{ item.label }}
       </view>
@@ -34,6 +34,7 @@ interface Props<T> {
   tableColumns: TableColumnConfig[];
   data: T[];
   cellStyle: CSSProperties;
+  headerFixed?: boolean;
 }
 
 const props = defineProps<Props<any>>();
@@ -111,4 +112,8 @@ const getCellValue = (row: any, prop: string) => {
 .no-data {
   @apply mt-16 bg-[#F6F8FA] text-center py-50 text-26 text-fore-light rounded-5;
 }
+
+.fixed {
+  @apply sticky top-0 z-1;
+}
 </style>

+ 34 - 0
src/pagesStudy/components/henan-exam-item.vue

@@ -0,0 +1,34 @@
+<template>
+  <view class="bg-white rounded-5">
+    <view class="px-30 pt-32 pb-20">
+      <view class="text-28 text-fore-title font-bold ellipsis-2">河南省 2026 年普通高校对口招生考试语文全真模拟试卷</view>
+      <view class="flex items-center gap-16 mt-20">
+        <view class="tag-item bg-[#FFFBEB] text-[#F97316]">语文</view>
+        <view class="tag-item bg-back text-fore-light">公共课</view>
+      </view>
+    </view>
+    <uv-line color="#F6F8FA" />
+    <view class="px-30 py-20 flex items-center justify-between">
+      <view class="text-24 text-fore-light">
+        <text>共</text>
+        <text class="text-primary">36</text>
+        <text>道题,总分</text>
+        <text class="text-primary">100</text>
+        <text>分</text>
+      </view>
+      <view class="px-20 py-8 bg-primary border border-solid border-primary rounded-full text-24 text-white" @click="handleStartExam">开始考试</view>
+    </view>
+  </view>
+</template>
+<script lang="ts" setup>
+
+const handleStartExam = () => {
+  console.log('开始考试');
+}
+
+</script>
+<style lang="scss" scoped>
+.tag-item {
+  @apply text-24 rounded-4 px-10 py-6 w-fit;
+}
+</style>

+ 0 - 0
src/pagesStudy/components/exam-record-item.vue → src/pagesStudy/components/hunan-exam-item.vue


+ 16 - 14
src/pagesStudy/components/knowledge-table.vue

@@ -1,18 +1,20 @@
 <template>
-  <view class="p-30">
-    <ie-table :table-columns="tableColumns" :table-config="tableConfig" :data="data">
-      <template #name="{ item }">
-        <view class="">
-          <text class="leading-38">{{ item.name }}</text>
-          <text v-if="item.directed"
-            class="ml-10 bg-[#F0FDF4] text-[#22C55E] border border-solid border-[#22C55E] text-20 rounded-4 px-10 py-2">定向</text>
-        </view>
-      </template>
-      <template #rate="{ item }">
-        <text :class="[item.rate < 70 ? 'text-danger' : 'text-fore-title']">{{ item.rate }}%</text>
-      </template>
-    </ie-table>
-  </view>
+  <scroll-view class="h-full px-30 pt-30 box-border" scroll-y>
+    <view class="">
+      <ie-table :table-columns="tableColumns" :table-config="tableConfig" :data="data" :headerFixed="true">
+        <template #name="{ item }">
+          <view class="">
+            <text class="leading-38">{{ item.name }}</text>
+            <text v-if="item.directed"
+              class="ml-10 bg-[#F0FDF4] text-[#22C55E] border border-solid border-[#22C55E] text-20 rounded-4 px-10 py-2 whitespace-nowrap">定向</text>
+          </view>
+        </template>
+        <template #rate="{ item }">
+          <text :class="[item.rate < 70 ? 'text-danger' : 'text-fore-title']">{{ item.rate }}%</text>
+        </template>
+      </ie-table>
+    </view>
+  </scroll-view>
 </template>
 <script lang="ts" setup>
 import { Study, TableColumnConfig, TableConfig } from '@/types';

+ 9 - 5
src/pagesStudy/components/teacher-class-view.vue

@@ -1,14 +1,18 @@
 <template>
-  <view class="p-30">
-    <view class="flex items-center justify-between">
+  <view class="h-full box-border px-30 flex flex-col">
+    <view class="flex items-center justify-between py-30">
       <text class="text-30 text-fore-title font-bold">我的班级</text>
       <view>
         <ie-picker ref="pickerRef" v-model="classId" :list="classList" placeholder="选择班级" title="选择班级" icon="arrow-down"
           key-label="name" key-value="classId" @change="handleClassChange"></ie-picker>
       </view>
     </view>
-    <view>
-      <slot :teachClass="selectedClass"></slot>
+    <view class="flex-1 min-h-1 relative">
+      <view class="absolute inset-0">
+        <scroll-view class="h-full" scroll-y>
+          <slot :teachClass="selectedClass"></slot>
+        </scroll-view>
+      </view>
     </view>
   </view>
 
@@ -22,7 +26,7 @@ const selectedClass = ref<TeachClass>();
 const pickerRef = ref();
 const loadData = async () => {
   try {
-    const { data } = await getTeachClassList();
+    const { data } = await getTeachClassList({});
     classList.value = data;
     classId.value = classList.value[0].classId;
     selectedClass.value = classList.value[0];

+ 50 - 0
src/pagesStudy/pages/index/compoentns/henan-exam.vue

@@ -0,0 +1,50 @@
+<template>
+  <view>
+    <view class="h-16 bg-back my-32"></view>
+    <view class="px-30 pt-13 pb-24 text-32 text-fore-title font-bold">真题&模拟</view>
+    <view class="">
+      <view class="overflow-hidden bg-white sticky z-2" :style="{ top: baseStickyTop + 'px' }">
+        <view class="px-30 pt-24 pb-30 text-32 text-fore-title font-bold flex items-center gap-44 bg-back rounded-t-15">
+          <view :class="['relative text-fore-light', { 'is-active': current === 0 }]" @click="handleChange(0)">公共课
+          </view>
+          <view :class="['relative text-fore-light', { 'is-active': current === 1 }]" @click="handleChange(1)">专业课
+          </view>
+        </view>
+      </view>
+
+      <view class="px-30 pb-24 bg-back flex flex-col gap-20 sticky z-1 " :style="{ top: baseStickyTop + 20 + 'px' }">
+        <henan-exam-item v-for="(item, index) in list" :key="index" :data="item" />
+      </view>
+    </view>
+  </view>
+</template>
+<script lang="ts" setup>
+import HenanExamItem from '@/pagesStudy/components/henan-exam-item.vue';
+import { useNavbar } from '@/hooks/useNavbar';
+
+const { baseStickyTop } = useNavbar();
+const list = [1, 1, 1, 1, 1, 1, 1, 1]
+const current = ref(0);
+const handleChange = (index: number) => {
+  current.value = index;
+}
+</script>
+<style lang="scss" scoped>
+.is-active {
+  @apply text-fore-title;
+
+  &::after {
+    content: '';
+    display: block;
+    width: 20px;
+    height: 4px;
+    background: radial-gradient(0% 0% at 0% 0%, #31A0FC 0%, #70C8FD 100%);
+    position: absolute;
+    bottom: 0;
+    border-radius: 4rpx;
+    left: 50%;
+    transform: translateX(-50%);
+    bottom: -8rpx;
+  }
+}
+</style>

+ 38 - 0
src/pagesStudy/pages/index/compoentns/hunan-exam.vue

@@ -0,0 +1,38 @@
+<template>
+  <view>
+    <view class="h-16 bg-back my-32"></view>
+    <index-test :directed-school="directedSchool" />
+    <view v-if="list.length > 0" class="px-30 pb-30 bg-back">
+      <view class="h-94 flex items-center justify-center">
+        <view class="h-0 w-160 border-0 border-b border-dashed border-border"></view>
+        <ie-image src="/pagesStudy/static/image/icon-ear-left.png" customClass="w-20 h-26 ml-26 mr-30" />
+        <view class="text-30 text-fore-title font-bold">考试记录</view>
+        <ie-image src="/pagesStudy/static/image/icon-ear-right.png" customClass="w-20 h-26 ml-26 mr-30" />
+        <view class="h-0 w-160 border-0 border-b border-dashed border-border"></view>
+      </view>
+      <view v-for="value in list" :key="value.id" class="rounded-10 mb-20 bg-white px-20 py-38">
+        <hunan-exam-item :data="value" />
+      </view>
+    </view>
+  </view>
+</template>
+<script lang="ts" setup>
+import IndexTest from './index-test.vue';
+import HunanExamItem from '@/pagesStudy/components/hunan-exam-item.vue';
+import { getSimulatedRecord } from '@/api/modules/study';
+import { Study } from '@/types';
+
+const props = defineProps<{
+  directedSchool: Study.DirectedSchool;
+}>();
+
+const list = ref<Study.SimulatedRecord[]>([]);
+const loadData = async () => {
+  const { data } = await getSimulatedRecord();
+  list.value = data || [];
+}
+onShow(() => {
+  loadData();
+});
+</script>
+<style lang="scss" scoped></style>

+ 9 - 3
src/pagesStudy/pages/index/compoentns/index-banner.vue

@@ -1,8 +1,8 @@
 <template>
   <view class="mx-30 mt-40">
     <!-- <ie-image :is-oss="true" src="/banner/index-banner-4.png" :round="10" customClass="w-full h-178" mode="widthFix" /> -->
-    <view class="flex gap-x-30">
-      <view class="flex-1 rounded-12 bg-[#F0FFF2] py-40 pl-22 pr-8 flex items-center" @click="handleOpenPlan">
+    <view class="grid grid-cols-2 gap-x-30">
+      <view class="rounded-12 bg-[#F0FFF2] py-40 pl-22 pr-8 flex items-center" @click="handleOpenPlan">
         <!-- /pagesStudy/pages/study-plan-edit/study-plan-edit -->
         <view class="flex-1">
           <view class="text-30 text-fore-title font-bold flex items-center">
@@ -13,7 +13,7 @@
         </view>
         <ie-image :is-oss="true" src="/study-bg3.png" customClass="w-92 h-92" />
       </view>
-      <view class="flex-1 rounded-12 bg-[#FFF6F0] py-40 pl-22 pr-8 flex items-center" @click="handleTest">
+      <view v-if="showCoursePractice" class="rounded-12 bg-[#FFF6F0] py-40 pl-22 pr-8 flex items-center" @click="handleTest">
         <view class="flex-1">
           <view class="text-30 text-fore-title font-bold flex items-center">
             <text class="mr-2">教材同步练习</text>
@@ -31,10 +31,16 @@ import { useTransferPage } from '@/hooks/useTransferPage';
 import { getStudyPlan, getDirectedSchool } from '@/api/modules/study';
 import { OPEN_VIP_POPUP } from '@/types/injectionSymbols';
 import { useUserStore } from '@/store/userStore';
+import { EnumExamType } from '@/common/enum';
 
 const { transferTo } = useTransferPage();
 const userStore = useUserStore();
 const openVipPopup = inject(OPEN_VIP_POPUP);
+
+const showCoursePractice = computed(() => {
+  return userStore.getExamType !== EnumExamType.VHS;
+});
+
 const handleOpenPlan = async () => {
   const { data } = await getStudyPlan();
   if (data) {

+ 0 - 28
src/pagesStudy/pages/index/compoentns/index-exam-record.vue

@@ -1,28 +0,0 @@
-<template>
-  <view v-if="list.length > 0" class="px-30 pb-30 bg-back">
-    <view class="h-94 flex items-center justify-center">
-      <view class="h-0 w-160 border-0 border-b border-dashed border-border"></view>
-      <ie-image src="/pagesStudy/static/image/icon-ear-left.png" customClass="w-20 h-26 ml-26 mr-30" />
-      <view class="text-30 text-fore-title font-bold">考试记录</view>
-      <ie-image src="/pagesStudy/static/image/icon-ear-right.png" customClass="w-20 h-26 ml-26 mr-30" />
-      <view class="h-0 w-160 border-0 border-b border-dashed border-border"></view>
-    </view>
-    <view v-for="value in list" :key="value.id" class="rounded-15 mb-20 bg-white px-20 py-38">
-      <exam-record-item :data="value" />
-    </view>
-  </view>
-</template>
-<script lang="ts" setup>
-import ExamRecordItem from '@/pagesStudy/components/exam-record-item.vue';
-import { getSimulatedRecord } from '@/api/modules/study';
-import { Study } from '@/types';
-const list = ref<Study.SimulatedRecord[]>([]);
-const loadData = async () => {
-  const { data } = await getSimulatedRecord();
-  list.value = data || [];
-}
-onShow(() => {
-  loadData();
-});
-</script>
-<style lang="scss" scoped></style>

+ 3 - 1
src/pagesStudy/pages/index/compoentns/index-menu.vue

@@ -11,6 +11,8 @@
 <script lang="ts" setup>
 import { useUserStore } from '@/store/userStore';
 import { useTransferPage } from '@/hooks/useTransferPage';
+import { EnumExamType } from '@/common/enum';
+
 const { transferTo } = useTransferPage();
 const userStore = useUserStore();
 type MenuItem = {
@@ -29,7 +31,7 @@ const menus = computed(() => [
     label: '组卷作业',
     icon: '/menu/menu-exam.png',
     pageUrl: '/pagesStudy/pages/homework/homework',
-    visible: userStore.isStudent
+    visible: userStore.isStudent && (userStore.getExamType !== EnumExamType.VHS)
   },
   {
     label: '收藏夹',

+ 5 - 10
src/pagesStudy/pages/index/index.vue

@@ -55,19 +55,16 @@
     </view>
     <index-menu />
     <index-banner />
-    <block v-if="hasTestAndRecord">
-      <view class="h-16 bg-back my-32"></view>
-      <index-test :directed-school="firstDirectedSchool" />
-      <index-exam-record />
-    </block>
+    <henan-exam v-if="getLocation === '河南'" :directed-school="firstDirectedSchool" />
+    <hunan-exam v-else-if="getLocation === '湖南'" :directed-school="firstDirectedSchool" />
   </ie-page>
 </template>
 
 <script lang="ts" setup>
 import IndexMenu from './compoentns/index-menu.vue';
 import IndexBanner from './compoentns/index-banner.vue';
-import IndexTest from './compoentns/index-test.vue';
-import IndexExamRecord from './compoentns/index-exam-record.vue';
+import HunanExam from './compoentns/hunan-exam.vue';
+import HenanExam from './compoentns/henan-exam.vue';
 import { EnumDictName, EnumExamType, EnumUserRole } from '@/common/enum';
 import { useUserStore } from '@/store/userStore';
 import { useTransferPage } from '@/hooks/useTransferPage';
@@ -77,11 +74,9 @@ import { useAuth } from '@/hooks/useAuth';
 const { transferTo } = useTransferPage();
 const userStore = useUserStore();
 const { hasPermission } = useAuth();
-
-const hasTestAndRecord = computed(() => userStore.getExamType !== EnumExamType.VHS);
 // 通过 ref 获取 ie-page 组件实例
 const iePageRef = ref<InstanceType<typeof IePage>>();
-const { hasDirectedSchool, directedSchoolList } = toRefs(userStore);
+const { hasDirectedSchool, directedSchoolList, getExamType, getLocation } = storeToRefs(userStore);
 const firstDirectedSchool = computed(() => directedSchoolList.value[0] || {});
 
 const handlePracticeAll = () => {

+ 9 - 54
src/pagesStudy/pages/study-history/components/exam-history.vue

@@ -1,61 +1,16 @@
 <template>
-  <view class="flex-1 min-h-1 bg-white">
-    <view class="px-30 py-20 flex gap-x-20">
-      <view class="exam-type-item" :class="{ 'is-active': examType === EnumExamRecordType.SIMULATED }"
-        @click="handleChangeExamType(EnumExamRecordType.SIMULATED)">
-        <ie-image src="/pagesStudy/static/image/icon-exam-test.png" custom-class="w-64 h-60" />
-        <view class="exam-type-text">模拟仿真</view>
-      </view>
-      <view class="exam-type-item" :class="{ 'is-active': examType === EnumExamRecordType.HOMEWORK }"
-        @click="handleChangeExamType(EnumExamRecordType.HOMEWORK)">
-        <ie-image src="/pagesStudy/static/image/icon-exam-homework.png" custom-class="w-64 h-60" />
-        <view class="exam-type-text">组卷作业</view>
-      </view>
+  <view class="flex-1 min-h-1 relative bg-back">
+    <view class="absolute inset-0">
+      <hunan-exam-history v-if="getLocation === '湖南'" />
+      <henan-exam-history v-if="getLocation === '河南'" />
     </view>
-    <exam-history-student v-if="isStudent" :exam-type="examType" />
-    <exam-history-teacher v-else :exam-type="examType" />
   </view>
 </template>
 <script lang="ts" setup>
-import { EnumExamRecordType } from '@/common/enum';
-import examHistoryStudent from './exam-history-student.vue';
-import examHistoryTeacher from './exam-history-teacher.vue';
+import HunanExamHistory from './hunan-exam-history.vue'
+import HenanExamHistory from './henan-exam-history.vue'
 import { useUserStore } from '@/store/userStore';
-const { isStudent } = storeToRefs(useUserStore());
-const examType = ref(EnumExamRecordType.SIMULATED);
-
-const handleChangeExamType = (type: EnumExamRecordType) => {
-  examType.value = type;
-}
+const userStore = useUserStore();
+const { getLocation } = storeToRefs(userStore);
 </script>
-<style lang="scss" scoped>
-.exam-type-item {
-  @apply flex-1 h-175 rounded-15 bg-[#F5F5F5] flex flex-col items-center justify-center gap-y-10;
-}
-
-.exam-type-text {
-  @apply text-28 text-fore-title font-bold;
-}
-
-.is-active {
-  @apply bg-[#E6F7FF] relative;
-
-  &::after {
-    content: "";
-    display: block;
-    position: absolute;
-    bottom: -9px;
-    left: 50%;
-    transform: translateX(-50%);
-    width: 0;
-    height: 0;
-    border-left: 14px solid transparent;
-    border-right: 14px solid transparent;
-    border-top: 10px solid #E6F7FF;
-  }
-
-  .exam-type-text {
-    @apply text-primary;
-  }
-}
-</style>
+<style lang="scss" scoped></style>

+ 43 - 0
src/pagesStudy/pages/study-history/components/henan-exam-history-student.vue

@@ -0,0 +1,43 @@
+<template>
+  <view class="flex flex-col gap-20 px-30 pb-20 bg-back h-fit">
+    <view class="" v-for="(item, index) in [1, 1, 1, 1, 1, 1, 1]" :key="index">
+      <henan-exam-item :data="item" />
+    </view>
+  </view>
+</template>
+<script lang="ts" setup>
+import { getSimulatedRecord, getPaperWorkList } from '@/api/modules/study';
+import { EnumExamRecordType, EnumPaperWorkState } from '@/common/enum';
+import HenanExamItem from '@/pagesStudy/components/henan-exam-item.vue';
+import { Study } from '@/types';
+import PaperWorkItem from '@/pagesStudy/components/paper-work-item.vue';
+const props = defineProps({
+  examType: {
+    type: String,
+    default: 'test'
+  }
+});
+const simulatedRecordList = ref<Study.SimulatedRecord[]>([]);
+const paperWorkRecordList = ref<Study.PaperWork[]>([]);
+const loadData = async (type: string) => {
+  simulatedRecordList.value = [];
+  paperWorkRecordList.value = [];
+  if (type === EnumExamRecordType.SIMULATED) {
+    const { data } = await getSimulatedRecord();
+    simulatedRecordList.value = data;
+  } else {
+    const { rows } = await getPaperWorkList({ state: EnumPaperWorkState.COMPLETED });
+    paperWorkRecordList.value = rows;
+  }
+}
+
+watch(() => props.examType, (newVal) => {
+  loadData(newVal);
+}, {
+  immediate: false
+});
+onShow(() => {
+  loadData(props.examType);
+});
+</script>
+<style lang="scss" scoped></style>

+ 93 - 0
src/pagesStudy/pages/study-history/components/henan-exam-history-teacher.vue

@@ -0,0 +1,93 @@
+<template>
+  <view class="h-full bg-white">
+    <teacher-class-view>
+      <template #default="{ teachClass }">
+        <view class="">
+          <ie-table :tableColumns="tableColumns" :data="tableData" :cellStyle="cellStyle" :headerFixed="true">
+            <template #name="{ item }">
+              <text class="font-bold">{{ item.name }}</text>
+            </template>
+            <template #total="{ item }">
+              <text class="font-bold">{{ item.value }}/{{ item.total }}</text>
+            </template>
+            <template #action="{ item }">
+              <text class="text-30 text-primary font-bold" @click="handleRowClick(item)">查看</text>
+            </template>
+          </ie-table>
+        </view>
+      </template>
+    </teacher-class-view>
+  </view>
+</template>
+<script lang="ts" setup>
+import teacherClassView from '@/pagesStudy/components/teacher-class-view.vue';
+import examHistorySimulated from './exam-history-simulated.vue';
+import examHistoryPaperwork from './exam-history-paperwork.vue';
+import { Study } from '@/types';
+import { TableColumnConfig } from '@/types';
+import { CSSProperties } from 'vue';
+import { useTransferPage } from '@/hooks/useTransferPage';
+import { getClassExamRecord } from '@/api/modules/study';
+const { transferTo } = useTransferPage();
+
+const props = defineProps({
+  examType: {
+    type: String,
+    default: 'test'
+  }
+});
+const cellStyle: CSSProperties = {
+  padding: '30rpx 20rpx'
+}
+const mockData = {
+  name: '1班',
+  total: 100,
+  value: 100,
+  rate: 100,
+}
+const tableData = ref<Study.StudentExamRecord[]>(new Array(20).fill(mockData));
+const tableColumns: TableColumnConfig[] = [
+  {
+    prop: 'name',
+    label: '班级',
+    flex: 1,
+    slot: 'name',
+    headerAlign: 'center',
+    align: 'center'
+  },
+  {
+    prop: 'total',
+    label: '做卷情况',
+    flex: 1,
+    slot: 'total'
+  },
+  {
+    prop: 'action',
+    label: '操作',
+    flex: 1,
+    slot: 'action'
+  }
+];
+
+const handleRowClick = (row: Study.StudentExamRecord) => {
+  transferTo('/pagesStudy/pages/study-exam-simulated-class/study-exam-simulated-class', {
+    data: {
+      classId: row.id,
+      name: row.name
+    }
+  });
+}
+
+const loadData = async () => {
+  uni.$ie.showLoading();
+  await getClassExamRecord({}).then(res => {
+    tableData.value = res.data;
+  });
+  uni.$ie.hideLoading();
+}
+
+onMounted(() => {
+  // loadData();
+})
+</script>
+<style lang="scss" scoped></style>

+ 49 - 0
src/pagesStudy/pages/study-history/components/henan-exam-history.vue

@@ -0,0 +1,49 @@
+<template>
+  <view class="h-full">
+    <henan-exam-history-student v-if="isStudent" :exam-type="examType" />
+    <henan-exam-history-teacher v-else :exam-type="examType" />
+  </view>
+</template>
+<script lang="ts" setup>
+import { EnumExamRecordType } from '@/common/enum';
+import HenanExamHistoryStudent from './henan-exam-history-student.vue';
+import HenanExamHistoryTeacher from './henan-exam-history-teacher.vue';
+import { useUserStore } from '@/store/userStore';
+const { isStudent } = storeToRefs(useUserStore());
+const examType = ref(EnumExamRecordType.SIMULATED);
+
+const handleChangeExamType = (type: EnumExamRecordType) => {
+  examType.value = type;
+}
+</script>
+<style lang="scss" scoped>
+.exam-type-item {
+  @apply flex-1 h-175 rounded-15 bg-[#F5F5F5] flex flex-col items-center justify-center gap-y-10;
+}
+
+.exam-type-text {
+  @apply text-28 text-fore-title font-bold;
+}
+
+.is-active {
+  @apply bg-[#E6F7FF] relative;
+
+  &::after {
+    content: "";
+    display: block;
+    position: absolute;
+    bottom: -9px;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 0;
+    height: 0;
+    border-left: 14px solid transparent;
+    border-right: 14px solid transparent;
+    border-top: 10px solid #E6F7FF;
+  }
+
+  .exam-type-text {
+    @apply text-primary;
+  }
+}
+</style>

+ 8 - 5
src/pagesStudy/pages/study-history/components/exam-history-student.vue → src/pagesStudy/pages/study-history/components/hunan-exam-history-student.vue

@@ -2,20 +2,23 @@
   <view class="pb-30">
     <view v-if="examType === EnumExamRecordType.SIMULATED" class="px-30">
       <view class="sibling-border-top px-20 py-30" v-for="(item, index) in simulatedRecordList" :key="index">
-        <exam-record-item :data="item" />
+        <hunan-exam-item :data="item" />
       </view>
     </view>
     <template v-else>
-      <view class="sibling-border-top" v-for="(item, index) in paperWorkRecordList" :key="index">
-        <paper-work-item :data="item" />
-      </view>
+      <template v-if="paperWorkRecordList.length > 0">
+        <view class="sibling-border-top" v-for="(item, index) in paperWorkRecordList" :key="index">
+          <paper-work-item :data="item" />
+        </view>
+      </template>
+      <view v-else class="mt-50 mx-30 bg-[#F6F8FA] text-center py-50 text-26 text-fore-light rounded-5">暂无数据</view>
     </template>
   </view>
 </template>
 <script lang="ts" setup>
 import { getSimulatedRecord, getPaperWorkList } from '@/api/modules/study';
 import { EnumExamRecordType, EnumPaperWorkState } from '@/common/enum';
-import examRecordItem from '@/pagesStudy/components/exam-record-item.vue';
+import HunanExamItem from '@/pagesStudy/components/hunan-exam-item.vue';
 import { Study } from '@/types';
 import PaperWorkItem from '@/pagesStudy/components/paper-work-item.vue';
 const props = defineProps({

+ 0 - 0
src/pagesStudy/pages/study-history/components/exam-history-teacher.vue → src/pagesStudy/pages/study-history/components/hunan-exam-history-teacher.vue


+ 63 - 0
src/pagesStudy/pages/study-history/components/hunan-exam-history.vue

@@ -0,0 +1,63 @@
+<template>
+  <view class="h-full bg-white flex flex-col">
+    <view class="px-30 py-20 flex gap-x-20">
+      <view class="exam-type-item" :class="{ 'is-active': examType === EnumExamRecordType.SIMULATED }"
+        @click="handleChangeExamType(EnumExamRecordType.SIMULATED)">
+        <ie-image src="/pagesStudy/static/image/icon-exam-test.png" custom-class="w-64 h-60" />
+        <view class="exam-type-text">模拟仿真</view>
+      </view>
+      <view class="exam-type-item" :class="{ 'is-active': examType === EnumExamRecordType.HOMEWORK }"
+        @click="handleChangeExamType(EnumExamRecordType.HOMEWORK)">
+        <ie-image src="/pagesStudy/static/image/icon-exam-homework.png" custom-class="w-64 h-60" />
+        <view class="exam-type-text">组卷作业</view>
+      </view>
+    </view>
+    <scroll-view class="flex-1 min-h-1" scroll-y>
+      <hunan-exam-history-student v-if="isStudent" :exam-type="examType" />
+      <hunan-exam-history-teacher v-else :exam-type="examType" />
+    </scroll-view>
+  </view>
+</template>
+<script lang="ts" setup>
+import { EnumExamRecordType } from '@/common/enum';
+import HunanExamHistoryStudent from './hunan-exam-history-student.vue';
+import HunanExamHistoryTeacher from './hunan-exam-history-teacher.vue';
+import { useUserStore } from '@/store/userStore';
+const { isStudent } = storeToRefs(useUserStore());
+const examType = ref(EnumExamRecordType.SIMULATED);
+
+const handleChangeExamType = (type: EnumExamRecordType) => {
+  examType.value = type;
+}
+</script>
+<style lang="scss" scoped>
+.exam-type-item {
+  @apply flex-1 h-175 rounded-15 bg-[#F5F5F5] flex flex-col items-center justify-center gap-y-10;
+}
+
+.exam-type-text {
+  @apply text-28 text-fore-title font-bold;
+}
+
+.is-active {
+  @apply bg-[#E6F7FF] relative;
+
+  &::after {
+    content: "";
+    display: block;
+    position: absolute;
+    bottom: -9px;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 0;
+    height: 0;
+    border-left: 14px solid transparent;
+    border-right: 14px solid transparent;
+    border-top: 10px solid #E6F7FF;
+  }
+
+  .exam-type-text {
+    @apply text-primary;
+  }
+}
+</style>

+ 1 - 1
src/pagesStudy/pages/study-history/components/knowledge-history-teacher.vue

@@ -1,5 +1,5 @@
 <template>
-  <view class="mt-40 flex items-center justify-end gap-x-10">
+  <view class="flex items-center justify-end gap-x-10">
     <text class="text-24 text-fore-light">平均正确率</text>
     <text class="text-30 text-fore-title font-bold">{{ averageRate.toFixed(1) }}%</text>
   </view>

+ 9 - 7
src/pagesStudy/pages/study-history/components/knowledge-history.vue

@@ -1,11 +1,13 @@
 <template>
-  <view class="bg-white">
-    <knowledge-history-student v-if="isStudent" />
-    <teacher-class-view v-else>
-      <template #default="{ teachClass }">
-        <knowledge-history-teacher :teach-class="teachClass" />
-      </template>
-    </teacher-class-view>
+  <view class="bg-white flex-1 min-h-1 relative">
+    <view class="absolute inset-0">
+      <knowledge-history-student v-if="isStudent" />
+      <teacher-class-view v-else>
+        <template #default="{ teachClass }">
+          <knowledge-history-teacher :teach-class="teachClass" />
+        </template>
+      </teacher-class-view>
+    </view>
   </view>
 </template>
 <script lang="ts" setup>

+ 21 - 17
src/pagesStudy/pages/study-history/components/practice-history.vue

@@ -1,21 +1,25 @@
 <template>
-  <view class="flex-1 min-h-1 bg-white">
-    <practice-history-student v-if="isStudent" />
-    <teacher-class-view v-else>
-      <template #default="{ teachClass }">
-        <view class="type-wrap">
-          <view v-for="item in typeList" :key="item.value" class="type-item"
-            :class="{ 'is-active': currentType === item.value }" @click="handleTypeChange(item.value)">{{ item.label }}
+  <view class="flex-1 min-h-1 bg-white relative">
+    <view class="absolute inset-0">
+      <practice-history-student v-if="isStudent" />
+      <teacher-class-view v-else>
+        <template #default="{ teachClass }">
+          <view class="type-wrap">
+            <view v-for="item in typeList" :key="item.value" class="type-item"
+              :class="{ 'is-active': currentType === item.value }" @click="handleTypeChange(item.value)">
+              {{ item.label }}
+            </view>
           </view>
-        </view>
-        <view class="mt-30 w-fit mx-auto">
-          <ie-tab :options="tabList" v-model="currentSort" />
-        </view>
-        <view class="mt-30">
-          <practice-history-teacher :teach-class="teachClass" :current-type="currentType" :current-sort="currentSort" />
-        </view>
-      </template>
-    </teacher-class-view>
+          <view class="mt-30 w-fit mx-auto">
+            <ie-tab :options="tabList" v-model="currentSort" />
+          </view>
+          <view class="mt-30">
+            <practice-history-teacher :teach-class="teachClass" :current-type="currentType"
+              :current-sort="currentSort" />
+          </view>
+        </template>
+      </teacher-class-view>
+    </view>
   </view>
 </template>
 <script lang="ts" setup>
@@ -68,7 +72,7 @@ provide(OPEN_PRACTICE_DETAIL, openPracticeDetail);
 </script>
 <style lang="scss" scoped>
 .type-wrap {
-  @apply mt-40 mx-auto p-10 bg-white border border-solid border-border rounded-8 w-fit flex gap-x-10;
+  @apply mx-auto p-10 bg-white border border-solid border-border rounded-8 w-fit flex gap-x-10;
 }
 
 .type-item {

+ 3 - 2
src/pagesStudy/pages/study-history/components/student-stat-table.vue

@@ -1,6 +1,6 @@
 <template>
-  <view>
-    <ie-table :table-columns="tableColumns" :table-config="tableConfig" :data="data" @rowClick="handleRowClick">
+  <view class="h-full">
+    <ie-table v-if="data.length > 0" :table-columns="tableColumns" :table-config="tableConfig" :data="data" @rowClick="handleRowClick">
       <template #name="{ item }">
         <view class="flex items-center justify-center gap-10">
           <!-- <ie-image :src="item.avatar" class="w-60 h-60 bg-back" :round="999" /> -->
@@ -11,6 +11,7 @@
         <text :class="[item.rate < 70 ? 'text-danger' : 'text-fore-title']">{{ item.rate }}%</text>
       </template>
     </ie-table>
+    <view v-else class="bg-[#F6F8FA] text-center py-50 text-26 text-fore-light rounded-5">暂无数据</view>
   </view>
 </template>
 <script lang="ts" setup>

+ 12 - 10
src/pagesStudy/pages/study-history/components/video-history.vue

@@ -1,14 +1,16 @@
 <template>
-  <view class="bg-white flex-1">
-    <video-history-student v-if="isStudent" />
-    <teacher-class-view v-else>
-      <template #default="{ teachClass }">
-        <view class="mt-30 w-fit mx-auto">
-          <ie-tab :options="tabList" v-model="currentSort" />
-        </view>
-        <video-history-teacher :teach-class="teachClass" :current-sort="currentSort" />
-      </template>
-    </teacher-class-view>
+  <view class="flex-1 min-h-1 bg-white relative">
+    <view class="absolute inset-0">
+      <video-history-student v-if="isStudent" />
+      <teacher-class-view v-else>
+        <template #default="{ teachClass }">
+          <view class="w-fit mx-auto">
+            <ie-tab :options="tabList" v-model="currentSort" />
+          </view>
+          <video-history-teacher :teach-class="teachClass" :current-sort="currentSort" />
+        </template>
+      </teacher-class-view>
+    </view>
   </view>
 </template>
 <script lang="ts" setup>

+ 8 - 3
src/pagesStudy/pages/study-history/study-history.vue

@@ -1,11 +1,11 @@
 <template>
-  <ie-page bg-color="#F6F8FA" :fix-height="true">
+  <ie-page bg-color="#FFFFFF" :fix-height="true">
     <ie-navbar title="学习记录" />
     <view class="bg-white sticky z-1" :style="{ top: baseStickyTop + 'px' }">
       <uv-tabs :list="list" :current="current" :activeStyle="activeStyle" :inactiveStyle="inactiveStyle"
         :scrollable="false" @change="handleTabChange"></uv-tabs>
     </view>
-    <view class="h-20"></view>
+    <view class="h-20 bg-back"></view>
     <knowledge-history v-if="current === 0" />
     <exam-history v-if="current === 1" />
     <practice-history v-if="current === 2" />
@@ -16,9 +16,14 @@
 <script lang="ts" setup>
 import { useNavbar } from '@/hooks/useNavbar';
 import knowledgeHistory from './components/knowledge-history.vue'
-import examHistory from './components/exam-history.vue'
+import ExamHistory from './components/exam-history.vue'
+
 import practiceHistory from './components/practice-history.vue'
 import videoHistory from './components/video-history.vue'
+import { useUserStore } from '@/store/userStore';
+
+const userStore = useUserStore();
+const { getLocation } = storeToRefs(userStore);
 const { baseStickyTop } = useNavbar();
 const current = ref(0);
 const list = [