taiji_caozhaorui 1 maand geleden
bovenliggende
commit
53e33295c4

+ 2 - 0
src/api/modules/global/login.ts

@@ -6,6 +6,8 @@ export const authLogin = (params) =>
   post(`/auth/login`, params, {
     encrypt: true,
   })
+// 退出登录
+export const authLogout = () => post(`/auth/logout`, {}, {})
 // 用户信息
 export const systemUserGetInfo = () => get(`/system/user/getInfo`, {}, {})
 // 用户信息

+ 6 - 0
src/api/modules/study/index.ts

@@ -15,3 +15,9 @@ export const trainingCampPaperQuestionRelIpadPracticeRanking = (m) =>
     {},
     {},
   )
+// 树
+export const trainingCampQuestionTypeTree = (params) =>
+  get(`/trainingCamp/questionType/tree`, params, {})
+// 题库列表
+export const trainingCampQuestionList = (params) =>
+  get(`/trainingCamp/question/list`, params, {})

+ 2 - 1
src/router/index.ts

@@ -154,7 +154,8 @@ router.beforeEach((to, from, next) => {
         if (localStorage.getItem((import.meta as any).env.VITE_TOKEN)) {
           AppStore.initUserInfo()
             .then(() => {
-              isLogin ? next({ name: 'root' }) : next()
+              console.log(to)
+              isLogin ? next({ name: 'root' }) : next(to.path)
             })
             .catch((e) => {
               localStorage.removeItem((import.meta as any).env.VITE_TOKEN)

+ 3 - 0
src/stores/modules/app.ts

@@ -35,6 +35,7 @@ export const useAppStore = defineStore('app', {
                       component: () =>
                         import('@/views/study/subject/index.vue'),
                       meta: {
+                        subjectId: su.subjectId,
                         isMenu: true,
                         fa: 'fa-book',
                         res: su,
@@ -47,6 +48,7 @@ export const useAppStore = defineStore('app', {
                       component: () =>
                         import('@/views/study/subject/question/index.vue'),
                       meta: {
+                        subjectId: su.subjectId,
                         res: su,
                         title: su.subject,
                         root: menu1.name,
@@ -58,6 +60,7 @@ export const useAppStore = defineStore('app', {
                       component: () =>
                         import('@/views/study/subject/question/only.vue'),
                       meta: {
+                        subjectId: su.subjectId,
                         res: su,
                         title: su.subject,
                         root: menu1.name,

+ 11 - 0
src/style/czr.scss

@@ -518,3 +518,14 @@
   justify-content: center;
   box-sizing: border-box;
 }
+
+.__czr-quasar-el-date {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+  .el-input, .el-date-editor {
+    position: absolute;
+    z-index: -1;
+  }
+}

+ 16 - 0
src/views/study/components/study-layout.vue

@@ -36,6 +36,9 @@
                 >个人信息</q-item-section
               >
             </q-item>
+            <q-item clickable v-close-popup>
+              <q-item-section @click="onLogout">退出登录</q-item-section>
+            </q-item>
           </q-list>
         </q-menu>
       </div>
@@ -88,6 +91,7 @@
           </div>
         </div>
       </q-card-section>
+
       <q-card-actions align="right" class="text-teal bg-white">
         <q-btn flat label="确定" v-close-popup />
         <q-btn flat label="取消" v-close-popup />
@@ -101,6 +105,8 @@ import { computed, reactive } from 'vue'
 import { useRouter } from 'vue-router'
 import { Plus } from '@element-plus/icons-vue'
 import { Notify } from 'quasar'
+import { ElMessageBox } from 'element-plus'
+import { authLogout } from '@/api/modules/global/login'
 
 const router = useRouter()
 const state: any = reactive({
@@ -172,6 +178,16 @@ const beforeAvatarUpload = (rawFile) => {
   }
   return true
 }
+const onLogout = () => {
+  ElMessageBox.confirm('请确认是否退出登录?', '提示', {})
+    .then(() => {
+      authLogout().finally(() => {
+        localStorage.clear()
+        location.reload()
+      })
+    })
+    .catch(() => {})
+}
 </script>
 
 <style lang="scss" scoped>

+ 2 - 12
src/views/study/home/index.vue

@@ -60,7 +60,7 @@
               <i class="fas fa-calendar-alt mr-2"></i>
               学习计划
               <div class="absolute right-2 ml-auto flex">
-                <div class="date-month">
+                <div class="__czr-quasar-el-date">
                   <q-input
                     class="date w-[130px]"
                     rounded
@@ -141,7 +141,7 @@
                 <i class="fas fa-trophy mr-2"></i>
                 历史刷题榜单
                 <div class="absolute right-2 ml-auto flex">
-                  <div class="date-month">
+                  <div class="__czr-quasar-el-date">
                     <q-input
                       class="date w-[120px]"
                       rounded
@@ -783,14 +783,4 @@ onBeforeMount(() => {
     color: #ffffff;
   }
 }
-:deep(.date-month) {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  position: relative;
-  .el-input {
-    position: absolute;
-    z-index: -1;
-  }
-}
 </style>

+ 80 - 130
src/views/study/subject/index.vue

@@ -10,7 +10,7 @@
             板块提升
             <div
               class="subject-questions-btn bg-subject-color ml-auto flex items-center rounded-full px-3 py-1 text-sm"
-              @click="$router.push({ name: 'chinese-question' })"
+              @click="$router.push({ name: $route.name + 'question' })"
             >
               <i class="fas fa-question-circle mr-1"></i>
               <span>更多</span>
@@ -19,7 +19,7 @@
         </div>
         <!-- 图表容器 -->
         <div
-          class="flex flex-1 flex-col overflow-y-auto p-4"
+          class="flex flex-1 flex-col overflow-x-hidden overflow-y-auto p-4"
           style="flex-wrap: unset"
         >
           <!-- 图表切换标签 -->
@@ -96,135 +96,52 @@
 
           <div class="flex items-center justify-between py-3">
             <div class="font-semibold text-gray-800">最近刷题记录</div>
+
             <div class="ml-auto">
-              <q-input
-                class="date w-[250px]"
-                rounded
-                standout="focus"
-                :dense="true"
-                v-model="dateStr"
-                readonly
-              >
-                <template v-slot:prepend>
-                  <q-icon name="event" class="cursor-pointer" color="">
-                    <q-popup-proxy
-                      cover
-                      transition-show="scale"
-                      transition-hide="scale"
+              <div class="__czr-quasar-el-date">
+                <q-input
+                  class="w-[250px]"
+                  rounded
+                  standout="focus"
+                  :dense="true"
+                  v-model="dateStr"
+                  readonly
+                >
+                  <template v-slot:prepend>
+                    <q-icon
+                      name="event"
+                      class="cursor-pointer"
+                      @click="ref_date.handleOpen()"
                     >
-                      <q-date
-                        v-model="state.query.date"
-                        mask="YYYY-MM-DD"
-                        range
-                      >
-                        <div class="row items-center justify-end">
-                          <q-btn
-                            v-close-popup
-                            label="关闭"
-                            color="primary"
-                            flat
-                          />
-                        </div>
-                      </q-date>
-                    </q-popup-proxy>
-                  </q-icon>
-                </template>
-                <template v-slot:append>
-                  <q-icon
-                    v-if="dateStr"
-                    name="clear"
-                    class="cursor-pointer"
-                    @click="state.query.date = {}"
-                  />
-                </template>
-              </q-input>
-            </div>
-          </div>
-          <div class="max-h-[120px] overflow-y-auto">
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
-              </div>
-            </div>
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
-              </div>
-            </div>
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
-              </div>
-            </div>
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
+                    </q-icon>
+                  </template>
+                </q-input>
+                <el-date-picker
+                  ref="ref_date"
+                  v-model="state.makeQuestion.date"
+                  value-format="YYYY-MM-DD"
+                  type="daterange"
+                />
               </div>
             </div>
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
-              </div>
-            </div>
-            <div
-              class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
-              @click="$router.push({ name: 'chinese-question-only' })"
-            >
-              <div class="flex items-center justify-between">
-                <span class="text-sm font-medium">文言文阅读专项</span>
-              </div>
-              <div class="mt-1 text-xs text-gray-500">
-                2025-07-06 | 25题(<span class="text-red">5</span>/<span
-                  class="text-green"
-                  >20</span
-                >) | 正确率80%
+          </div>
+          <div>
+            <template v-for="item in state.makeQuestion.data">
+              <div
+                class="record-item cursor-pointer rounded-lg border border-gray-100 p-2"
+                @click="$router.push({ name: 'chinese-question-only' })"
+              >
+                <div class="flex items-center justify-between">
+                  <span class="text-sm font-medium">
+                    {{ AppStore.subjectMap.get(item.subject) }}
+                  </span>
+                </div>
+                <div class="mt-1 text-xs text-gray-500">
+                  {{ item.planDate }} | xxx题(<span class="text-red">xxx</span
+                  >/<span class="text-green">xxx</span>) | 正确率xxx%
+                </div>
               </div>
-            </div>
+            </template>
           </div>
         </div>
       </div>
@@ -571,28 +488,61 @@
 </template>
 
 <script setup lang="ts">
-import { computed, onBeforeMount, onMounted, reactive } from 'vue'
+import { computed, onBeforeMount, onMounted, reactive, ref } from 'vue'
 import StudyLayout from '@/views/study/components/study-layout.vue'
 import chart1 from './chart-1.vue'
 import chart2 from './chart-2.vue'
 import chart3 from './chart-3.vue'
 import chart4 from './chart-4.vue'
+import { trainingCampLearningPlanList } from '@/api/modules/study'
+import { oneDayTime, YMD } from '@/utils/czr-util'
+import { useAppStore } from '@/stores'
+import { useRoute } from 'vue-router'
 
+const route = useRoute()
+const AppStore = useAppStore()
 const state: any = reactive({
   type: 1,
+  makeQuestion: {
+    loading: false,
+    data: [],
+    date: [YMD(new Date().getTime() - oneDayTime * 7), YMD(new Date())],
+  },
   query: {
     p1: '近三个月',
     p2: '全部类型',
     date: {},
   },
 })
+const ref_date = ref()
 const dateStr = computed(() => {
-  if (state.query.date.from && state.query.date.to) {
-    return `${state.query.date.from} - ${state.query.date.to}`
+  if (state.makeQuestion.date.length > 0) {
+    return `${state.makeQuestion.date[0]} - ${state.makeQuestion.date[1]}`
   }
   return ''
 })
-onMounted(() => {})
+const initMakeQuestion = () => {
+  trainingCampLearningPlanList({
+    pageNum: 1,
+    pageSize: 10000,
+    studentId: AppStore.studentInfo?.studentId,
+    subject: route.meta.subjectId,
+    paperType: 1,
+    params: {
+      beginPlanDate: `${state.makeQuestion.date[0]} 00:00:00`,
+      endPlanDate: `${state.makeQuestion.date[1]} 23:59:59`,
+    },
+  })
+    .then(({ rows }: any) => {
+      state.makeQuestion.data = rows
+    })
+    .finally(() => {
+      state.makeQuestion.loading = false
+    })
+}
+onMounted(() => {
+  initMakeQuestion()
+})
 onBeforeMount(() => {
   document.documentElement.style.setProperty(
     '--czr-quasar-color',

+ 112 - 293
src/views/study/subject/question/index.vue

@@ -4,7 +4,7 @@
       <div
         class="col-span-1 flex h-full flex-col overflow-hidden rounded-xl bg-white shadow-md"
       >
-        <div class="bg-[var(--czr-chinese-sub-color)] p-4 text-white">
+        <div class="bg-[var(--czr-main-sub-color)] p-4 text-white">
           <div class="flex items-center text-xl font-bold">
             <i class="fas fa-book mr-2"></i>
             知识点分类
@@ -32,7 +32,7 @@
           <div class="relative">
             <div class="">
               <q-input
-                v-model="state.treeText"
+                v-model="state.tree.text"
                 outlined
                 placeholder="搜索知识点..."
                 :dense="true"
@@ -42,31 +42,33 @@
                 </template>
                 <template v-slot:append>
                   <q-icon
-                    v-if="state.treeText !== ''"
+                    v-if="state.tree.text !== ''"
                     name="clear"
                     class="cursor-pointer"
-                    @click="state.treeText = ''"
+                    @click="state.tree.text = ''"
                   />
                 </template>
               </q-input>
             </div>
           </div>
         </div>
-        <div class="flex-1 overflow-y-auto p-2">
+        <div class="flex-1 overflow-y-auto p-2" v-loading="state.tree.loading">
           <q-tree
             ref="ref_tree"
-            :nodes="treeData"
-            node-key="name"
-            label-key="name"
+            :nodes="state.tree.data"
+            node-key="value"
+            label-key="label"
             v-model:selected="state.selected"
-            :filter="state.treeText"
+            :filter="state.tree.text"
           >
             <template v-slot:default-header="prop">
               <div class="flex w-full items-center text-sm">
                 <div class="">
-                  {{ prop.node.name }}
+                  {{ prop.node.label }}
+                </div>
+                <div class="ml-auto">
+                  {{ prop.node.totalMake }}/{{ prop.node.total }}题
                 </div>
-                <div class="ml-auto">{{ prop.node.total }}题</div>
               </div>
             </template>
           </q-tree>
@@ -75,65 +77,24 @@
       <div
         class="col-span-3 flex h-full flex-col overflow-hidden rounded-xl bg-white shadow-md"
       >
-        <div class="bg-[var(--czr-chinese-sub-color)] p-4 text-white">
+        <div class="bg-[var(--czr-main-sub-color)] p-4 text-white">
           <div class="relative flex items-center text-xl font-bold">
             <i class="fas fa-book mr-2"></i>
             题目列表
             <span class="text-base" v-if="state.selected">
-              ({{ treeMapCpt.get(state.selected).name }} - 共{{
-                treeMapCpt.get(state.selected).total
+              ({{ treeMapCpt.get(state.selected)?.label }} - 共{{
+                state.question.total
               }}题)
             </span>
             <div class="absolute right-2 ml-auto flex">
-              <q-input
-                class="date w-[250px]"
-                rounded
-                standout="focus"
-                :dense="true"
-                v-model="dateStr"
-                readonly
-              >
-                <template v-slot:prepend>
-                  <q-icon name="event" class="cursor-pointer" color="white">
-                    <q-popup-proxy
-                      cover
-                      transition-show="scale"
-                      transition-hide="scale"
-                    >
-                      <q-date
-                        v-model="state.query.date"
-                        mask="YYYY-MM-DD"
-                        range
-                      >
-                        <div class="row items-center justify-end">
-                          <q-btn
-                            v-close-popup
-                            label="关闭"
-                            color="primary"
-                            flat
-                          />
-                        </div>
-                      </q-date>
-                    </q-popup-proxy>
-                  </q-icon>
-                </template>
-                <template v-slot:append>
-                  <q-icon
-                    v-if="dateStr"
-                    name="clear"
-                    class="cursor-pointer"
-                    @click="state.query.date = {}"
-                    color="white"
-                  />
-                </template>
-              </q-input>
               <q-select
                 class="select ml-4 w-[100px]"
                 rounded
                 standout="focus"
-                v-model="state.query.p2"
-                :options="['全部题', '错题', '正确题']"
+                v-model="state.question.type"
+                :options="['错题', '正确题']"
                 :dense="true"
+                @change="initQuestion"
               >
               </q-select>
             </div>
@@ -141,14 +102,14 @@
         </div>
         <div class="flex-1 overflow-y-auto p-4" id="questionsContainer">
           <div class="grid grid-cols-1 gap-4 md:grid-cols-2">
-            <template v-for="(item, index) in state.list">
+            <template v-for="(item, index) in state.question.data">
               <div
                 class="question-card overflow-hidden rounded-xl border border-[#e5e7eb] bg-white shadow-sm"
               >
                 <div class="p-4">
                   <div class="mb-3 flex items-start justify-between">
                     <div class="text-base font-semibold text-gray-800">
-                      题目 {{ index + 1 }} - {{ item.name }}
+                      题目 {{ index + 1 }}
                     </div>
                     <div class="flex space-x-1">
                       <q-btn
@@ -165,7 +126,7 @@
                     class="bg-gray-light mb-4 flex justify-center rounded-lg p-4"
                   >
                     <img
-                      :src="item.question"
+                      :src="item.questionContent"
                       alt="题目图片"
                       class="max-h-40 rounded"
                     />
@@ -175,7 +136,7 @@
                     class="bg-gray-light mb-4 flex justify-center rounded-lg p-4"
                   >
                     <img
-                      :src="item.answer"
+                      :src="item.questionAnswer"
                       alt="答案图片"
                       class="max-h-32 rounded"
                     />
@@ -186,11 +147,11 @@
                       视频解析:
                     </div>
                     <ul class="space-y-2">
-                      <template v-for="video in item.videos">
+                      <template v-for="video in item.questionVideos">
                         <li
                           class="video-item flex items-center justify-between rounded-lg border border-[#e5e7eb] p-2"
                         >
-                          <span class="text-sm">{{ video.name }}</span>
+                          <span class="text-sm">{{ video.fileName }}</span>
                           <div
                             class="play-video bg-subject-color hover:bg-subject-dark rounded-full p-1.5 transition-colors"
                             @click="state.showVideo = true"
@@ -307,257 +268,115 @@
 </template>
 
 <script setup lang="ts">
-import { computed, onBeforeMount, onMounted, reactive, ref } from 'vue'
+import { computed, onBeforeMount, onMounted, reactive, ref, watch } from 'vue'
 import StudyLayout from '@/views/study/components/study-layout.vue'
 import { Plus } from '@element-plus/icons-vue'
+import {
+  trainingCampQuestionList,
+  trainingCampQuestionTypeTree,
+} from '@/api/modules/study'
+import { useAppStore } from '@/stores'
+import { useRoute } from 'vue-router'
 
+const AppStore = useAppStore()
+const route = useRoute()
 const state: any = reactive({
   selected: null,
-  treeText: '',
-  query: {
-    p2: '错题',
-    date: {},
+  tree: {
+    text: '',
+    loading: false,
+    data: [],
+  },
+  question: {
+    loading: false,
+    type: '错题',
+    data: [],
+    total: 0,
+    page: 1,
   },
   showVideo: false,
   showHistory: false,
-  list: [
-    {
-      name: '下列汉字中属于独体字的是哪一项?',
-      question: 'https://picsum.photos/id/24/400/200',
-      answer: 'https://picsum.photos/id/26/400/150',
-      videos: [
-        {
-          name: '独体字与合体字的区别',
-          url: 'http://cyberplayer.bcelive.com/videoworks/mda-kbuhu4wqdi08dwix/cyberplayer/mp4/cyberplayer-demo.mp4',
-        },
-        {
-          name: '常见独体字结构分析',
-          url: 'http://cyberplayer.bcelive.com/videoworks/mda-kbuhu4wqdi08dwix/cyberplayer/mp4/cyberplayer-demo.mp4',
-        },
-      ],
-    },
-    {
-      name: '找出下列选项中书写有误的汉字并改正?',
-      question: 'https://picsum.photos/id/24/400/200',
-      answer: 'https://picsum.photos/id/26/400/150',
-      videos: [
-        {
-          name: '汉字结构分类详解',
-          url: 'http://cyberplayer.bcelive.com/videoworks/mda-kbuhu4wqdi08dwix/cyberplayer/mp4/cyberplayer-demo.mp4',
-        },
-      ],
-    },
-    {
-      name: '下列哪个汉字是上下结构?',
-      question: 'https://picsum.photos/id/24/400/200',
-      answer: 'https://picsum.photos/id/26/400/150',
-      videos: [
-        {
-          name: '汉字结构分类详解',
-          url: 'http://cyberplayer.bcelive.com/videoworks/mda-kbuhu4wqdi08dwix/cyberplayer/mp4/cyberplayer-demo.mp4',
-        },
-      ],
-    },
-    {
-      name: '下列哪组汉字都是左右结构?',
-      question: 'https://picsum.photos/id/24/400/200',
-      answer: 'https://picsum.photos/id/26/400/150',
-      videos: [
-        {
-          name: '汉字结构分类详解',
-          url: 'http://cyberplayer.bcelive.com/videoworks/mda-kbuhu4wqdi08dwix/cyberplayer/mp4/cyberplayer-demo.mp4',
-        },
-      ],
-    },
-  ],
-})
-const dateStr = computed(() => {
-  if (state.query.date.from && state.query.date.to) {
-    return `${state.query.date.from} - ${state.query.date.to}`
-  }
-  return ''
 })
 const ref_tree = ref()
-const treeData = [
-  {
-    name: '基础知识',
-    total: 328,
-    children: [
-      {
-        name: '字音字形',
-        total: 128,
-        children: [
-          {
-            name: '声母韵母',
-            total: 48,
-            children: [
-              { name: '声母辨析', total: 25 },
-              { name: '韵母辨析', total: 18 },
-              { name: '整体认读音节', total: 5 },
-            ],
-          },
-          {
-            name: '字形结构',
-            total: 80,
-            children: [
-              { name: '独体字', total: 24 },
-              { name: '合体字', total: 32 },
-              { name: '形近字', total: 16 },
-              { name: '多音字', total: 8 },
-            ],
-          },
-        ],
-      },
-      {
-        name: '词语辨析',
-        total: 145,
-        children: [
-          { name: '近义词', total: 45 },
-          { name: '反义词', total: 35 },
-          { name: '成语辨析', total: 50 },
-          { name: '熟语运用', total: 15 },
-        ],
-      },
-      {
-        name: '句子运用',
-        total: 55,
-        children: [
-          { name: '病句辨析', total: 30 },
-          { name: '修辞手法', total: 15 },
-          { name: '句式转换', total: 10 },
-        ],
-      },
-    ],
-  },
-  {
-    name: '文言文',
-    total: 196,
-    children: [
-      {
-        name: '文言实词',
-        total: 96,
-        children: [
-          { name: '一词多义', total: 40 },
-          { name: '古今异义', total: 35 },
-          { name: '通假字', total: 21 },
-        ],
-      },
-      {
-        name: '文言虚词',
-        total: 65,
-        children: [
-          { name: '之乎者也', total: 35 },
-          { name: '而何乃焉', total: 30 },
-        ],
-      },
-      {
-        name: '文言句式',
-        total: 35,
-      },
-    ],
-  },
-  {
-    name: '现代文阅读',
-    total: 178,
-    children: [
-      {
-        name: '记叙文',
-        total: 78,
-        children: [
-          { name: '写人记事', total: 45 },
-          { name: '写景状物', total: 33 },
-        ],
-      },
-      {
-        name: '说明文',
-        total: 55,
-        children: [
-          { name: '事物说明', total: 30 },
-          { name: '事理说明', total: 25 },
-        ],
-      },
-      {
-        name: '议论文',
-        total: 45,
-        children: [
-          { name: '论点论据', total: 25 },
-          { name: '论证方法', total: 20 },
-        ],
-      },
-    ],
-  },
-  {
-    name: '诗歌鉴赏',
-    total: 164,
-    children: [
-      {
-        name: '古诗',
-        total: 104,
-        children: [
-          { name: '唐诗', total: 45 },
-          { name: '宋诗', total: 35 },
-          { name: '乐府诗', total: 24 },
-        ],
-      },
-      {
-        name: '词曲',
-        total: 45,
-        children: [
-          { name: '宋词', total: 30 },
-          { name: '元曲', total: 15 },
-        ],
-      },
-      {
-        name: '现代诗',
-        total: 15,
-      },
-    ],
-  },
-  {
-    name: '写作技巧',
-    total: 120,
-    children: [
-      {
-        name: '记叙文写作',
-        total: 65,
-        children: [
-          { name: '人物描写', total: 35 },
-          { name: '情节安排', total: 30 },
-        ],
-      },
-      {
-        name: '议论文写作',
-        total: 45,
-        children: [
-          { name: '论点确立', total: 20 },
-          { name: '论据选择', total: 25 },
-        ],
-      },
-      {
-        name: '应用文写作',
-        total: 10,
-      },
-    ],
-  },
-]
 const treeMapCpt = computed(() => {
   const map = new Map()
   const deep = (arr) => {
     arr.forEach((v) => {
-      map.set(v.name, v)
+      map.set(v.value, v)
       if (v.children?.length > 0) {
         deep(v.children)
       }
     })
   }
-  deep(treeData)
+  deep(state.tree.data)
+  console.log(map)
   return map
 })
-onMounted(() => {})
+const initTree = () => {
+  state.tree.loading = true
+  state.tree.data = []
+  trainingCampQuestionTypeTree({
+    category: AppStore.studentInfo?.grade,
+    subject: route.name,
+    studentId: AppStore.studentInfo?.studentId,
+    level: 1,
+  })
+    .then(({ data }: any) => {
+      const deep = (arr, parent = []) => {
+        return arr.map((v) => {
+          v.total = 0
+          v.totalMake = 0
+          if (v.children?.length > 0) {
+            v.children = deep(v.children, [...parent, v])
+          } else {
+            parent.forEach((p) => {
+              p.total += v.size
+              p.totalMake += v.questionSize
+            })
+          }
+          return v
+        })
+      }
+      state.tree.data = deep(data)
+      console.log(state.tree.data)
+    })
+    .finally(() => {
+      state.tree.loading = false
+    })
+}
+const initQuestion = () => {
+  state.question.loading = true
+  state.question.total = 0
+  state.question.data = []
+  trainingCampQuestionList({
+    pageNum: 1,
+    pageSize: 10,
+    category: AppStore.studentInfo?.grade,
+    subject: route.meta.subjectId,
+    correct: state.question.type !== '错题',
+    questionTypeCode: treeMapCpt.value.get(state.selected).questionTypeCode,
+  })
+    .then(({ rows, total }: any) => {
+      state.question.data = rows
+      state.question.total = total
+    })
+    .finally(() => {
+      state.question.loading = false
+    })
+}
+watch(
+  () => state.selected,
+  (n) => {
+    initQuestion()
+  },
+)
+onMounted(() => {
+  initTree()
+})
 onBeforeMount(() => {
   document.documentElement.style.setProperty(
     '--czr-quasar-color',
-    'var(--czr-chinese-color)',
+    'var(--czr-main-color)',
   )
 })
 </script>
@@ -566,7 +385,7 @@ onBeforeMount(() => {
 $primary: red;
 
 .search-input:focus {
-  box-shadow: 0 0 0 3px rgba(var(--czr-chinese-color-rgb), 0.2);
+  box-shadow: 0 0 0 3px rgba(var(--czr-main-color-rgb), 0.2);
 }
 .question-card {
   transition: all 0.3s ease;
@@ -594,7 +413,7 @@ $primary: red;
 }
 :deep(.q-tree__node--selected),
 :deep(.q-tree__node--selected .q-tree__node-header-content) {
-  color: var(--czr-chinese-color) !important;
+  color: var(--czr-main-color) !important;
 }
 // FILE (create it): src/quasar-variables.sass
 </style>