|  | @@ -0,0 +1,284 @@
 | 
	
		
			
				|  |  | +import { defineComponent, onMounted, reactive, ref } from 'vue';
 | 
	
		
			
				|  |  | +import styles from '../index.module.less';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  NButton,
 | 
	
		
			
				|  |  | +  NDataTable,
 | 
	
		
			
				|  |  | +  NForm,
 | 
	
		
			
				|  |  | +  NFormItem,
 | 
	
		
			
				|  |  | +  NGi,
 | 
	
		
			
				|  |  | +  NGrid,
 | 
	
		
			
				|  |  | +  NImage,
 | 
	
		
			
				|  |  | +  NNumberAnimation,
 | 
	
		
			
				|  |  | +  NSelect,
 | 
	
		
			
				|  |  | +  NSpace
 | 
	
		
			
				|  |  | +} from 'naive-ui';
 | 
	
		
			
				|  |  | +import SearchInput from '@/components/searchInput';
 | 
	
		
			
				|  |  | +import CSelect from '@/components/CSelect';
 | 
	
		
			
				|  |  | +import Pagination from '@/components/pagination';
 | 
	
		
			
				|  |  | +import add from './images/add.png';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  getNowDateAndMonday,
 | 
	
		
			
				|  |  | +  getNowDateAndSunday,
 | 
	
		
			
				|  |  | +  getTimes,
 | 
	
		
			
				|  |  | +  formatTime
 | 
	
		
			
				|  |  | +} from '/src/utils/dateFormat';
 | 
	
		
			
				|  |  | +import { getTestList } from '../api';
 | 
	
		
			
				|  |  | +import CDatePicker from '/src/components/CDatePicker';
 | 
	
		
			
				|  |  | +import { useRoute, useRouter } from 'vue-router';
 | 
	
		
			
				|  |  | +import { get } from 'lodash';
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'student-studentList',
 | 
	
		
			
				|  |  | +  setup(props, { emit }) {
 | 
	
		
			
				|  |  | +    const state = reactive({
 | 
	
		
			
				|  |  | +      searchForm: { keyword: '', trainingStatus: null as any, vipFlag: null },
 | 
	
		
			
				|  |  | +      searchWord: '',
 | 
	
		
			
				|  |  | +      orchestraType: null,
 | 
	
		
			
				|  |  | +      courseTypeCode: null,
 | 
	
		
			
				|  |  | +      subjectId: null,
 | 
	
		
			
				|  |  | +      classId: null,
 | 
	
		
			
				|  |  | +      studentType: null,
 | 
	
		
			
				|  |  | +      loading: false,
 | 
	
		
			
				|  |  | +      pagination: {
 | 
	
		
			
				|  |  | +        page: 1,
 | 
	
		
			
				|  |  | +        rows: 10,
 | 
	
		
			
				|  |  | +        pageTotal: 4
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      tableList: [{ studentId: '1000578', studentName: '一十四' }] as any,
 | 
	
		
			
				|  |  | +      memberNumber: 0,
 | 
	
		
			
				|  |  | +      testInfo: {
 | 
	
		
			
				|  |  | +        practiceDurationAvg: 0,
 | 
	
		
			
				|  |  | +        memberCount: 0
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const route = useRoute();
 | 
	
		
			
				|  |  | +    const router = useRouter();
 | 
	
		
			
				|  |  | +    const search = () => {
 | 
	
		
			
				|  |  | +      state.pagination.page = 1;
 | 
	
		
			
				|  |  | +      getList();
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const timer = ref<[number, number]>([
 | 
	
		
			
				|  |  | +      getNowDateAndMonday(new Date().getTime()),
 | 
	
		
			
				|  |  | +      getNowDateAndSunday(new Date().getTime())
 | 
	
		
			
				|  |  | +    ]);
 | 
	
		
			
				|  |  | +    const onReset = () => {
 | 
	
		
			
				|  |  | +      state.searchForm = {
 | 
	
		
			
				|  |  | +        keyword: '',
 | 
	
		
			
				|  |  | +        trainingStatus: null as any,
 | 
	
		
			
				|  |  | +        vipFlag: null
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +      search();
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const getList = async () => {
 | 
	
		
			
				|  |  | +      state.loading = true;
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res = await getTestList({
 | 
	
		
			
				|  |  | +          classGroupId: route.query.id,
 | 
	
		
			
				|  |  | +          ...state.searchForm,
 | 
	
		
			
				|  |  | +          ...state.pagination,
 | 
	
		
			
				|  |  | +          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // state.tableList = res.data.rows;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        state.pagination.pageTotal = res.data.total;
 | 
	
		
			
				|  |  | +        state.loading = false;
 | 
	
		
			
				|  |  | +      } catch (e) {
 | 
	
		
			
				|  |  | +        state.loading = false;
 | 
	
		
			
				|  |  | +        console.log(e);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    onMounted(() => {
 | 
	
		
			
				|  |  | +      getList();
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const gotoStudentDetail = (row: any) => {
 | 
	
		
			
				|  |  | +      router.push({
 | 
	
		
			
				|  |  | +        path: '/classStudentRecode',
 | 
	
		
			
				|  |  | +        query: {
 | 
	
		
			
				|  |  | +          ...route.query,
 | 
	
		
			
				|  |  | +          studentId: row.studentId,
 | 
	
		
			
				|  |  | +          studentName: row.studentName
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const columns = () => {
 | 
	
		
			
				|  |  | +      return [
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '姓名',
 | 
	
		
			
				|  |  | +          key: 'studentName'
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '手机号',
 | 
	
		
			
				|  |  | +          key: 'studentPhone'
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '性别',
 | 
	
		
			
				|  |  | +          key: 'sex',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return <>{row.sex == '0' ? '女' : '男'}</>;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '学生类型',
 | 
	
		
			
				|  |  | +          key: 'studentType',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return <>{row.studentType == 'member' ? '会员' : '普通'}</>;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '练习天数',
 | 
	
		
			
				|  |  | +          key: 'practiceDays',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return <>{row.practiceDays ? row.practiceDays : 0}天</>;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '练习时长',
 | 
	
		
			
				|  |  | +          key: 'studentType',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return (
 | 
	
		
			
				|  |  | +              <>{row.practiceDuration ? formatTime(row.practiceDuration) : 0}</>
 | 
	
		
			
				|  |  | +            );
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          title: '操作',
 | 
	
		
			
				|  |  | +          key: 'id',
 | 
	
		
			
				|  |  | +          render(row: any) {
 | 
	
		
			
				|  |  | +            return (
 | 
	
		
			
				|  |  | +              <NButton
 | 
	
		
			
				|  |  | +                text
 | 
	
		
			
				|  |  | +                type="primary"
 | 
	
		
			
				|  |  | +                onClick={() => {
 | 
	
		
			
				|  |  | +                  gotoStudentDetail(row);
 | 
	
		
			
				|  |  | +                }}>
 | 
	
		
			
				|  |  | +                详情
 | 
	
		
			
				|  |  | +              </NButton>
 | 
	
		
			
				|  |  | +            );
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      ];
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <div>
 | 
	
		
			
				|  |  | +        <div class={styles.searchList}>
 | 
	
		
			
				|  |  | +          <NForm label-placement="left" inline>
 | 
	
		
			
				|  |  | +            <NFormItem>
 | 
	
		
			
				|  |  | +              <SearchInput
 | 
	
		
			
				|  |  | +                {...{ placeholder: '请输入学生姓名' }}
 | 
	
		
			
				|  |  | +                class={styles.searchInput}
 | 
	
		
			
				|  |  | +                searchWord={state.searchForm.keyword}
 | 
	
		
			
				|  |  | +                onChangeValue={(val: string) =>
 | 
	
		
			
				|  |  | +                  (state.searchForm.keyword = val)
 | 
	
		
			
				|  |  | +                }></SearchInput>
 | 
	
		
			
				|  |  | +            </NFormItem>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <NFormItem>
 | 
	
		
			
				|  |  | +              <CSelect
 | 
	
		
			
				|  |  | +                {...({
 | 
	
		
			
				|  |  | +                  options: [
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                      label: '学生类型',
 | 
	
		
			
				|  |  | +                      value: null
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                      label: '会员',
 | 
	
		
			
				|  |  | +                      value: true
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                      label: '普通',
 | 
	
		
			
				|  |  | +                      value: false
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                  ],
 | 
	
		
			
				|  |  | +                  placeholder: '学生类型',
 | 
	
		
			
				|  |  | +                  clearable: true,
 | 
	
		
			
				|  |  | +                  inline: true
 | 
	
		
			
				|  |  | +                } as any)}
 | 
	
		
			
				|  |  | +                v-model:value={state.searchForm.vipFlag}></CSelect>
 | 
	
		
			
				|  |  | +            </NFormItem>
 | 
	
		
			
				|  |  | +            <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>
 | 
	
		
			
				|  |  | +        <div class={['section-container']}>
 | 
	
		
			
				|  |  | +          <NGrid x-gap="12" cols={8}>
 | 
	
		
			
				|  |  | +            <NGi>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={state.pagination.pageTotal}></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  人
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>练习人数</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </NGi>
 | 
	
		
			
				|  |  | +            <NGi>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={state.testInfo.memberCount}></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  人
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>会员人数</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </NGi>
 | 
	
		
			
				|  |  | +            <NGi>
 | 
	
		
			
				|  |  | +              <div class={styles.TrainDataItem}>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemTitle}>
 | 
	
		
			
				|  |  | +                  <span>
 | 
	
		
			
				|  |  | +                    <NNumberAnimation
 | 
	
		
			
				|  |  | +                      from={0}
 | 
	
		
			
				|  |  | +                      to={
 | 
	
		
			
				|  |  | +                        state.testInfo.practiceDurationAvg
 | 
	
		
			
				|  |  | +                      }></NNumberAnimation>
 | 
	
		
			
				|  |  | +                  </span>
 | 
	
		
			
				|  |  | +                  分钟
 | 
	
		
			
				|  |  | +                </p>
 | 
	
		
			
				|  |  | +                <p class={styles.TrainDataItemsubTitle}>平均练习时长</p>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </NGi>
 | 
	
		
			
				|  |  | +          </NGrid>
 | 
	
		
			
				|  |  | +        </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>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 |