mo 1 jaar geleden
bovenliggende
commit
0fd3a342ec

+ 53 - 15
src/views/attend-class/model/train-type/index.module.less

@@ -1,7 +1,7 @@
 .trainType {
   display: inline-block;
   width: 462px;
-  background: #ECF6FF;
+  background: #ecf6ff;
   border-radius: 16px;
   padding: 20px;
   position: relative;
@@ -45,10 +45,10 @@
   .btn {
     padding: 0 12px;
     height: 32px;
-    background: linear-gradient(270deg, #23C3FF 0%, #007AFE 100%);
+    background: linear-gradient(270deg, #23c3ff 0%, #007afe 100%);
     font-size: 16px;
     font-weight: 600;
-    color: #FFFFFF;
+    color: #ffffff;
     line-height: 22px;
     --n-border: 0 !important;
     --n-border-hover: 0 !important;
@@ -89,9 +89,9 @@
 .train-content {
   margin: 20px 0;
   height: 238px;
-  background: #FFFFFF;
+  background: #ffffff;
   border-radius: 11px;
-  border: 1px solid #74BAFF;
+  border: 1px solid #74baff;
   position: relative;
   overflow: hidden;
 
@@ -115,11 +115,11 @@
     left: 0;
     right: 0;
     bottom: 0;
-    background-color: rgba(0, 0, 0, .7);
+    background-color: rgba(0, 0, 0, 0.7);
     display: flex;
     align-items: center;
     justify-content: center;
-    transition: all .2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
 
     .previewBtn {
       background: #fff;
@@ -129,11 +129,49 @@
     }
   }
 
+  .disPreview {
+    position: absolute;
+    // opacity: 0;
+    // visibility: hidden;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.7);
+    display: flex;
+    align-items: center;
+    flex-direction: column;
+    justify-content: center;
+    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+    .disPreviewDivide {
+      font-size: 15px;
+      color: #fff;
+    }
+    :global {
+      .n-progress-graph-circle-rail {
+        stroke: #8b8b8b !important;
+      }
+    }
+    .BProgress {
+      color: #fff;
+      h4 {
+        font-size: 28px;
+        font-family: 'DINA';
+        font-weight: bold;
+        text-align: center;
+        span {
+          font-size: 12px;
+          font-weight: 400;
+        }
+      }
+    }
+  }
+
   &:hover {
     .preview {
       opacity: 1;
       visibility: visible;
-      transition: all .3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+      transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
     }
   }
 }
@@ -151,9 +189,9 @@
     .n-tag {
       font-size: 14px;
       font-weight: 500;
-      color: #0378EC;
+      color: #0378ec;
       line-height: 20px;
-      border: 1px solid #198CFE;
+      border: 1px solid #198cfe;
       border-radius: 6px;
       background-color: transparent;
       height: 28px;
@@ -173,10 +211,10 @@
 }
 
 .evaluationType {
-  background: #FFF0EB;
+  background: #fff0eb;
 
   .btn {
-    background: linear-gradient(270deg, #FF7B57 0%, #FF3460 100%);
+    background: linear-gradient(270deg, #ff7b57 0%, #ff3460 100%);
   }
 
   .train-content {
@@ -186,9 +224,9 @@
   .train-footer {
     :global {
       .n-tag {
-        color: #F92D53;
-        border: 1px solid #F92D53;
+        color: #f92d53;
+        border: 1px solid #f92d53;
       }
     }
   }
-}
+}

+ 94 - 33
src/views/attend-class/model/train-type/index.tsx

@@ -1,6 +1,14 @@
 import { PropType, defineComponent } from 'vue';
 import styles from './index.module.less';
-import { NButton, NEllipsis, NSpace, NImage, NTag, useDialog } from 'naive-ui';
+import {
+  NButton,
+  NEllipsis,
+  NSpace,
+  NImage,
+  NTag,
+  useDialog,
+  NProgress
+} from 'naive-ui';
 import pTag from './images/p-tag.svg';
 import eTag from './images/e-tag.svg';
 import pEdit from './images/p-edit.svg';
@@ -17,6 +25,8 @@ type ItemType = {
   coverImg: string;
   musicName: string;
   typeList: string[];
+  allTimes?: number;
+  trainingTimes?: number;
 };
 
 export default defineComponent({
@@ -33,6 +43,10 @@ export default defineComponent({
     isDelete: {
       type: Boolean,
       default: false
+    },
+    isDisabled: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['click', 'delete', 'edit'],
@@ -60,6 +74,10 @@ export default defineComponent({
       const src = `${origin}/instrument?platform=pc&modelType=practise`;
       window.open(src, '_blank');
     };
+    function rgba(arg0: number, arg1: number, arg2: number, arg3: number) {
+      throw new Error('Function not implemented.');
+    }
+
     return () => (
       <div
         class={[
@@ -91,25 +109,65 @@ export default defineComponent({
               <img src={iconDelete} />
             </NButton>
           ) : (
-            <NButton class={styles.btn} round onClick={onDetail}>
+            <NButton
+              class={styles.btn}
+              round
+              onClick={() => {
+                if (props.isDisabled) {
+                  return;
+                }
+                onDetail;
+              }}>
               {props.item.trainingType === 'EVALUATION'
                 ? '评测模式'
                 : '练习模式'}
-              <img src={iconPause} />
+              {props.isDisabled ? null : <img src={iconPause} />}
             </NButton>
           )}
         </div>
         <div class={styles['train-content']}>
           <NImage src={props.item.coverImg} previewDisabled objectFit="cover" />
-          <div class={styles.preview}>
-            <NButton
-              strong
-              secondary
-              class={styles.previewBtn}
-              onClick={onDetail}>
-              预览
-            </NButton>
-          </div>
+          {props.isDisabled ? (
+            <div class={styles.disPreview}>
+              <NProgress
+                percentage={
+                  Number(props.item.trainingTimes) / Number(props.item.allTimes)
+                }
+                offset-degree={180}
+                type="circle"
+                rail-color={'8b8b8b'}
+                color={
+                  props.item.trainingType === 'EVALUATION'
+                    ? '#FF7E65'
+                    : '#44B3FF'
+                }
+                style="width: 120px; margin: 0  0 10px;">
+                <div class={styles.BProgress}>
+                  <h4>
+                    {props.item.trainingTimes} <span>分钟</span>{' '}
+                  </h4>
+                  <p>实际练习 </p>
+                </div>
+              </NProgress>
+              <p class={styles.disPreviewDivide}>
+                {props.item.trainingType === 'EVALUATION'
+                  ? '合格分数'
+                  : '练习时长要求'}
+                {props.item.allTimes}
+                {props.item.trainingType === 'EVALUATION' ? '分' : '分钟'}
+              </p>
+            </div>
+          ) : (
+            <div class={styles.preview}>
+              <NButton
+                strong
+                secondary
+                class={styles.previewBtn}
+                onClick={onDetail}>
+                预览
+              </NButton>
+            </div>
+          )}
         </div>
         <div class={styles['train-footer']}>
           <NSpace class={styles.type}>
@@ -117,37 +175,40 @@ export default defineComponent({
               <NTag>{type}</NTag>
             ))}
           </NSpace>
-
-          <NSpace size={6}>
-            <n-button
-              quaternary
-              disabled={props.isDelete}
-              class={styles.operation}
-              onClick={(e: MouseEvent) => {
-                e.stopPropagation();
-                emit('edit', props.item);
-              }}>
-              <img
-                src={props.item.trainingType === 'EVALUATION' ? eEdit : pEdit}
-              />
-            </n-button>
-            {props.type === 'homework' && (
+          {props.isDisabled ? null : (
+            <NSpace size={6}>
               <n-button
                 quaternary
                 disabled={props.isDelete}
                 class={styles.operation}
                 onClick={(e: MouseEvent) => {
                   e.stopPropagation();
-                  onDelete();
+                  emit('edit', props.item);
                 }}>
                 <img
-                  src={
-                    props.item.trainingType === 'EVALUATION' ? eDelete : pDelete
-                  }
+                  src={props.item.trainingType === 'EVALUATION' ? eEdit : pEdit}
                 />
               </n-button>
-            )}
-          </NSpace>
+              {props.type === 'homework' && (
+                <n-button
+                  quaternary
+                  disabled={props.isDelete}
+                  class={styles.operation}
+                  onClick={(e: MouseEvent) => {
+                    e.stopPropagation();
+                    onDelete();
+                  }}>
+                  <img
+                    src={
+                      props.item.trainingType === 'EVALUATION'
+                        ? eDelete
+                        : pDelete
+                    }
+                  />
+                </n-button>
+              )}
+            </NSpace>
+          )}
         </div>
       </div>
     );

+ 24 - 4
src/views/classList/components/afterWorkDetail.tsx

@@ -47,12 +47,14 @@ export default defineComponent({
         teacherName: ''
       },
       detailVisiable: false,
-      activeRow: null as any
+      activeRow: null as any,
+      index: 0
     });
     const timer = ref<[number, number]>([
       getNowDateAndMonday(new Date().getTime()),
       getNowDateAndSunday(new Date().getTime())
     ]);
+    const TrainingDetailsRef = ref();
     const route = useRoute();
     const routerList = ref([
       { name: '班级管理', path: '/classList' },
@@ -103,7 +105,9 @@ export default defineComponent({
       }
     };
 
-    const lookDetail = (row: any) => {
+    const lookDetail = (row: any, index: number) => {
+      console.log(index, 'index');
+      state.index = index + 1;
       state.activeRow = row;
       state.detailVisiable = true;
     };
@@ -148,13 +152,13 @@ export default defineComponent({
         {
           title: '操作',
           key: 'id',
-          render(row: any) {
+          render(row: any, index: number) {
             return (
               <NButton
                 text
                 type="primary"
                 onClick={() => {
-                  lookDetail(row);
+                  lookDetail(row, index);
                 }}>
                 详情
               </NButton>
@@ -163,6 +167,17 @@ export default defineComponent({
         }
       ];
     };
+
+    const goToNext = () => {
+      state.index++;
+      state.activeRow = state.tableList[state.index - 1];
+      TrainingDetailsRef.value.getTrainingDetail();
+    };
+    const gotoPre = () => {
+      state.index--;
+      state.activeRow = state.tableList[state.index - 1];
+      TrainingDetailsRef.value.getTrainingDetail();
+    };
     return () => (
       <div>
         <CBreadcrumb list={routerList.value}></CBreadcrumb>
@@ -278,7 +293,12 @@ export default defineComponent({
           class={['modalTitle background', styles.wordDetailModel]}
           title={'训练详情'}>
           <TrainingDetails
+            onNext={() => goToNext()}
+            onPre={() => gotoPre()}
+            ref={TrainingDetailsRef}
             onClose={() => (state.detailVisiable = false)}
+            total={state.tableList.length}
+            current={state.index}
             activeRow={state.activeRow}></TrainingDetails>
         </NModal>
       </div>

+ 21 - 0
src/views/classList/index.module.less

@@ -617,4 +617,25 @@
       }
     }
   }
+  .workList {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+  }
+  .allTotal {
+    font-size: 16px;
+    font-weight: 400;
+    color: #8b8b8b;
+  }
+  .btnGroups {
+    padding: 40px 0;
+    :global {
+      .n-button {
+        height: 47px;
+        min-width: 96px;
+        border-radius: 8px;
+      }
+    }
+  }
 }

+ 105 - 16
src/views/classList/modals/TrainingDetails.tsx

@@ -10,22 +10,32 @@ import {
 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 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 { evaluateDifficult } from '/src/utils/contants';
 import dayjs from 'dayjs';
 export default defineComponent({
   props: {
     activeRow: {
       type: Object,
       default: () => ({ studentLessonTrainingId: '' })
+    },
+    total: {
+      type: Number,
+      default: 0
+    },
+    current: {
+      type: Number,
+      default: 0
     }
   },
   name: 'TrainingDetails',
-  emits: ['close', 'getList'],
-  setup(props, { emit }) {
+  emits: ['close', 'next', 'pre'],
+
+  setup(props, { emit, expose }) {
     const data = reactive({
       uploading: false
     });
@@ -38,20 +48,59 @@ export default defineComponent({
     } as any);
     const message = useMessage();
     const foemsRef = ref();
+    const typeFormat = (trainingType: string, configJson: any) => {
+      let tList: string[] = [];
+
+      if (trainingType === 'EVALUATION') {
+        tList = [
+          `${evaluateDifficult[configJson.evaluateDifficult]}`,
+          '全部小节',
+          `速度${configJson.evaluateSpeed}`,
+          `${configJson.trainingTimes}分合格`
+        ];
+        console.log('configJson.evaluateDifficult--', tList);
+      } else {
+        tList = [
+          `${configJson.practiceChapterBegin}-${configJson.practiceChapterEnd}小节`,
+          `速度${configJson.practiceSpeed}`,
+          `${configJson.trainingTimes}分钟`
+        ];
+        console.log('configJson.evaluateDifficult', tList);
+      }
+      return tList;
+    };
     const getTrainingDetail = async () => {
       try {
         const res = await getTrainingStudentDetail({
           studentLessonTrainingId: props.activeRow.studentLessonTrainingId
         });
+        const arr = res.data.studentLessonTrainingDetails.map((item: any) => {
+          const tList = typeFormat(
+            item.trainingType,
+            JSON.parse(item.trainingContent)
+          );
+          return {
+            ...item,
+            coverImg: item.titleImg,
+            allTimes: JSON.parse(item.trainingContent).trainingTimes,
+            typeList: tList || []
+          };
+        });
+        studnetInfo.value = {
+          ...res.data,
 
-        studnetInfo.value = { ...res.data };
+          studentLessonTrainingDetails: arr
+        };
+        console.log(studnetInfo.value.studentLessonTrainingDetails);
       } catch (e) {
         console.log(e);
       }
     };
+    expose({ getTrainingDetail });
     onMounted(() => {
       getTrainingDetail();
     });
+
     return () => (
       <div class={[styles.trainingDetails]}>
         <div class={styles.studentList}>
@@ -84,19 +133,59 @@ export default defineComponent({
               </p>
             </div>
           </div>
-          <NImage
-            previewDisabled
-            class={styles.workStatus}
-            src={noSub}></NImage>
+          {studnetInfo.value.trainingStatus == 'UNSUBMITTED' ? (
+            <NImage
+              previewDisabled
+              class={styles.workStatus}
+              src={noSub}></NImage>
+          ) : null}
+          {studnetInfo.value.trainingStatus == 'SUBMITTED' ? (
+            <NImage
+              previewDisabled
+              class={styles.workStatus}
+              src={unqualified}></NImage>
+          ) : null}
+          {studnetInfo.value.trainingStatus == 'TARGET' ? (
+            <NImage
+              previewDisabled
+              class={styles.workStatus}
+              src={qualified}></NImage>
+          ) : null}
+        </div>
+        <div class={styles.workList}>
+          {studnetInfo.value.studentLessonTrainingDetails.map((item: any) => (
+            <TrainType
+              isDisabled={true}
+              isDelete={false}
+              item={item}></TrainType>
+          ))}
         </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 class={styles.btnGroups} justify="space-between">
+          <div class={styles.allTotal}>
+            {props.current}/{props.total}名学生
+          </div>
+          <div>
+            <NSpace>
+              <NButton
+                disabled={props.current <= 1}
+                round
+                type="primary"
+                onClick={() => {
+                  emit('pre');
+                }}>
+                上一名
+              </NButton>
+              <NButton
+                disabled={props.current >= props.total}
+                round
+                type="primary"
+                onClick={() => {
+                  emit('next');
+                }}>
+                下一名
+              </NButton>
+            </NSpace>
+          </div>
         </NSpace>
       </div>
     );