|  | @@ -0,0 +1,327 @@
 | 
	
		
			
				|  |  | +import { Ref, defineComponent, onMounted, reactive, ref } from 'vue';
 | 
	
		
			
				|  |  | +import styles from '../index.module.less';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  NButton,
 | 
	
		
			
				|  |  | +  NDataTable,
 | 
	
		
			
				|  |  | +  NForm,
 | 
	
		
			
				|  |  | +  NFormItem,
 | 
	
		
			
				|  |  | +  NNumberAnimation,
 | 
	
		
			
				|  |  | +  NSpace
 | 
	
		
			
				|  |  | +} from 'naive-ui';
 | 
	
		
			
				|  |  | +import numeral from 'numeral';
 | 
	
		
			
				|  |  | +import { useECharts } from '@/hooks/web/useECharts';
 | 
	
		
			
				|  |  | +import Pagination from '/src/components/pagination';
 | 
	
		
			
				|  |  | +import { getTrainingStat } from '../api';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  getNowDateAndMonday,
 | 
	
		
			
				|  |  | +  getNowDateAndSunday,
 | 
	
		
			
				|  |  | +  getTimes
 | 
	
		
			
				|  |  | +} from '/src/utils/dateFormat';
 | 
	
		
			
				|  |  | +import CDatePicker from '/src/components/CDatePicker';
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'student-practiceData',
 | 
	
		
			
				|  |  | +  props: {
 | 
	
		
			
				|  |  | +    studentId: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  setup(props) {
 | 
	
		
			
				|  |  | +    const chartRef = ref<HTMLDivElement | null>(null);
 | 
	
		
			
				|  |  | +    const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
 | 
	
		
			
				|  |  | +    const practiceFlag = ref(true);
 | 
	
		
			
				|  |  | +    const payForm = reactive({
 | 
	
		
			
				|  |  | +      height: '360px',
 | 
	
		
			
				|  |  | +      width: '100%',
 | 
	
		
			
				|  |  | +      practiceDurationAvg: 0,
 | 
	
		
			
				|  |  | +      practiceDays: 0,
 | 
	
		
			
				|  |  | +      practiceDurationTotal: 0,
 | 
	
		
			
				|  |  | +      dateList: [],
 | 
	
		
			
				|  |  | +      timeList: []
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const state = reactive({
 | 
	
		
			
				|  |  | +      loading: false,
 | 
	
		
			
				|  |  | +      pagination: {
 | 
	
		
			
				|  |  | +        page: 1,
 | 
	
		
			
				|  |  | +        rows: 10,
 | 
	
		
			
				|  |  | +        pageTotal: 4
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      tableList: [] as any,
 | 
	
		
			
				|  |  | +      goCourseVisiable: false
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const timer = ref<[number, number]>([
 | 
	
		
			
				|  |  | +      getNowDateAndMonday(new Date().getTime()),
 | 
	
		
			
				|  |  | +      getNowDateAndSunday(new Date().getTime())
 | 
	
		
			
				|  |  | +    ]);
 | 
	
		
			
				|  |  | +    const columns = () => {
 | 
	
		
			
				|  |  | +      return [
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '日期',
 | 
	
		
			
				|  |  | +          key: 'date'
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '练习时长(分钟)',
 | 
	
		
			
				|  |  | +          key: 'practiceDuration',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return <span>{row.practiceDuration}分钟</span>;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      ];
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const getList = () => {
 | 
	
		
			
				|  |  | +      console.log('1');
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const setChart = () => {
 | 
	
		
			
				|  |  | +      setOptions({
 | 
	
		
			
				|  |  | +        tooltip: {
 | 
	
		
			
				|  |  | +          trigger: 'axis',
 | 
	
		
			
				|  |  | +          axisPointer: {
 | 
	
		
			
				|  |  | +            type: 'shadow'
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        legend: {
 | 
	
		
			
				|  |  | +          show: false,
 | 
	
		
			
				|  |  | +          selected: {
 | 
	
		
			
				|  |  | +            //在这里设置默认展示就ok了
 | 
	
		
			
				|  |  | +            '练习时长(分钟)': practiceFlag.value
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        xAxis: {
 | 
	
		
			
				|  |  | +          type: 'category',
 | 
	
		
			
				|  |  | +          boundaryGap: true,
 | 
	
		
			
				|  |  | +          axisLabel: {
 | 
	
		
			
				|  |  | +            show: true,
 | 
	
		
			
				|  |  | +            interval: 0
 | 
	
		
			
				|  |  | +          },
 | 
	
		
			
				|  |  | +          data: payForm.dateList
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        yAxis: [
 | 
	
		
			
				|  |  | +          {
 | 
	
		
			
				|  |  | +            type: 'value',
 | 
	
		
			
				|  |  | +            axisLabel: {
 | 
	
		
			
				|  |  | +              formatter: '{value} min'
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            axisTick: {
 | 
	
		
			
				|  |  | +              show: false
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            splitArea: {
 | 
	
		
			
				|  |  | +              show: false,
 | 
	
		
			
				|  |  | +              areaStyle: {
 | 
	
		
			
				|  |  | +                color: ['rgba(255,255,255,0.2)']
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        ],
 | 
	
		
			
				|  |  | +        grid: {
 | 
	
		
			
				|  |  | +          left: '1%',
 | 
	
		
			
				|  |  | +          right: '1%',
 | 
	
		
			
				|  |  | +          top: '2%',
 | 
	
		
			
				|  |  | +          bottom: 0,
 | 
	
		
			
				|  |  | +          containLabel: true
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        series: [
 | 
	
		
			
				|  |  | +          {
 | 
	
		
			
				|  |  | +            // smooth: true,
 | 
	
		
			
				|  |  | +            data: payForm.timeList,
 | 
	
		
			
				|  |  | +            type: 'bar',
 | 
	
		
			
				|  |  | +            barWidth: '48px',
 | 
	
		
			
				|  |  | +            stack: 'total',
 | 
	
		
			
				|  |  | +            label: {
 | 
	
		
			
				|  |  | +              // 柱图头部显示值
 | 
	
		
			
				|  |  | +              show: true,
 | 
	
		
			
				|  |  | +              position: 'top',
 | 
	
		
			
				|  |  | +              color: '#333',
 | 
	
		
			
				|  |  | +              fontSize: '12px',
 | 
	
		
			
				|  |  | +              fontWeight: 600
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            itemStyle: {
 | 
	
		
			
				|  |  | +              normal: {
 | 
	
		
			
				|  |  | +                //这里设置柱形图圆角 [左上角,右上角,右下角,左下角]
 | 
	
		
			
				|  |  | +                barBorderRadius: [8, 8, 0, 0],
 | 
	
		
			
				|  |  | +                color: '#D5E9FF'
 | 
	
		
			
				|  |  | +              },
 | 
	
		
			
				|  |  | +              emphasis: {
 | 
	
		
			
				|  |  | +                focus: 'series',
 | 
	
		
			
				|  |  | +                color: '#3583FA' //hover时改变柱子颜色
 | 
	
		
			
				|  |  | +                // borderWidth: 4,
 | 
	
		
			
				|  |  | +                // borderColor: 'rgba(213, 233, 255,.4)',
 | 
	
		
			
				|  |  | +                // borderType: 'solid'
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            } as any
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        ],
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        formatter: (item: any) => {
 | 
	
		
			
				|  |  | +          if (Array.isArray(item)) {
 | 
	
		
			
				|  |  | +            return [
 | 
	
		
			
				|  |  | +              item[0].axisValueLabel,
 | 
	
		
			
				|  |  | +              ...item.map(
 | 
	
		
			
				|  |  | +                (d: any) =>
 | 
	
		
			
				|  |  | +                  `<br/>${
 | 
	
		
			
				|  |  | +                    d.marker
 | 
	
		
			
				|  |  | +                  }<span style="margin-top:10px;margin-left:5px;font-size: 13px;font-weight: 500;
 | 
	
		
			
				|  |  | +                  color: #131415;font-weight: 600;
 | 
	
		
			
				|  |  | +                  margin-top:12px
 | 
	
		
			
				|  |  | +                  line-height: 18px;">练习时长: ${d.value}${'分钟'} </span>`
 | 
	
		
			
				|  |  | +              )
 | 
	
		
			
				|  |  | +            ].join('');
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            return item;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // dataZoom: [
 | 
	
		
			
				|  |  | +        //   {
 | 
	
		
			
				|  |  | +        //     type: 'slider',
 | 
	
		
			
				|  |  | +        //     start: 5,
 | 
	
		
			
				|  |  | +        //     end: 100,
 | 
	
		
			
				|  |  | +        //     filterMode: 'empty'
 | 
	
		
			
				|  |  | +        //   }
 | 
	
		
			
				|  |  | +        // ]
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const getChartDetail = async () => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res = await getTrainingStat({
 | 
	
		
			
				|  |  | +          studentId: props.studentId,
 | 
	
		
			
				|  |  | +          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        payForm.practiceDays = res.data.practiceDays;
 | 
	
		
			
				|  |  | +        payForm.practiceDurationAvg = res.data.practiceDurationAvg;
 | 
	
		
			
				|  |  | +        payForm.practiceDurationTotal = res.data.practiceDurationTotal;
 | 
	
		
			
				|  |  | +        payForm.dateList = res.data.trainingStatDetailList.map((item: any) => {
 | 
	
		
			
				|  |  | +          return item.date;
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        payForm.timeList = res.data.trainingStatDetailList.map((item: any) => {
 | 
	
		
			
				|  |  | +          return item.practiceDuration;
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        state.tableList = res.data.trainingStatDetailList;
 | 
	
		
			
				|  |  | +        setChart();
 | 
	
		
			
				|  |  | +        console.log(payForm);
 | 
	
		
			
				|  |  | +      } catch (e) {
 | 
	
		
			
				|  |  | +        console.log(e);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const search = () => {
 | 
	
		
			
				|  |  | +      state.pagination.page = 1;
 | 
	
		
			
				|  |  | +      getChartDetail();
 | 
	
		
			
				|  |  | +      console.log('search');
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const onReset = () => {
 | 
	
		
			
				|  |  | +      timer.value = [
 | 
	
		
			
				|  |  | +        getNowDateAndMonday(new Date().getTime()),
 | 
	
		
			
				|  |  | +        getNowDateAndSunday(new Date().getTime())
 | 
	
		
			
				|  |  | +      ];
 | 
	
		
			
				|  |  | +      search();
 | 
	
		
			
				|  |  | +      console.log('onReset');
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    onMounted(() => {
 | 
	
		
			
				|  |  | +      console.log(props.studentId);
 | 
	
		
			
				|  |  | +      getChartDetail();
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <>
 | 
	
		
			
				|  |  | +        <NForm label-placement="left" inline>
 | 
	
		
			
				|  |  | +          <NFormItem>
 | 
	
		
			
				|  |  | +            <CDatePicker
 | 
	
		
			
				|  |  | +              v-model:value={timer.value}
 | 
	
		
			
				|  |  | +              separator={'至'}
 | 
	
		
			
				|  |  | +              type="daterange"
 | 
	
		
			
				|  |  | +              timerValue={timer.value}></CDatePicker>
 | 
	
		
			
				|  |  | +          </NFormItem>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <NFormItem>
 | 
	
		
			
				|  |  | +            <NSpace justify="end">
 | 
	
		
			
				|  |  | +              <NButton type="primary" class="searchBtn" onClick={search}>
 | 
	
		
			
				|  |  | +                搜索
 | 
	
		
			
				|  |  | +              </NButton>
 | 
	
		
			
				|  |  | +              <NButton type="primary" ghost class="resetBtn" onClick={onReset}>
 | 
	
		
			
				|  |  | +                重置
 | 
	
		
			
				|  |  | +              </NButton>
 | 
	
		
			
				|  |  | +            </NSpace>
 | 
	
		
			
				|  |  | +          </NFormItem>
 | 
	
		
			
				|  |  | +        </NForm>
 | 
	
		
			
				|  |  | +        <div class={styles.homeTrainData}>
 | 
	
		
			
				|  |  | +          <div class={styles.TrainDataTop}>
 | 
	
		
			
				|  |  | +            <div class={styles.TrainDataTopLeft}>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={payForm.practiceDurationTotal}></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  人
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>累计练习时长</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={payForm.practiceDurationAvg}></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  分钟
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>平均练习时长</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={payForm.practiceDays}></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  天
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>练习天数</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.TrainDataTopRight}>
 | 
	
		
			
				|  |  | +              <div
 | 
	
		
			
				|  |  | +                // onClick={() => {
 | 
	
		
			
				|  |  | +                //   practiceFlag.value = !practiceFlag.value;
 | 
	
		
			
				|  |  | +                //   setChart();
 | 
	
		
			
				|  |  | +                // }}
 | 
	
		
			
				|  |  | +                class={[
 | 
	
		
			
				|  |  | +                  styles.DataTopRightItem,
 | 
	
		
			
				|  |  | +                  practiceFlag.value ? '' : styles.DataTopRightItemDis
 | 
	
		
			
				|  |  | +                ]}>
 | 
	
		
			
				|  |  | +                <div
 | 
	
		
			
				|  |  | +                  class={[
 | 
	
		
			
				|  |  | +                    styles.DataTopRightDot,
 | 
	
		
			
				|  |  | +                    styles.DataTopRightDotBlue
 | 
	
		
			
				|  |  | +                  ]}></div>
 | 
	
		
			
				|  |  | +                <p>练习时长(分钟)</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +          <div class={styles.chatrs}>
 | 
	
		
			
				|  |  | +            <div
 | 
	
		
			
				|  |  | +              ref={chartRef}
 | 
	
		
			
				|  |  | +              style={{ height: payForm.height, width: payForm.width }}></div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +          <div class={styles.tableWrap}>
 | 
	
		
			
				|  |  | +            <NDataTable
 | 
	
		
			
				|  |  | +              class={styles.classTable}
 | 
	
		
			
				|  |  | +              loading={state.loading}
 | 
	
		
			
				|  |  | +              columns={columns()}
 | 
	
		
			
				|  |  | +              data={state.tableList}></NDataTable>
 | 
	
		
			
				|  |  | +            {/* <Pagination
 | 
	
		
			
				|  |  | +              v-model:page={state.pagination.page}
 | 
	
		
			
				|  |  | +              v-model:pageSize={state.pagination.rows}
 | 
	
		
			
				|  |  | +              v-model:pageTotal={state.pagination.pageTotal}
 | 
	
		
			
				|  |  | +              onList={getList}
 | 
	
		
			
				|  |  | +              sync
 | 
	
		
			
				|  |  | +              saveKey="orchestraRegistration-key"
 | 
	
		
			
				|  |  | +            /> */}
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 |