Browse Source

添加首页显示功能

lex 1 year ago
parent
commit
b55203e49e

+ 13 - 0
src/utils/contants.ts

@@ -58,3 +58,16 @@ export const weekToCN = {
   5: '星期五',
   6: '星期六'
 } as any;
+
+/** 年级 */
+export const gradeToCN = {
+  1: '一年级',
+  2: '二年级',
+  3: '三年级',
+  4: '四年级',
+  5: '五年级',
+  6: '六年级',
+  7: '七年级',
+  8: '八年级',
+  9: '九年级'
+} as any;

+ 19 - 0
src/views/home/api.ts

@@ -0,0 +1,19 @@
+import request from '@/utils/request';
+
+/**
+ * 首页 - 使用记录
+ */
+export const courseSchedulePage = (params: any) => {
+  return request.post('/edu-app/courseSchedule/page', {
+    data: params
+  });
+};
+
+/**
+ * 首页 - 年级班级列表
+ */
+export const classGroupList = (params: any) => {
+  return request.post('/edu-app/classGroup/list', {
+    data: params
+  });
+};

+ 1 - 0
src/views/home/components/teachList.tsx

@@ -58,6 +58,7 @@ export default defineComponent({
         }
       ]
     } as any;
+
     return () => (
       <>
         <div class={styles.teachListWrap}>

+ 23 - 2
src/views/home/index.module.less

@@ -160,6 +160,7 @@
     height: 40px;
     font-size: 14px;
     color: #6AA1E0;
+    display: flex;
   }
 
   .selectContainer {
@@ -195,6 +196,7 @@
   :global {
     .n-avatar {
       --n-merged-size: 42px !important;
+      --n-merged-color: #3E9FFF !important;
     }
 
     .n-base-selection {
@@ -527,8 +529,8 @@
 
 
 .homeInfoRight {
-  display: flex;
-  flex-direction: column;
+  // display: flex;
+  // flex-direction: column;
 
   .rightTitle {
     display: flex;
@@ -640,6 +642,25 @@
         rgba(255, 255, 255, 0) 0%,
         #ffffff 100%);
     border-radius: 0px 0px 20px 20px;
+
+    span {
+      position: absolute;
+      bottom: 0px;
+      left: 0;
+      width: 100%;
+      text-align: center;
+      color: #1677FF;
+      font-size: 16px;
+
+      &::after {
+        content: ' ';
+        display: inline-block;
+        width: 12px;
+        height: 12px;
+        background: url('./images/blueArrow.png') no-repeat center;
+        background-size: contain;
+      }
+    }
   }
 }
 

+ 439 - 45
src/views/home/index.tsx

@@ -1,4 +1,4 @@
-import { computed, defineComponent, reactive } from 'vue';
+import { defineComponent, onMounted, reactive, ref } from 'vue';
 import styles from './index.module.less';
 import {
   NImage,
@@ -8,11 +8,13 @@ import {
   NFormItem,
   NSelect,
   NSpace,
-  NModal
+  NModal,
+  NCascader,
+  useMessage,
+  NSpin
 } from 'naive-ui';
 import headerD from './images/headerD.png';
 import defultHeade from '@/components/layout/images/teacherIcon.png';
-import TeachList from './components/teachList';
 import blackBoardBg from './images/blackboard_bg.png';
 import teacherMan from './images/teacher_man.png';
 import teacherWoman from './images/teacher_woman.png';
@@ -28,25 +30,66 @@ import { useRouter } from 'vue-router';
 import { useUserStore } from '/src/store/modules/users';
 import SelectClass from './modals/selectClass';
 import dayjs from 'dayjs';
-import { weekToCN } from '/src/utils/contants';
-import { getCLassStudent } from '../classList/api';
+import { gradeToCN, weekToCN } from '/src/utils/contants';
+import { getCLassStudent, getCourseChapter } from '../classList/api';
+import { useCatchStore } from '/src/store/modules/catchData';
+import { useThrottleFn } from '@vueuse/core';
+import {
+  bookVersionPage,
+  courseScheduleStart,
+  lessonCoursewarePage,
+  queryCourseware
+} from '../prepare-lessons/api';
+import TheNoticeBar from '/src/components/TheNoticeBar';
+import TeachGroup from './modals/teachGroup';
+import { classGroupList, courseSchedulePage } from './api';
+import TheEmpty from '/src/components/TheEmpty';
+import { setTabsCaches } from '/src/hooks/use-async';
+
+export const formatDateToDay = () => {
+  //
+  const hours = dayjs().hour();
+  if (hours < 12) {
+    return '早上好!'; //如果小时数小于12则输出“早上好!”
+  } else if (hours > 12 && hours < 18) {
+    return '下午好!'; //如果小时数大于12并且小于18,输入“下午好!”
+  } else {
+    return '晚上好!'; //如果上面两个条件都不符合,则输出“晚上好!”
+  }
+};
 
 export default defineComponent({
   name: 'home-page',
   setup() {
+    const catchStore = useCatchStore();
+    const message = useMessage();
     const router = useRouter();
     const userStore = useUserStore();
     const forms = reactive({
-      applyClass: null as any,
       applyClassItem: {} as any, // 选择的内容
       applyStatus: false,
-      studentList: [] as any
-    });
-
-    // 显示选择的内容
-    const bookInfo = computed(() => {
-      return '';
+      useStatus: false,
+      studentList: [] as any,
+      bookVersionId: null,
+      classGroupId: null,
+      category: null,
+      subjectId: null,
+      musicTagList: [] as any,
+      loading: false,
+      list: [] as any,
+      unit: null,
+      unitList: [],
+      subjectList: [] as any,
+      gradeList: [] as any,
+      classLoading: false,
+      total: 0, // 上课数量
+      classSelect: {
+        currentGradeNum: null,
+        currentClass: null,
+        name: ''
+      } as any
     });
+    const teachList = ref({} as any);
 
     // 学生列表
     // getStdentList
@@ -67,14 +110,219 @@ export default defineComponent({
             src: row.avatar
           });
         });
-
-        console.log(item, data);
-        forms.applyClass = item.currentGradeLabel + item.className;
         forms.applyClassItem = item;
       } catch {
         //
       }
     };
+
+    const onUseConfirm = (item: any) => {
+      forms.classSelect = {
+        currentGradeNum: item.currentGradeNum,
+        currentClass: item.classGroupId,
+        name: item.name
+      };
+
+      getCourseSchedulePage();
+    };
+
+    const throttledFn = useThrottleFn(() => getLessonCourseware(), 500);
+    const getLessonCourseware = async () => {
+      forms.category = null;
+      forms.unit = null;
+      forms.category = null;
+      forms.loading = true;
+
+      try {
+        const { data } = await lessonCoursewarePage({
+          bookVersionId: forms.bookVersionId,
+          enableFlag: 1,
+          page: 1,
+          rows: 99,
+          type: 'COURSEWARE'
+        });
+
+        forms.list = data.rows.map((item: any) => {
+          return {
+            label: item.name,
+            value: item.id
+          };
+        });
+      } catch {
+        //
+      }
+
+      forms.loading = false;
+    };
+
+    const getunitList = async () => {
+      forms.unit = null;
+      try {
+        if (forms.category) {
+          const res = await getCourseChapter(forms.category);
+          forms.unitList = res.data.lessonList.map((item: any) => {
+            return { ...item, label: item.name, value: item.id };
+          });
+        } else {
+          forms.unitList = [];
+        }
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    const getVersion = async () => {
+      forms.unit = null;
+
+      try {
+        const { data } = await bookVersionPage({
+          page: 1,
+          rows: 99,
+          type: 'COURSEWARE'
+        });
+        const temp = data.rows || [];
+        temp.forEach((item: any) => {
+          forms.musicTagList.push({
+            id: item.id,
+            name: item.name
+          });
+        });
+      } catch {
+        //
+      }
+    };
+
+    // 获取年级班级
+    const getClassList = async () => {
+      try {
+        const { data } = await classGroupList({ removeZeroClass: true });
+        const cList = data || [];
+        const gradeList: any = [];
+        cList.forEach((item: any, index: number) => {
+          if (index === 0) {
+            const temp = item.classGroupList[0];
+            forms.classSelect = {
+              currentGradeNum: item.currentGradeNum,
+              currentClass: temp.id,
+              name: temp.name
+            };
+          }
+
+          const classList: any = [];
+          item.classGroupList.forEach((i: any, j: number) => {
+            classList.push({
+              label: j + 1 + '班',
+              value: i.id,
+              lastStudy: i.lastStudy
+            });
+          });
+
+          gradeList.push({
+            label: gradeToCN[item.currentGradeNum],
+            value: item.currentGradeNum,
+            childrens: classList
+          });
+        });
+
+        forms.gradeList = gradeList;
+      } catch {
+        //
+      }
+    };
+
+    const getCourseSchedulePage = async () => {
+      forms.classLoading = true;
+      try {
+        const { data } = await courseSchedulePage({
+          classGroupId: forms.classSelect.currentClass,
+          page: 1,
+          rows: 6
+        });
+
+        const result = data.rows || [];
+        forms.total = data.total || 0;
+        const dateTime: any = {};
+        result.forEach((item: any) => {
+          const tempTime = dayjs(item.classDate).format('MM-DD');
+          if (!dateTime[tempTime]) {
+            dateTime[tempTime] = [];
+          }
+
+          const lessonCourseware = item.lessonCoursewareJson
+            ? JSON.parse(item.lessonCoursewareJson)
+            : {};
+          dateTime[tempTime].push({
+            classGroup: forms.classSelect.name,
+            teacherName: item.teacherName,
+            conent:
+              lessonCourseware.lessonCoursewareName +
+              ' | ' +
+              lessonCourseware.lessonCoursewareDetailName +
+              ' | ' +
+              lessonCourseware.lessonCoursewareKnowledgeDetailName,
+            image: item.teacherAvatar
+          });
+        });
+
+        teachList.value = dateTime;
+      } catch (e: any) {
+        //
+        console.log(e);
+      }
+
+      forms.classLoading = false;
+    };
+
+    onMounted(async () => {
+      await getClassList();
+
+      await catchStore.getSubjects();
+
+      await getCourseSchedulePage();
+      forms.subjectList = catchStore.getSubjectList.map((item: any) => {
+        return {
+          label: item.name,
+          value: item.id
+        };
+      });
+      getVersion();
+    });
+
+    const formsRef = ref();
+    const gotoClassPage = () => {
+      formsRef.value.validate(async (error: any) => {
+        if (error) return;
+        try {
+          const { data } = await queryCourseware({
+            coursewareDetailKnowledgeId: forms.unit,
+            subjectId: forms.subjectId,
+            page: 1,
+            rows: 99
+          });
+          if (data.rows && data.rows.length > 0) {
+            await courseScheduleStart({
+              lessonCoursewareKnowledgeDetailId: forms.unit,
+              classGroupId: forms.applyClassItem?.classGroupId
+            });
+
+            const { href } = router.resolve({
+              path: '/attend-class',
+              query: {
+                type: 'class',
+                classGroupId: forms.applyClassItem?.classGroupId,
+                subjectId: forms.subjectId,
+                detailId: forms.unit
+              }
+            });
+            window.open(href, +new Date() + '');
+          } else {
+            message.error('当前章节暂无课件,请重新选择');
+          }
+        } catch {
+          //
+        }
+      });
+    };
+
     return () => (
       <div class={styles.homeWrap}>
         <div class={styles.homeInfoLeft}>
@@ -82,7 +330,7 @@ export default defineComponent({
             <div class={styles.welcomeInfo}>
               <div class={styles.userInfo}>
                 <div class={styles.userName}>
-                  Hi,{userStore.getUserInfo?.nickname} 下午好
+                  Hi,{userStore.getUserInfo?.nickname} {formatDateToDay()}
                 </div>
                 <div class={styles.userTime}>
                   {dayjs().format('MM月DD日')},{weekToCN[dayjs().day()]}
@@ -112,35 +360,115 @@ export default defineComponent({
                   <span
                     class={styles.className}
                     onClick={() => (forms.applyStatus = true)}>
-                    {forms.applyClass || '请选择班级'}
+                    {forms.applyClassItem.name || '请选择班级'}
                   </span>
                   <NAvatarGroup options={forms.studentList} max={5} />
                 </div>
-                <div class={styles.informations}>{bookInfo.value}</div>
+                <div class={styles.informations}>
+                  {forms.applyClassItem.lastStudy ? (
+                    <>
+                      上次课程:
+                      <TheNoticeBar text={forms.applyClassItem.lastStudy} />
+                    </>
+                  ) : (
+                    ''
+                  )}
+                </div>
 
-                <NForm showLabel={false}>
-                  <NFormItem>
+                <NForm showLabel={false} ref={formsRef} model={forms}>
+                  <NFormItem
+                    path="bookVersionId"
+                    rule={[
+                      {
+                        required: true,
+                        message: '',
+                        trigger: ['blur', 'change']
+                      }
+                    ]}>
                     <div class={styles.selectContainer}>
                       <img src={iconLession} />
-                      <NSelect placeholder="请选择教材版本" />
+                      <NSelect
+                        placeholder="请选择教材版本"
+                        disabled={
+                          forms.applyClassItem?.currentGradeNum ? false : true
+                        }
+                        clearable
+                        options={[...forms.musicTagList]}
+                        labelField="name"
+                        valueField="id"
+                        v-model:value={forms.bookVersionId}
+                        onUpdate:value={() => throttledFn()}
+                      />
                     </div>
                   </NFormItem>
-                  <NFormItem>
+                  <NFormItem
+                    path="category"
+                    rule={[
+                      {
+                        required: true,
+                        message: '',
+                        trigger: ['blur', 'change']
+                      }
+                    ]}>
                     <div class={styles.selectContainer}>
                       <img src={iconBook} />
-                      <NSelect placeholder="请选择册别" />
+                      <NSelect
+                        placeholder="请选择册别"
+                        options={[...forms.list]}
+                        clearable
+                        disabled={!forms.bookVersionId}
+                        v-model:value={forms.category}
+                        onUpdate:value={() => getunitList()}
+                      />
                     </div>
                   </NFormItem>
-                  <NFormItem>
+                  <NFormItem
+                    path="unit"
+                    rule={[
+                      {
+                        required: true,
+                        message: '',
+                        trigger: ['blur', 'change']
+                      }
+                    ]}>
                     <div class={styles.selectContainer}>
                       <img src={iconDetail} />
-                      <NSelect placeholder="请选择章节" />
+                      <NCascader
+                        disabled={!forms.category}
+                        {...({
+                          options: [...forms.unitList],
+                          placeholder: '选择单元',
+                          clearable: true
+                        } as any)}
+                        childrenField="knowledgeList"
+                        valueField="id"
+                        labelField="name"
+                        v-model:value={forms.unit}
+                        checkStrategy="child"
+                        expandTrigger="hover"
+                      />
                     </div>
                   </NFormItem>
-                  <NFormItem>
+                  <NFormItem
+                    path="subjectId"
+                    rule={[
+                      {
+                        required: true,
+                        message: '',
+                        trigger: ['blur', 'change'],
+                        type: 'number'
+                      }
+                    ]}>
                     <div class={styles.selectContainer}>
                       <img src={iconSubject} />
-                      <NSelect placeholder="请选择声部" />
+                      <NSelect
+                        {...({
+                          options: [...forms.subjectList],
+                          placeholder: '选择乐器',
+                          clearable: true
+                        } as any)}
+                        v-model:value={forms.subjectId}
+                      />
                     </div>
                   </NFormItem>
                   <NSpace class={styles.btnGroup} justify="center">
@@ -148,7 +476,8 @@ export default defineComponent({
                       round
                       block
                       class={styles.startClass}
-                      color="#FF6E4C">
+                      color="#FF6E4C"
+                      onClick={gotoClassPage}>
                       开始上课
                     </NButton>
                     <NButton
@@ -203,31 +532,73 @@ export default defineComponent({
                 <NImage
                   previewDisabled
                   class={styles.defultHeade}
-                  src={defultHeade}></NImage>
+                  src={userStore.getUserInfo.avatar || defultHeade}></NImage>
               </div>
             </div>
             <div class={styles.headerInfo}>
-              <p class={styles.headerTitle}>张晚意</p>
-              <p class={styles.headerSubTitle}>武汉小学 | 音乐老师</p>
+              <p class={styles.headerTitle}>{userStore.getUserInfo.nickname}</p>
+              {userStore.getUserInfo.schoolInfos &&
+                userStore.getUserInfo.schoolInfos.length > 0 && (
+                  <p class={styles.headerSubTitle}>
+                    {userStore.getUserInfo.schoolInfos[0].name}
+                    {/* | 音乐老师 */}
+                  </p>
+                )}
             </div>
             <div class={styles.rightTeachingWrapTitle}>
               <h3 class={styles.rightTitle}>
                 <div class={styles.titleDot}></div>使用记录
               </h3>
-              <div class={styles.lookMore}>
-                三年级2班
-                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
-                  <path
-                    d="M6 9l6 6l6-6"
-                    fill="none"
-                    stroke="currentColor"
-                    stroke-width="2"
-                    stroke-linecap="round"
-                    stroke-linejoin="round"></path>
-                </svg>
-              </div>
+              {forms.classSelect.name && (
+                <div
+                  class={styles.lookMore}
+                  onClick={() => (forms.useStatus = true)}>
+                  {forms.classSelect.name}
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+                    <path
+                      d="M6 9l6 6l6-6"
+                      fill="none"
+                      stroke="currentColor"
+                      stroke-width="2"
+                      stroke-linecap="round"
+                      stroke-linejoin="round"></path>
+                  </svg>
+                </div>
+              )}
             </div>
-            <TeachList></TeachList>
+            <NSpin show={forms.classLoading} style={{ minHeight: '40vh' }}>
+              {Object.keys(teachList.value).length > 0 && (
+                <div class={styles.teachListWrap}>
+                  {Object.keys(teachList.value).map(key => (
+                    <TeachGroup
+                      list={teachList.value[key]}
+                      keys={key}></TeachGroup>
+                  ))}
+                  {forms.total > 6 && (
+                    <div class={styles.teachListWrapWall}>
+                      <span
+                        onClick={() => {
+                          setTabsCaches('attendclass', 'tabName', {
+                            path: '/classDetail'
+                          });
+                          router.push({
+                            path: '/classDetail',
+                            query: {
+                              name: forms.classSelect.name,
+                              id: forms.classSelect.currentClass
+                            }
+                          });
+                        }}>
+                        查看全部
+                      </span>
+                    </div>
+                  )}
+                </div>
+              )}
+
+              {Object.keys(teachList.value).length <= 0 &&
+                !forms.classLoading && <TheEmpty />}
+            </NSpin>
           </div>
         </div>
 
@@ -237,13 +608,36 @@ export default defineComponent({
           preset="card"
           showIcon={false}
           class={['modalTitle background', styles.assignHomework]}
-          title={'选择级'}
+          title={'选择级'}
           blockScroll={false}>
           <SelectClass
+            useDetail={{
+              currentGradeNum: forms.applyClassItem.currentGradeNum,
+              classGroupId: forms.applyClassItem.classGroupId
+            }}
+            gradeList={forms.gradeList}
             onConfirm={(item: any) => onApplyConfirm(item)}
             onClose={() => (forms.applyStatus = false)}
           />
         </NModal>
+
+        <NModal
+          v-model:show={forms.useStatus}
+          preset="card"
+          showIcon={false}
+          class={['modalTitle background', styles.assignHomework]}
+          title={'选择班级'}
+          blockScroll={false}>
+          <SelectClass
+            useDetail={{
+              currentGradeNum: forms.classSelect.currentGradeNum,
+              classGroupId: forms.classSelect.currentClass
+            }}
+            gradeList={forms.gradeList}
+            onConfirm={(item: any) => onUseConfirm(item)}
+            onClose={() => (forms.useStatus = false)}
+          />
+        </NModal>
       </div>
     );
   }

+ 34 - 23
src/views/home/modals/selectClass.tsx

@@ -1,39 +1,37 @@
-import { defineComponent, reactive, ref } from 'vue';
+import { defineComponent, onMounted, reactive, ref, watch } from 'vue';
 import styles from '../index.module.less';
 import { NButton, NForm, NFormItem, NSelect, NSpace } from 'naive-ui';
-import { BOOK_DATA } from '/src/views/natural-resources/model/add-teaching';
-import { classGroupPage } from '../../prepare-lessons/api';
 
 export default defineComponent({
   name: 'select-class',
+  props: {
+    gradeList: {
+      type: Array,
+      default: () => []
+    },
+    useDetail: {
+      type: Object,
+      default: () => ({})
+    }
+  },
   emits: ['close', 'confirm'],
   setup(props, { emit }) {
     const forms = reactive({
       id: null as any,
       uploading: false,
       classList: [] as any,
-      currentGradeNum: null,
-      classGroupId: null as any
+      currentGradeNum: props.useDetail.currentGradeNum || null,
+      classGroupId: props.useDetail.classGroupId || null
     });
     const formsRef = ref();
 
     const getClassList = async () => {
       try {
-        const { data } = await classGroupPage({
-          currentGradeNum: forms.currentGradeNum,
-          page: 1,
-          rows: 99
+        props.gradeList.forEach((item: any) => {
+          if (item.value === forms.currentGradeNum) {
+            forms.classList = item.childrens;
+          }
         });
-        const temp = data.rows || [];
-        const classList = [] as any;
-        temp.forEach((row: any) => {
-          classList.push({
-            label: row.currentClass + '班',
-            value: row.id
-          });
-        });
-
-        forms.classList = classList;
       } catch {
         //
       }
@@ -46,23 +44,25 @@ export default defineComponent({
         forms.uploading = true;
         try {
           let gradeName = '';
-          BOOK_DATA.grades.forEach((item: any) => {
+          props.gradeList.forEach((item: any) => {
             if (forms.currentGradeNum === item.value) {
               gradeName = item.label;
             }
           });
 
           let className = '';
+          let lastStudy = '';
           forms.classList.forEach((item: any) => {
             if (item.value === forms.classGroupId) {
               className = item.label;
+              lastStudy = item.lastStudy;
             }
           });
           emit('confirm', {
             currentGradeNum: forms.currentGradeNum, // 年级
-            currentGradeLabel: gradeName,
             classGroupId: forms.classGroupId, // 班级
-            className
+            name: gradeName + className,
+            lastStudy
           });
           emit('close');
         } catch {
@@ -72,6 +72,17 @@ export default defineComponent({
       });
     };
 
+    watch(
+      () => props.useDetail,
+      () => {
+        forms.currentGradeNum = props.useDetail.currentGradeNum;
+        forms.classGroupId = props.useDetail.classGroupId;
+      }
+    );
+
+    onMounted(() => {
+      getClassList();
+    });
     return () => (
       <div class={styles.assignHomeworkContainer}>
         <NForm
@@ -94,7 +105,7 @@ export default defineComponent({
             <NSelect
               v-model:value={forms.currentGradeNum}
               placeholder="请选择年级"
-              options={BOOK_DATA.grades}
+              options={props.gradeList as any}
               clearable
               onUpdate:value={() => {
                 forms.classGroupId = null;

+ 7 - 1
src/views/prepare-lessons/model/attend-class/index.tsx

@@ -58,7 +58,13 @@ export default defineComponent({
           rows: 99,
           ...forms
         });
-        list.value = data.rows || [];
+        const result = data.rows || [];
+        result.forEach((item: any) => {
+          // 判断班级里面有学生的
+          if (item.preStudentNum > 0) {
+            list.value.push(item);
+          }
+        });
       } catch {
         //
       }