|
@@ -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>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|