Bläddra i källkod

更新周报月报

lex 1 år sedan
förälder
incheckning
8d70e2b191

+ 6 - 1
src/school/train-report/index.module.less

@@ -2,10 +2,12 @@
   --van-tab-active-text-color: var(--van-primary-color);
   --van-tab-text-color: #333;
   --van-tab-font-size: 16px;
+
   :global {
     .van-tab {
       // font-weight: 400;
     }
+
     .van-tabs__wrap {
       // padding-bottom: 3px;
     }
@@ -15,6 +17,7 @@
     margin: 12px 13px 0;
     overflow: hidden;
     border-radius: 10px;
+
     .select {
       height: 45px;
 
@@ -53,12 +56,14 @@
       font-size: 16px;
       color: #333333;
     }
+
     .van-cell_label {
       font-size: 14px;
       color: #777;
     }
+
     .van-cell__value {
       flex: 0 auto;
     }
   }
-}
+}

+ 80 - 13
src/school/train-report/modal/index.module.less

@@ -4,10 +4,12 @@
   position: relative;
   z-index: 1;
   margin: 0 13px 10px;
+
   &.studentSection {
     background: url('../images/week/section-title-bg1.png') no-repeat top center;
     background-size: contain;
   }
+
   &.teacherSection {
     background: url('../images/week/section-title-bg2.png') no-repeat top center;
     background-size: contain;
@@ -16,10 +18,12 @@
   &.teacherTrainSection {
     background: url('../images/month/teacher-section-title-bg.png') no-repeat top center;
     background-size: contain;
+
     &.studentSection {
       background: url('../images/month/teacher-section-title-bg1.png') no-repeat top center;
       background-size: contain;
     }
+
     &.teacherSection {
       background: url('../images/month/teacher-section-title-bg2.png') no-repeat top center;
       background-size: contain;
@@ -32,16 +36,19 @@
     justify-content: space-between;
     padding-top: 4px;
     height: 36px;
+
     .allowLine {
       width: 13px;
       height: 13px;
       margin-right: 6px;
     }
+
     .arrowPoint {
       height: 5px;
       width: 22px;
       margin-right: 15px;
     }
+
     .name {
       display: flex;
       align-items: center;
@@ -52,6 +59,7 @@
       line-height: 22px;
     }
   }
+
   .countNums {
     display: flex;
     align-items: center;
@@ -61,6 +69,7 @@
     color: #ffffff;
     line-height: 20px;
     font-family: DINA;
+
     span {
       color: #42ffe2;
       padding: 0 6px;
@@ -75,6 +84,7 @@
     padding: 12px;
     border-radius: 20px;
   }
+
   .tContent {
     background: #ffffff;
     box-shadow: 0px 2px 22px 0px rgba(83, 109, 233, 0.79);
@@ -87,33 +97,35 @@
       margin: 0 10px 10px 0;
       width: 53px;
       height: 55px;
-      background: linear-gradient(
-        132deg,
-        rgba(199, 239, 243, 0.39) 0%,
-        rgba(229, 206, 251, 0.39) 40%,
-        rgba(147, 194, 254, 0.39) 100%
-      );
+      background: linear-gradient(132deg,
+          rgba(199, 239, 243, 0.39) 0%,
+          rgba(229, 206, 251, 0.39) 40%,
+          rgba(147, 194, 254, 0.39) 100%);
       box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
       border-radius: 4px;
       display: flex;
       align-items: center;
       flex-direction: column;
       justify-content: center;
+
       &:nth-child(5n + 5) {
         margin-right: 0;
       }
+
       .pople {
         font-size: 20px;
         font-family: DINA;
         font-weight: bold;
         color: #1c4aff;
         line-height: 24px;
+
         span {
           font-size: 12px;
           color: #777777;
           line-height: 17px;
         }
       }
+
       .subjectName {
         font-size: 12px;
         color: #333333;
@@ -128,24 +140,72 @@
     justify-content: space-between;
     width: 100%;
     padding-bottom: 10px;
+
     .unit {
       font-size: 12px;
       color: #777777;
     }
+
     .unitType {
-      background: linear-gradient(
-        132deg,
-        rgba(199, 239, 243, 0.25) 0%,
-        rgba(223, 213, 250, 0.25) 32%,
-        rgba(147, 194, 254, 0.25) 100%
-      );
+      background: linear-gradient(132deg,
+          rgba(199, 239, 243, 0.25) 0%,
+          rgba(223, 213, 250, 0.25) 32%,
+          rgba(147, 194, 254, 0.25) 100%);
+      box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
+      border-radius: 12px;
+      padding: 4px 8px;
+      font-size: 12px;
+      color: #000977;
+    }
+
+    .overWorkType {
       box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
       border-radius: 12px;
       padding: 4px 8px;
       font-size: 12px;
       color: #000977;
+      border: 1px solid #8279F6;
+
+      &.overWorkActive {
+        background-color: #7A70FB;
+        box-shadow: none;
+        color: #fff;
+
+      }
+
+      &+.overWorkType {
+        margin-left: 8px;
+      }
+    }
+
+    .attendType {
+      display: inline-flex;
+      align-items: center;
+
+      &::before {
+        content: ' ';
+        display: inline-block;
+        width: 10px;
+        height: 10px;
+        background-color: #ccc;
+        margin-right: 4px;
+        border-radius: 1px;
+      }
+
+      &+.attendType {
+        margin-left: 8px;
+      }
+
+      &.attendActive::before {
+        background-color: #5DA4FF;
+      }
+
+      &.attendActive2::before {
+        background-color: #69EAF6;
+      }
     }
   }
+
   .classEcharts {
     height: 210px;
     width: 100%;
@@ -154,14 +214,17 @@
   .tProgress {
     display: block;
   }
+
   .progressItem {
     padding-bottom: 16px;
+
     .className {
       padding-bottom: 6px;
       font-size: 14px;
       font-weight: 600;
       color: #333333;
       line-height: 20px;
+
       .line {
         display: inline-block;
         width: 4px;
@@ -171,6 +234,7 @@
         margin-right: 6px;
       }
     }
+
     .classNum {
       display: flex;
       align-items: center;
@@ -178,18 +242,21 @@
       font-size: 12px;
       padding-bottom: 6px;
       color: #333333;
+
       span {
         font-size: 16px;
         padding: 0 4px;
         font-weight: bold;
         font-family: DINA;
       }
+
       .konowCount {
         color: #777;
+
         span {
           color: #f44541;
         }
       }
     }
   }
-}
+}

+ 4 - 3
src/school/train-report/modal/student-attendance.tsx

@@ -73,8 +73,8 @@ export default defineComponent({
       const data = props.reportData || {}
       const titleList: any = []
       const valueList: any = []
-      const lineColor = '#FF8057'
-      const textColor = '#F67146'
+      const lineColor = '#5EA4FF'
+      const textColor = '#777777'
       for (const i in data) {
         if (i === 'TOTAL') {
           forms.total = Math.ceil(data[i] * 100)
@@ -117,8 +117,9 @@ export default defineComponent({
         },
         series: [
           {
-            type: 'line',
+            type: 'bar',
             showBackground: false,
+            barWidth: 15,
             itemStyle: {
               color: lineColor
             },

+ 97 - 20
src/school/train-report/modal/teacher-attendance.tsx

@@ -49,11 +49,16 @@ export default defineComponent({
     reportData: {
       type: Object,
       default: () => ({})
+    },
+    reportDataNot: {
+      type: Object,
+      default: () => ({})
     }
   },
   setup(props) {
     const forms = reactive({
-      total: 0
+      total: 0,
+      type: ['YES', 'NOT']
     })
 
     watch(
@@ -70,10 +75,10 @@ export default defineComponent({
       }
 
       const data = props.reportData || {}
+      const seriesList: any = []
       const titleList: any = []
       const valueList: any = []
-      const lineColor = '#356BF7'
-      const textColor = '#1B4FD7'
+
       for (const i in data) {
         if (i === 'TOTAL') {
           forms.total = Math.ceil(data[i] * 100)
@@ -87,6 +92,52 @@ export default defineComponent({
         }
       }
 
+      const valueList2: any = []
+      const dataNot = props.reportDataNot || {}
+      for (const i in dataNot) {
+        if (i !== 'TOTAL') {
+          valueList2.push(Math.ceil(dataNot[i] * 100))
+        }
+      }
+      if (forms.type.includes('YES')) {
+        seriesList.push({
+          name: '出勤课时数',
+          type: 'bar',
+          stack: 'work',
+          showBackground: false,
+          barWidth: 15,
+          itemStyle: {
+            color: '#5EA4FF'
+          },
+          label: {
+            show: true,
+            position: 'top',
+            fontSize: 10,
+            color: '#777777'
+          },
+          data: valueList
+        })
+      }
+      if (forms.type.includes('NOT')) {
+        seriesList.push({
+          name: '未出勤课时数',
+          type: 'bar',
+          stack: 'work',
+          showBackground: false,
+          barWidth: 15,
+          itemStyle: {
+            color: '#69DDE8'
+          },
+          label: {
+            show: true,
+            position: 'top',
+            fontSize: 10,
+            color: '#777777'
+          },
+          data: valueList2
+        })
+      }
+
       const chartDom = document.getElementById('teacherEcharts')
       myChart = echarts.init(chartDom as HTMLDivElement)
       const option = {
@@ -107,6 +158,12 @@ export default defineComponent({
         yAxis: {
           type: 'value'
         },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
         grid: {
           left: 0,
           top: 22,
@@ -114,22 +171,7 @@ export default defineComponent({
           bottom: 12,
           containLabel: true
         },
-        series: [
-          {
-            type: 'line',
-            showBackground: false,
-            itemStyle: {
-              color: lineColor
-            },
-            label: {
-              show: true,
-              position: 'top',
-              fontSize: 10,
-              color: textColor
-            },
-            data: valueList
-          }
-        ]
+        series: seriesList
       }
 
       option && myChart.setOption(option)
@@ -172,7 +214,42 @@ export default defineComponent({
         <div class={styles.trainSectionContent}>
           <div class={styles.tContent}>
             <div class={styles.calssEchartTitle}>
-              <span class={styles.unit}>单位:%</span>
+              <span class={styles.unit}>单位:课时</span>
+              <div>
+                <span
+                  class={[styles.attendType, forms.type.includes('YES') ? styles.attendActive : '']}
+                  onClick={() => {
+                    // forms.type = 'target'
+                    const index = forms.type.indexOf('YES')
+                    if (index > -1) {
+                      forms.type.splice(index, 1)
+                    } else {
+                      forms.type.push('YES')
+                    }
+                    handleInit()
+                  }}
+                >
+                  出勤课时数
+                </span>
+                <span
+                  class={[
+                    styles.attendType,
+                    forms.type.includes('NOT') ? styles.attendActive2 : ''
+                  ]}
+                  onClick={() => {
+                    // forms.type = 'submitted'
+                    const index = forms.type.indexOf('NOT')
+                    if (index > -1) {
+                      forms.type.splice(index, 1)
+                    } else {
+                      forms.type.push('NOT')
+                    }
+                    handleInit()
+                  }}
+                >
+                  未出勤课时数
+                </span>
+              </div>
             </div>
             <div id="teacherEcharts" class={styles.classEcharts}></div>
           </div>

+ 210 - 0
src/school/train-report/modal/train-over-work.tsx

@@ -0,0 +1,210 @@
+import { defineComponent, onMounted, reactive, watch } from 'vue'
+import { Image } from 'vant'
+import styles from './index.module.less'
+import arrowLine from '../images/week/icon-arrow-line.png'
+import arrowPoint from '../images/icon-arrow-point.png'
+import teacherArrowLine from '../images/month/teacher-icon-arrow-line.png'
+import * as echarts from 'echarts/core'
+import {
+  TitleComponent,
+  // 组件类型的定义后缀都为 ComponentOption
+  TooltipComponent,
+  GridComponent,
+  // 数据集组件
+  DatasetComponent,
+  // 内置数据转换器组件 (filter, sort)
+  TransformComponent,
+  LegendComponent,
+  ToolboxComponent,
+  DataZoomComponent
+} from 'echarts/components'
+import { BarChart } from 'echarts/charts'
+import { PieChart } from 'echarts/charts'
+import { LabelLayout, UniversalTransition } from 'echarts/features'
+import { CanvasRenderer } from 'echarts/renderers'
+import { reportCourseType } from '../week-report'
+// type EChartsOption = echarts.EChartsOption
+
+// 注册必须的组件
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  DatasetComponent,
+  TransformComponent,
+  BarChart,
+  LabelLayout,
+  UniversalTransition,
+  CanvasRenderer,
+  PieChart,
+  ToolboxComponent,
+  LegendComponent,
+  DataZoomComponent
+])
+
+export default defineComponent({
+  name: 'orchestra-num',
+  props: {
+    type: {
+      type: String,
+      default: 'week'
+    },
+    reportData: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  setup(props) {
+    const forms = reactive({
+      total: 0,
+      type: 'target' as 'target' | 'submitted',
+      workTarget: {} as any, //作业完成率
+      workSubmitted: {} as any //作业提交率
+    })
+
+    watch(
+      () => props.reportData,
+      () => {
+        handleInit()
+      }
+    )
+
+    let myChart: any
+    const handleInit = () => {
+      if (myChart) {
+        myChart.dispose()
+      }
+      const report = props.reportData || {}
+
+      const data = forms.type === 'target' ? report.HOMEWORK_TARGET : report.HOMEWORK_SUBMITTED
+      const titleList: any = []
+      const valueList: any = []
+      for (const i in data) {
+        if (i === 'TOTAL') {
+          // forms.total = data[i]
+          forms.total = Math.ceil(data[i] * 100)
+        } else {
+          titleList.push(reportCourseType[i])
+          valueList.push(Math.ceil(data[i] * 100))
+        }
+      }
+
+      const chartDom = document.getElementById('overWorkEcharts')
+      myChart = echarts.init(chartDom as HTMLDivElement)
+      const option = {
+        xAxis: {
+          type: 'category',
+          data: titleList,
+          axisLabel: {
+            rotate: 45,
+            fontSize: 10,
+            color: '#333'
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#D6D6D6'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value'
+        },
+        grid: {
+          left: 0,
+          top: 22,
+          right: 0,
+          bottom: 12,
+          containLabel: true
+        },
+        series: [
+          {
+            type: 'bar',
+            showBackground: false,
+            barWidth: 15,
+            itemStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: '#69DCE8' },
+                { offset: 0.5, color: '#E5CEFB' },
+                { offset: 1, color: '#58A2FF' }
+              ])
+            },
+            emphasis: {
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: '#69DCE8' },
+                  { offset: 0.5, color: '#E5CEFB' },
+                  { offset: 1, color: '#58A2FF' }
+                ])
+              }
+            },
+            label: {
+              show: true,
+              position: 'top',
+              fontSize: 10,
+              color: '#777'
+            },
+            data: valueList
+          }
+        ]
+      }
+      option && myChart.setOption(option)
+    }
+
+    onMounted(() => {
+      handleInit()
+    })
+
+    return () => (
+      <div class={[styles.trainSection, props.type === 'month' ? styles.teacherTrainSection : '']}>
+        <div class={styles.trainTitle}>
+          <div class={styles.name}>
+            <Image
+              src={props.type === 'month' ? teacherArrowLine : arrowLine}
+              class={styles.allowLine}
+            />
+            完成作业率
+          </div>
+          <div class={styles.countNums}>
+            <Image src={arrowPoint} class={styles.arrowPoint} />
+            总完成率<span>{forms.total}</span>%
+          </div>
+        </div>
+
+        <div class={styles.trainSectionContent}>
+          <div class={styles.tContent}>
+            <div class={styles.calssEchartTitle}>
+              <span class={styles.unit}>单位:%</span>
+              <div>
+                <span
+                  class={[
+                    styles.overWorkType,
+                    forms.type === 'target' ? styles.overWorkActive : ''
+                  ]}
+                  onClick={() => {
+                    forms.type = 'target'
+                    handleInit()
+                  }}
+                >
+                  作业完成率
+                </span>
+                <span
+                  class={[
+                    styles.overWorkType,
+                    forms.type === 'submitted' ? styles.overWorkActive : ''
+                  ]}
+                  onClick={() => {
+                    forms.type = 'submitted'
+                    handleInit()
+                  }}
+                >
+                  作业提交率
+                </span>
+              </div>
+            </div>
+            <div id="overWorkEcharts" class={styles.classEcharts}></div>
+          </div>
+        </div>
+      </div>
+    )
+  }
+})

+ 24 - 2
src/school/train-report/month-report.tsx

@@ -34,6 +34,7 @@ import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'
 import html2canvas from 'html2canvas'
 import iconArrow from './images/icon-arrow.png'
 import { useRect } from '@vant/use'
+import TrainOverWork from './modal/train-over-work'
 
 export const reportCourseType = {
   PERCUSSION: '打击乐',
@@ -75,7 +76,10 @@ export default defineComponent({
       ORCHESTRA: {},
       PHOTO: {} as any,
       STUDENT_ATTENDANCE: {},
-      TEACHER_ATTENDANCE: {}
+      TEACHER_ATTENDANCE: {},
+      HOMEWORK_TARGET: {} as any, // 作业完成率
+      HOMEWORK_SUBMITTED: {} as any, // 作业提交率
+      TEACHER_NOT_ATTENDANCE: {} as any
     })
 
     const getDetail = async () => {
@@ -85,9 +89,13 @@ export default defineComponent({
         reportData.COURSE_SCHEDULE = data.reportItem.COURSE_SCHEDULE || {}
         reportData.KNOWLEDGE = data.reportItem.KNOWLEDGE || {}
         reportData.ORCHESTRA = data.reportItem.ORCHESTRA || {}
+        reportData.HOMEWORK_TARGET = data.reportItem.HOMEWORK_TARGET || {}
+        reportData.HOMEWORK_SUBMITTED = data.reportItem.HOMEWORK_SUBMITTED || {}
         reportData.PHOTO = data.reportItem.PHOTO || {}
         reportData.STUDENT_ATTENDANCE = data.reportItem.STUDENT_ATTENDANCE || {}
+
         reportData.TEACHER_ATTENDANCE = data.reportItem.TEACHER_ATTENDANCE || {}
+        reportData.TEACHER_NOT_ATTENDANCE = data.reportItem.TEACHER_NOT_ATTENDANCE || {}
         reportData.orchestraName = data.orchestraName || ''
         reportData.monthlyTime = data.monthlyTime || ''
         reportData.startTime = data.startTime || ''
@@ -261,6 +269,16 @@ export default defineComponent({
         <OrchestraNum type="month" reportData={reportData.ORCHESTRA} />
         <TrainClass type="month" reportData={reportData.COURSE_SCHEDULE} />
 
+        {/* {reportData.HOMEWORK_TARGET.total && ( */}
+        <TrainOverWork
+          type="month"
+          reportData={{
+            HOMEWORK_SUBMITTED: reportData.HOMEWORK_SUBMITTED,
+            HOMEWORK_TARGET: reportData.HOMEWORK_TARGET
+          }}
+        />
+        {/* )} */}
+
         <div class={[styles.trainPhoto, styles.teacherTrainPhoto]}>
           <Image src={iconPhoto} class={styles.iconPhoto} />
           <p
@@ -281,7 +299,11 @@ export default defineComponent({
         </div>
 
         <StudentAttendance type="month" reportData={reportData.STUDENT_ATTENDANCE} />
-        <TeacherAttendance type="month" reportData={reportData.TEACHER_ATTENDANCE} />
+        <TeacherAttendance
+          type="month"
+          reportData={reportData.TEACHER_ATTENDANCE}
+          reportDataNot={reportData.TEACHER_NOT_ATTENDANCE}
+        />
 
         <div class={[styles.trainClass, styles.teacherTrainClass]}>
           <Image src={iconClass} class={styles.iconPhoto} />