|
@@ -0,0 +1,351 @@
|
|
|
+import MHeader from '@/components/m-header';
|
|
|
+import MSearch from '@/components/m-search';
|
|
|
+import MSticky from '@/components/m-sticky';
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ DropdownItem,
|
|
|
+ DropdownItemOption,
|
|
|
+ DropdownMenu,
|
|
|
+ Image,
|
|
|
+ List,
|
|
|
+ Picker
|
|
|
+} from 'vant';
|
|
|
+import { defineComponent, onMounted, reactive, ref } from 'vue';
|
|
|
+import styles from './index.module.less';
|
|
|
+import MStudent from './component/m-student/index';
|
|
|
+import Attendance from './component/Attendance';
|
|
|
+import Assignment from './component/Assignment';
|
|
|
+import icon_tuituan from './images/icon-tuituan.png';
|
|
|
+import icon_zaidu from './images/icon-zaidu.png';
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import SkeletionIndex from './skeletion-index';
|
|
|
+import {
|
|
|
+ api_cooperationOrganMusicGroupPage,
|
|
|
+ api_studentManageCoopSubjectList,
|
|
|
+ api_studentManageUserCount,
|
|
|
+ api_studentManageUserPage
|
|
|
+} from './api';
|
|
|
+import MFullRefresh from '@/components/m-full-refresh';
|
|
|
+import { IMusicGroup, IStudentManage, ISubject } from './type';
|
|
|
+import DropDownModal from './component/drop-down-modal';
|
|
|
+import MEmpty from '@/components/m-empty';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'student-manage',
|
|
|
+ setup() {
|
|
|
+ const router = useRouter();
|
|
|
+ const fromData = reactive({
|
|
|
+ page: 1,
|
|
|
+ rows: 20,
|
|
|
+ /** 关键词 */
|
|
|
+ keyword: '',
|
|
|
+ /** 乐团ID */
|
|
|
+ musicGroupId: '',
|
|
|
+ /** 学生乐团状态 */
|
|
|
+ statusList: '',
|
|
|
+ /** 声部ID */
|
|
|
+ subjectId: '',
|
|
|
+ /** 是否会员 */
|
|
|
+ vipFlag: ''
|
|
|
+ });
|
|
|
+ const studentMagege = reactive({
|
|
|
+ skelet: true,
|
|
|
+ refresh: false,
|
|
|
+ loading: false,
|
|
|
+ finshed: false,
|
|
|
+ list: [] as IStudentManage[],
|
|
|
+ studentCount: 0,
|
|
|
+ quitCount: 0,
|
|
|
+ musicGroups: [] as IMusicGroup[],
|
|
|
+ musicGroupId: '',
|
|
|
+ musicGroupName: '全部乐团',
|
|
|
+ subjects: [] as ISubject[],
|
|
|
+ subjectId: '',
|
|
|
+ subjectName: '全部声部',
|
|
|
+ studentTypes: [
|
|
|
+ { text: '全部学员', value: '' },
|
|
|
+ { text: '团练宝学员', value: '1' },
|
|
|
+ { text: '普通学员', value: '2' }
|
|
|
+ ] as DropdownItemOption[],
|
|
|
+ studentTypeName: '全部学员'
|
|
|
+ });
|
|
|
+ const musicGroupRef = ref();
|
|
|
+ const subjectRef = ref();
|
|
|
+
|
|
|
+ /** 获取乐团列表 */
|
|
|
+ const getGroups = () => {
|
|
|
+ api_cooperationOrganMusicGroupPage().then(res => {
|
|
|
+ let data = Array.isArray(res?.data) ? res.data : [];
|
|
|
+ if (data.length) {
|
|
|
+ data = [{ name: '全部乐团', id: '' }].concat(data);
|
|
|
+ studentMagege.musicGroups = data.map((item: any) => {
|
|
|
+ return {
|
|
|
+ text: item.name,
|
|
|
+ value: item.id
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 获取声部列表 */
|
|
|
+ const getSubjects = () => {
|
|
|
+ api_studentManageCoopSubjectList().then(res => {
|
|
|
+ let data = Array.isArray(res?.data) ? res.data : [];
|
|
|
+ if (data.length) {
|
|
|
+ data = [{ name: '全部声部', id: '' }].concat(data);
|
|
|
+ studentMagege.subjects = data.map((item: any) => {
|
|
|
+ return {
|
|
|
+ text: item.name,
|
|
|
+ value: item.id
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getSchoolData = () => {
|
|
|
+ api_studentManageUserCount({
|
|
|
+ ...fromData,
|
|
|
+ vipFlag:
|
|
|
+ fromData.vipFlag === '1'
|
|
|
+ ? true
|
|
|
+ : fromData.vipFlag === '2'
|
|
|
+ ? false
|
|
|
+ : ''
|
|
|
+ }).then(res => {
|
|
|
+ const data = res?.data;
|
|
|
+ if (data) {
|
|
|
+ studentMagege.studentCount = data.studentCount;
|
|
|
+ studentMagege.quitCount = data.quitCount;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getData = async () => {
|
|
|
+ studentMagege.loading = true;
|
|
|
+ api_studentManageUserPage({
|
|
|
+ ...fromData,
|
|
|
+ vipFlag:
|
|
|
+ fromData.vipFlag === '1'
|
|
|
+ ? true
|
|
|
+ : fromData.vipFlag === '2'
|
|
|
+ ? false
|
|
|
+ : ''
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ if (studentMagege.refresh) {
|
|
|
+ studentMagege.list = [];
|
|
|
+ }
|
|
|
+ const rows: IStudentManage[] = Array.isArray(res?.data?.rows)
|
|
|
+ ? res.data.rows
|
|
|
+ : [];
|
|
|
+ studentMagege.list = studentMagege.list.concat(rows);
|
|
|
+ if (!rows.length || rows.length < fromData.rows) {
|
|
|
+ studentMagege.finshed = true;
|
|
|
+ }
|
|
|
+ fromData.page++;
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ studentMagege.finshed = true;
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ studentMagege.loading = false;
|
|
|
+ studentMagege.refresh = false;
|
|
|
+ studentMagege.skelet = false;
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleSearch = () => {
|
|
|
+ fromData.page = 1;
|
|
|
+ studentMagege.refresh = true;
|
|
|
+ getSchoolData();
|
|
|
+ getData();
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ getGroups();
|
|
|
+ getSubjects();
|
|
|
+ getSchoolData();
|
|
|
+ });
|
|
|
+
|
|
|
+ return () => (
|
|
|
+ <div class={styles.container}>
|
|
|
+ <MSticky position="top">
|
|
|
+ <MHeader />
|
|
|
+ <MSearch
|
|
|
+ onSearch={value => {
|
|
|
+ fromData.keyword = value;
|
|
|
+ handleSearch();
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <DropdownMenu>
|
|
|
+ <DropdownItem
|
|
|
+ ref={musicGroupRef}
|
|
|
+ title={studentMagege.musicGroupName}>
|
|
|
+ <Picker
|
|
|
+ showToolbar={false}
|
|
|
+ visibleOptionNum={5}
|
|
|
+ columns={studentMagege.musicGroups}
|
|
|
+ onChange={value => {
|
|
|
+ studentMagege.musicGroupId = value.selectedValues[0];
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={['btnGroupPopup', 'van-hairline--top']}>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ onClick={() => {
|
|
|
+ musicGroupRef.value?.toggle(false);
|
|
|
+ }}>
|
|
|
+ 取消
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ disabled={!studentMagege.musicGroups.length}
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ onClick={() => {
|
|
|
+ musicGroupRef.value?.toggle(false);
|
|
|
+ fromData.musicGroupId = studentMagege.musicGroupId;
|
|
|
+ studentMagege.musicGroupName =
|
|
|
+ studentMagege.musicGroups.find(
|
|
|
+ _item => _item.value == studentMagege.musicGroupId
|
|
|
+ )?.text || '全部乐团';
|
|
|
+ handleSearch();
|
|
|
+ }}>
|
|
|
+ 确定
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </DropdownItem>
|
|
|
+ <DropdownItem ref={subjectRef} title={studentMagege.subjectName}>
|
|
|
+ <Picker
|
|
|
+ showToolbar={false}
|
|
|
+ visibleOptionNum={5}
|
|
|
+ columns={studentMagege.subjects}
|
|
|
+ onChange={value => {
|
|
|
+ const option = value.selectedOptions[0];
|
|
|
+ studentMagege.subjectId = option.value;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={['btnGroupPopup', 'van-hairline--top']}>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ onClick={() => {
|
|
|
+ subjectRef.value?.toggle(false);
|
|
|
+ }}>
|
|
|
+ 取消
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ disabled={!studentMagege.subjects.length}
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ onClick={() => {
|
|
|
+ subjectRef.value?.toggle(false);
|
|
|
+ fromData.subjectId = studentMagege.subjectId;
|
|
|
+ studentMagege.subjectName =
|
|
|
+ studentMagege.subjects.find(
|
|
|
+ _item => _item.value == studentMagege.subjectId
|
|
|
+ )?.text || '全部声部';
|
|
|
+ handleSearch();
|
|
|
+ }}>
|
|
|
+ 确定
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </DropdownItem>
|
|
|
+ <DropdownItem
|
|
|
+ title={studentMagege.studentTypeName}
|
|
|
+ v-model={fromData.vipFlag}
|
|
|
+ options={studentMagege.studentTypes}
|
|
|
+ onChange={value => {
|
|
|
+ studentMagege.studentTypeName =
|
|
|
+ studentMagege.studentTypes.find(_o => _o.value == value)
|
|
|
+ ?.text || '';
|
|
|
+ handleSearch();
|
|
|
+ }}></DropdownItem>
|
|
|
+ </DropdownMenu>
|
|
|
+ </MSticky>
|
|
|
+
|
|
|
+ <MFullRefresh
|
|
|
+ v-model:modelValue={studentMagege.refresh}
|
|
|
+ onRefresh={() => {
|
|
|
+ fromData.page = 1;
|
|
|
+ studentMagege.finshed = false;
|
|
|
+ getData();
|
|
|
+ }}>
|
|
|
+ <List
|
|
|
+ class={styles.list}
|
|
|
+ loading={studentMagege.loading}
|
|
|
+ finished={studentMagege.finshed}
|
|
|
+ onLoad={() => {
|
|
|
+ studentMagege.loading = true;
|
|
|
+ console.log('触底了');
|
|
|
+ getData();
|
|
|
+ }}>
|
|
|
+ <SkeletionIndex loading={studentMagege.skelet}>
|
|
|
+ <>
|
|
|
+ <div class={styles.statistics}>
|
|
|
+ <div class={styles.statisticsItem}>
|
|
|
+ <Image class={styles.iconstatistics} src={icon_zaidu} />
|
|
|
+ <div class={styles.statisticsDes}>
|
|
|
+ <div style={{ color: '#333' }}>
|
|
|
+ <span
|
|
|
+ class={styles.statisticsNum}
|
|
|
+ style={{ color: '#333' }}>
|
|
|
+ {studentMagege.studentCount}
|
|
|
+ </span>
|
|
|
+ 人
|
|
|
+ </div>
|
|
|
+ <div>在读学员</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class={styles.statisticsItem}
|
|
|
+ onClick={() => {
|
|
|
+ router.push({
|
|
|
+ path: '/student-manage-withdraw'
|
|
|
+ });
|
|
|
+ }}>
|
|
|
+ <Image class={styles.iconstatistics} src={icon_tuituan} />
|
|
|
+ <div class={styles.statisticsDes}>
|
|
|
+ <div style={{ color: '#333' }}>
|
|
|
+ <span
|
|
|
+ class={styles.statisticsNum}
|
|
|
+ style={{ color: '#FC1A19' }}>
|
|
|
+ {studentMagege.quitCount}
|
|
|
+ </span>
|
|
|
+ 人
|
|
|
+ </div>
|
|
|
+ <div>退团人数</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {studentMagege.list.map((item: IStudentManage) => (
|
|
|
+ <div class={styles.student}>
|
|
|
+ <MStudent item={item} />
|
|
|
+ {!!item.shouldAttendanceCount && (
|
|
|
+ <>
|
|
|
+ <Assignment item={item} />
|
|
|
+ <Attendance item={item} />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+
|
|
|
+ {!studentMagege.loading && !studentMagege.list.length && (
|
|
|
+ <MEmpty
|
|
|
+ description="暂无数据"
|
|
|
+ style={{
|
|
|
+ minHeight: '100%'
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ </SkeletionIndex>
|
|
|
+ </List>
|
|
|
+ </MFullRefresh>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|