mo 1 year ago
parent
commit
5765f3a1ca

+ 18 - 0
src/views/classList/api.ts

@@ -122,3 +122,21 @@ export const courseSchedulePage = (params: any) => {
     data: params
   });
 };
+
+/**
+ * 开始上课 获取章节
+ */
+export const getCourseChapter = (params: any) => {
+  return request.get(`/edu-app/lessonCourseware/detail/${params}`);
+};
+
+/**
+ * 获取学生训练详情
+ */
+
+export const getTrainingStudentDetail = (params: any) => {
+  return request.get(`/edu-app/lessonTraining/trainingStudentDetail`, {
+    params,
+    requestType: 'form'
+  });
+};

+ 26 - 2
src/views/classList/components/afterWorkDetail.tsx

@@ -6,6 +6,7 @@ import {
   NForm,
   NFormItem,
   NImage,
+  NModal,
   NSelect,
   NSpace
 } from 'naive-ui';
@@ -24,7 +25,9 @@ import {
   getTimes
 } from '/src/utils/dateFormat';
 import { trainingStatusArray } from '@/utils/searchArray';
+import TrainingDetails from '../modals/TrainingDetails';
 import dayjs from 'dayjs';
+import { lookup } from 'dns';
 export default defineComponent({
   name: 'student-studentList',
   setup(props, { emit }) {
@@ -42,7 +45,9 @@ export default defineComponent({
         expireDate: '',
         teacherAvatar: '',
         teacherName: ''
-      }
+      },
+      detailVisiable: false,
+      activeRow: null as any
     });
     const timer = ref<[number, number]>([
       getNowDateAndMonday(new Date().getTime()),
@@ -97,6 +102,11 @@ export default defineComponent({
         console.log(e);
       }
     };
+
+    const lookDetail = (row: any) => {
+      state.activeRow = row;
+      state.detailVisiable = true;
+    };
     onMounted(() => {
       getWorkInfo();
       getList();
@@ -140,7 +150,12 @@ export default defineComponent({
           key: 'id',
           render(row: any) {
             return (
-              <NButton text type="primary">
+              <NButton
+                text
+                type="primary"
+                onClick={() => {
+                  lookDetail(row);
+                }}>
                 详情
               </NButton>
             );
@@ -257,6 +272,15 @@ export default defineComponent({
             />
           </div>
         </div>
+        <NModal
+          v-model:show={state.detailVisiable}
+          preset="card"
+          class={['modalTitle background', styles.wordDetailModel]}
+          title={'训练详情'}>
+          <TrainingDetails
+            onClose={() => (state.detailVisiable = false)}
+            activeRow={state.activeRow}></TrainingDetails>
+        </NModal>
       </div>
     );
   }

+ 7 - 7
src/views/classList/contants.ts

@@ -1,15 +1,15 @@
 export const threeYearSystem = [
   { label: '全部年级', value: null },
-  { label: '七年级', value: 1 },
-  { label: '八年级', value: 2 },
-  { label: '九年级', value: 3 }
+  { label: '七年级', value: 7 },
+  { label: '八年级', value: 8 },
+  { label: '九年级', value: 9 }
 ];
 export const foreYearSystem = [
   { label: '选择年级', value: null },
-  { label: '六年级', value: 1 },
-  { label: '七年级', value: 2 },
-  { label: '八年级', value: 3 },
-  { label: '九年级', value: 4 }
+  { label: '六年级', value: 6 },
+  { label: '七年级', value: 7 },
+  { label: '八年级', value: 8 },
+  { label: '九年级', value: 9 }
 ];
 export const fiveYearSystem = [
   { label: '选择年级', value: null },

BIN
src/views/classList/images/nosub.png


BIN
src/views/classList/images/qualified.png


BIN
src/views/classList/images/unqualified.png


+ 208 - 60
src/views/classList/index.module.less

@@ -1,4 +1,5 @@
 @img: '../setting/images';
+@currentimg './images'
 .listWrap {
   padding: 32px;
   background-color: #fff;
@@ -129,66 +130,66 @@
           }
         }
       }
-      .n-legacy-transfer-gap {
-        width: 80px;
-        .n-button {
-          width: 34px;
-          height: 34px;
-          border-radius: 8px;
-          .n-button__state-border {
-            border: none !important;
-          }
-          &:nth-child(1) {
-            transform: rotate(180deg);
-            position: relative;
-            &:hover {
-              &::after {
-                background: url('@{img}/transArrowActive.png') no-repeat;
-                top: 0;
-                left: 0;
+      // .n-legacy-transfer-gap {
+      //   width: 80px;
+      //   .n-button {
+      //     width: 34px;
+      //     height: 34px;
+      //     border-radius: 8px;
+      //     .n-button__state-border {
+      //       border: none !important;
+      //     }
+      //     &:nth-child(1) {
+      //       transform: rotate(180deg);
+      //       position: relative;
+      //       &:hover {
+      //         &::after {
+      //           background: url('@{currentimg}/transArrowActive.png') no-repeat;
+      //           top: 0;
+      //           left: 0;
 
-                background-size: 34px 34px;
-              }
-            }
-            &::after {
-              position: absolute;
-              content: '';
-              width: 34px;
-              height: 34px;
-              background-color: black;
-              top: 0;
-              left: 0;
-              background: url('@{img}/transArrrow.png') no-repeat;
-              background-size: 34px 34px;
-              z-index: 100;
-            }
-          }
-          &:nth-child(2) {
-            position: relative;
-            &:hover {
-              &::after {
-                background: url('@{img}/transArrowActive.png') no-repeat;
-                top: 0;
-                left: 0;
+      //           background-size: 34px 34px;
+      //         }
+      //       }
+      //       &::after {
+      //         position: absolute;
+      //         content: '';
+      //         width: 34px;
+      //         height: 34px;
+      //         background-color: black;
+      //         top: 0;
+      //         left: 0;
+      //         background: url('@{currentimg}/transArrrow.png') no-repeat;
+      //         background-size: 34px 34px;
+      //         z-index: 100;
+      //       }
+      //     }
+      //     &:nth-child(2) {
+      //       position: relative;
+      //       &:hover {
+      //         &::after {
+      //           background: url('@{currentimg}/transArrowActive.png') no-repeat;
+      //           top: 0;
+      //           left: 0;
 
-                background-size: 34px 34px;
-              }
-            }
-            &::after {
-              position: absolute;
-              content: '';
-              width: 100%;
-              height: 100%;
-              background-color: black;
-              top: 0;
-              left: 0;
-              background: url('@{img}/transArrrow.png') no-repeat;
-              background-size: 34px 34px;
-              z-index: 100;
-            }
-          }
-        }
-      }
+      //           background-size: 34px 34px;
+      //         }
+      //       }
+      //       &::after {
+      //         position: absolute;
+      //         content: '';
+      //         width: 100%;
+      //         height: 100%;
+      //         background-color: black;
+      //         top: 0;
+      //         left: 0;
+      //         background: url('@{img}/transArrrow.png') no-repeat;
+      //         background-size: 34px 34px;
+      //         z-index: 100;
+      //       }
+      //     }
+      //   }
+      // }
     }
     .studentTransferBottom {
       width: 100%;
@@ -259,10 +260,10 @@
       width: 34px;
       height: 34px;
       border-radius: 8px;
-      background: url('@{img}/transArrrow.png') no-repeat;
+      background: url('./images/transArrrow.png') no-repeat;
       background-size: 34px 34px;
       &:hover {
-        background: url('@{img}/transArrowActive.png') no-repeat;
+        background: url('./images/transArrowActive.png') no-repeat;
         background-size: 34px 34px;
       }
     }
@@ -470,3 +471,150 @@
     height: 20px;
   }
 }
+
+.chioseModel {
+  width: 413px;
+
+  :global {
+    .n-select {
+      width: 100%;
+      min-width: 180px;
+
+      .n-base-selection-label {
+        height: 43px;
+        line-height: 43px;
+      }
+
+      .n-base-selection__border {
+        border-radius: 8px;
+        overflow: hidden;
+      }
+
+      .n-base-selection__state-border {
+        border-radius: 8px;
+        overflow: hidden;
+      }
+    }
+
+    .n-card-header {
+      position: relative;
+      padding: 20px 18px;
+      text-align: center;
+      // background: #F5F6FA;
+      font-size: 22px;
+      font-weight: 600;
+      color: #131415;
+      line-height: 30px;
+    }
+
+    .n-card-header__close {
+      position: absolute;
+      right: 18px;
+    }
+
+    .n-card__content {
+      // padding: 28px;
+      padding: 30px;
+    }
+  }
+
+  .updateBtnGroup {
+    padding: 0;
+    justify-content: center !important;
+
+    :global {
+      .n-button {
+        height: 48px !important;
+        min-width: 156px;
+      }
+    }
+  }
+}
+.wordDetailModel {
+  width: 1012px;
+}
+.trainingDetails {
+  padding: 24px 32px 32px;
+  .studentList {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 24px;
+    justify-content: space-between;
+    border-bottom: 1px solid #f2f2f2;
+    padding-bottom: 18px;
+    .studentHeaderWrap {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+
+      .studentHeader {
+        width: 66px;
+        height: 66px;
+        padding: 2px;
+        border-radius: 99px;
+        background: linear-gradient(
+          228deg,
+          rgba(2, 186, 255, 1),
+          rgba(0, 122, 254, 1)
+        );
+        margin-right: 16px;
+        .studentHeaderBorder {
+          width: 100%;
+          height: 100%;
+          background: #fff;
+          border-radius: 99px;
+          overflow: hidden;
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          justify-content: center;
+          padding: 4px;
+        }
+      }
+    }
+    .workStatus {
+      width: 87px;
+      height: 87px;
+    }
+    .studentHeaderImg {
+      width: 66px;
+      height: 66px;
+      border-radius: 50%;
+      overflow: hidden;
+    }
+    .workafterInfo {
+      h4 {
+        font-size: 22px;
+        line-height: 30px;
+        line-height: 30px;
+        font-weight: 600;
+        color: #131415;
+        margin-bottom: 12px;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        .workafterInfoDot {
+          width: 52px;
+          height: 22px;
+          background: #ff8a32;
+          border-radius: 13px 4px 13px 4px;
+          font-size: 14px;
+          font-weight: 600;
+          color: #ffffff;
+          line-height: 22px;
+          text-align: center;
+          margin-left: 8px;
+        }
+      }
+      p {
+        font-size: 16px;
+        line-height: 22px;
+        color: #777;
+        span {
+          color: #ea4132;
+        }
+      }
+    }
+  }
+}

+ 23 - 2
src/views/classList/index.tsx

@@ -19,6 +19,7 @@ import { classGroupList, deleteClass } from './api';
 import { useUserStore } from '/src/store/modules/users';
 import CreateClass from './modals/createClass';
 import RestStudentBox from './modals/restStudentBox';
+import TrainDetail from './modals/Gotoclass';
 import {
   sixYearSystem,
   fiveYearSystem,
@@ -29,6 +30,7 @@ import {
 } from './contants';
 import add from '@/views/studentList/images/add.png';
 import { useRouter } from 'vue-router';
+import { rowDark } from 'naive-ui/es/legacy-grid/styles';
 export default defineComponent({
   name: 'class-classList',
   setup(props, { emit }) {
@@ -51,7 +53,8 @@ export default defineComponent({
       tableList: [] as any,
       studentVisible: false,
       activeRow: null as any,
-      showaddClass: false
+      showaddClass: false,
+      goCourseVisiable: false
     });
     const formRef = ref();
     const dialog = useDialog();
@@ -167,7 +170,10 @@ export default defineComponent({
                     }}>
                     学生调整
                   </NButton>
-                  <NButton type="primary" text>
+                  <NButton
+                    type="primary"
+                    text
+                    onClick={() => classesBegin(row)}>
                     开始上课
                   </NButton>
                   {!(row.preStudentNum > 0) ? (
@@ -189,6 +195,12 @@ export default defineComponent({
       state.activeRow = row;
       state.studentVisible = true;
     };
+
+    const classesBegin = (row: any) => {
+      state.activeRow = row;
+      state.goCourseVisiable = true;
+      console.log('classesBegin');
+    };
     onMounted(() => {
       getList();
     });
@@ -295,6 +307,15 @@ export default defineComponent({
             onClose={() => (state.showaddClass = false)}
           />
         </NModal>
+
+        <NModal
+          v-model:show={state.goCourseVisiable}
+          preset="card"
+          class={['modalTitle background', styles.chioseModel]}
+          title={'选择课件'}>
+          <TrainDetail
+            onClose={() => (state.goCourseVisiable = false)}></TrainDetail>
+        </NModal>
       </div>
     );
   }

+ 268 - 0
src/views/classList/modals/Gotoclass.tsx

@@ -0,0 +1,268 @@
+import { defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from '../index.module.less';
+import {
+  NButton,
+  NForm,
+  NFormItem,
+  NSelect,
+  NSpace,
+  useMessage
+} from 'naive-ui';
+import {
+  bookVersionPage,
+  lessonCoursewarePage,
+  queryCourseware
+} from '@/views/prepare-lessons/api';
+import { useRouter } from 'vue-router';
+import { useThrottleFn } from '@vueuse/core';
+import { getCourseChapter } from '../api';
+import { useCatchStore } from '/src/store/modules/catchData';
+export default defineComponent({
+  name: 'train-update',
+  emits: ['close'],
+  props: {
+    activeRow: {
+      type: Object,
+      default: () => ({ id: '', currentGradeNum: '' })
+    }
+  },
+  setup(props, { emit }) {
+    // 'practice' | 'evaluation'
+    const forms = reactive({
+      bookVersionId: null,
+      classGroupId: null,
+      category: null,
+      chapter: null,
+      subjectId: null,
+      musicTagList: [] as any,
+      loading: false,
+      list: [] as any,
+      chapterList: [] as any,
+      unit: null,
+      unitList: [],
+      subjectList: [] as any
+    });
+    const router = useRouter();
+    const catchStore = useCatchStore();
+    const message = useMessage();
+    const gotoClassPage = () => {
+      formsRef.value.validate(async (error: any) => {
+        if (error) return;
+        const { data } = await queryCourseware({
+          coursewareDetailKnowledgeId: forms.chapter,
+          subjectId: forms.subjectId,
+          page: 1,
+          rows: 99
+        });
+        console.log('gotoClassPage', data);
+        if (data.rows && data.rows.length > 0) {
+          const { href } = router.resolve({
+            path: '/attend-class',
+            query: {
+              type: 'class',
+              classGroupId: props.activeRow.id,
+              subjectId: forms.subjectId,
+              detailId: forms.chapter
+            }
+          });
+          emit('close');
+          window.open(href, +new Date() + '');
+        } else {
+          message.error('当前章节没有课件,请重新学则');
+        }
+      });
+
+      /**
+       *         query: {
+            type: 'class',
+            classGroupId: item.id,
+            subjectId: prepareStore.getSubjectId,
+            detailId: prepareStore.getSelectKey // 章节id
+          }
+       */
+    };
+
+    const formsRef = ref();
+    const throttledFn = useThrottleFn(() => getLessonCourseware(), 500);
+    const getLessonCourseware = async () => {
+      forms.category = null;
+      forms.unit = null;
+      forms.category = null;
+      forms.chapter = null;
+      forms.loading = true;
+
+      if (forms.bookVersionId) {
+        try {
+          const { data } = await lessonCoursewarePage({
+            page: 1,
+            rows: 99,
+            type: 'COURSEWARE',
+            enableFlag: 1,
+            bookVersionId: forms.bookVersionId,
+            currentGradeNum: props.activeRow.currentGradeNum
+          });
+
+          forms.list = data.rows.map((item: any) => {
+            return {
+              label: item.name,
+              value: item.id
+            };
+          });
+        } catch {
+          //
+        }
+      } else {
+        forms.list = [];
+      }
+
+      forms.loading = false;
+    };
+    const getVersion = async () => {
+      forms.unit = null;
+      forms.chapter = 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 getunitList = async () => {
+      forms.unit = null;
+      forms.chapter = 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 getchapterList = () => {
+      forms.chapter = null;
+      if (forms.unit) {
+        const item: any = forms.unitList.find((item: any) => {
+          return item.id === forms.unit;
+        });
+        forms.chapterList = item.knowledgeList.map((know: any) => {
+          return { ...know, label: know.name, value: know.id };
+        });
+        console.log('getchapterList', item);
+      } else {
+        forms.chapterList = [];
+      }
+      console.log('getchapterList');
+    };
+    onMounted(async () => {
+      await catchStore.getSubjects();
+      forms.subjectList = catchStore.getSubjectList.map((item: any) => {
+        return {
+          label: item.name,
+          value: item.id
+        };
+      });
+      getVersion();
+    });
+    return () => (
+      <div class={styles.trainUpdate}>
+        <NForm
+          labelAlign="left"
+          labelPlacement="left"
+          ref={formsRef}
+          model={forms}>
+          <NFormItem
+            path="bookVersionId"
+            rule={[{ required: true, message: '选择教材版本' }]}>
+            <NSelect
+              placeholder="选择教材版本"
+              clearable
+              options={[...forms.musicTagList]}
+              labelField="name"
+              valueField="id"
+              v-model:value={forms.bookVersionId}
+              onUpdate:value={() => throttledFn()}
+            />
+          </NFormItem>
+          <NFormItem
+            path="category"
+            rule={[{ required: true, message: '请选择册别' }]}>
+            <NSelect
+              {...({
+                options: [...forms.list],
+                placeholder: '选择册别',
+                clearable: true
+              } as any)}
+              disabled={!forms.bookVersionId}
+              v-model:value={forms.category}
+              onUpdate:value={() => getunitList()}></NSelect>
+          </NFormItem>
+          <NFormItem
+            path="unit"
+            rule={[{ required: true, message: '请选择单元' }]}>
+            <NSelect
+              disabled={!forms.category}
+              {...({
+                options: [...forms.unitList],
+                placeholder: '选择单元',
+                clearable: true
+              } as any)}
+              v-model:value={forms.unit}
+              onUpdate:value={() => getchapterList()}></NSelect>
+          </NFormItem>
+          <NFormItem
+            path="chapter"
+            rule={[{ required: true, message: '请选择章节' }]}>
+            <NSelect
+              disabled={!forms.unit}
+              {...({
+                options: [...forms.chapterList],
+                placeholder: '选择章节',
+                clearable: true
+              } as any)}
+              v-model:value={forms.chapter}></NSelect>
+          </NFormItem>
+          <NFormItem
+            path="subjectId"
+            rule={[{ required: true, message: '请选择乐器' }]}>
+            <NSelect
+              {...({
+                options: [...forms.subjectList],
+                placeholder: '选择乐器',
+                clearable: true
+              } as any)}
+              v-model:value={forms.subjectId}></NSelect>
+          </NFormItem>
+          <NSpace class={styles.updateBtnGroup}>
+            <NButton strong type="default" round onClick={() => emit('close')}>
+              取消
+            </NButton>
+            <NButton
+              strong
+              type="primary"
+              round
+              onClick={() => gotoClassPage()}>
+              确认
+            </NButton>
+          </NSpace>
+        </NForm>
+      </div>
+    );
+  }
+});

+ 104 - 0
src/views/classList/modals/TrainingDetails.tsx

@@ -0,0 +1,104 @@
+import {
+  NButton,
+  NSpace,
+  useMessage,
+  NForm,
+  NFormItem,
+  NSelect,
+  NImage
+} from 'naive-ui';
+import { defineComponent, onMounted, reactive, ref } from 'vue';
+import { getTrainingStudentDetail } from '../api';
+import styles from '../index.module.less';
+import trainType from '@/views/attend-class/model/train-type';
+import defultHeade from '@/components/layout/images/teacherIcon.png';
+import noSub from '../images/nosub.png';
+import qualified from '../images/qualified.png';
+import unqualified from '../images/unqualified.png';
+import dayjs from 'dayjs';
+export default defineComponent({
+  props: {
+    activeRow: {
+      type: Object,
+      default: () => ({ studentLessonTrainingId: '' })
+    }
+  },
+  name: 'TrainingDetails',
+  emits: ['close', 'getList'],
+  setup(props, { emit }) {
+    const data = reactive({
+      uploading: false
+    });
+    const studnetInfo = ref({
+      studentName: '',
+      submitTime: '',
+      trainingStatus: '',
+      studentAvatar: '',
+      studentLessonTrainingDetails: [] as any
+    } as any);
+    const message = useMessage();
+    const foemsRef = ref();
+    const getTrainingDetail = async () => {
+      try {
+        const res = await getTrainingStudentDetail({
+          studentLessonTrainingId: props.activeRow.studentLessonTrainingId
+        });
+
+        studnetInfo.value = { ...res.data };
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    onMounted(() => {
+      getTrainingDetail();
+    });
+    return () => (
+      <div class={[styles.trainingDetails]}>
+        <div class={styles.studentList}>
+          <div class={styles.studentHeaderWrap}>
+            <div class={styles.studentHeader}>
+              <div class={styles.studentHeaderBorder}>
+                <NImage
+                  class={styles.studentHeaderImg}
+                  src={
+                    studnetInfo.value.studentAvatar
+                      ? studnetInfo.value.studentAvatar
+                      : defultHeade
+                  }
+                  previewDisabled></NImage>
+              </div>
+            </div>
+
+            <div class={styles.workafterInfo}>
+              <h4>
+                {studnetInfo.value.studentName}{' '}
+                <div class={styles.workafterInfoDot}>学生</div>
+              </h4>
+              <p>
+                提交时间:
+                {studnetInfo.value.submitTime
+                  ? dayjs(new Date(studnetInfo.value.submitTime)).format(
+                      'YYYY-MM-DD'
+                    )
+                  : '--'}
+              </p>
+            </div>
+          </div>
+          <NImage
+            previewDisabled
+            class={styles.workStatus}
+            src={noSub}></NImage>
+        </div>
+        <div class={styles.workList}></div>
+        <NSpace class={styles.btnGroup} justify="center">
+          <NButton round onClick={() => emit('close')}>
+            取消
+          </NButton>
+          <NButton round loading={data.uploading} type="primary">
+            保存
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});