|
@@ -0,0 +1,522 @@
|
|
|
+import { computed, defineComponent, onMounted, reactive, ref } from "vue";
|
|
|
+import styles from './train-model.module.less'
|
|
|
+import MSearch from "@/components/m-search";
|
|
|
+import { Button, Calendar, Cell, Col, DropdownItem, DropdownMenu, Picker, Popup, Row, showToast } from "vant";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import { musicGroupClassPage, musicGroupPage } from "./api";
|
|
|
+
|
|
|
+export function getNowDateAndMonday(time: any) {
|
|
|
+ let timestamp = new Date(time.replace(/-/g, "/")).getTime();
|
|
|
+ let serverDate = new Date(time);
|
|
|
+ if (serverDate.getDay() == 0) {
|
|
|
+ timestamp -= 7 * 24 * 60 * 60 * 1000;
|
|
|
+ }
|
|
|
+ let mondayTime = timestamp - (serverDate.getDay() - 1) * 24 * 60 * 60 * 1000;
|
|
|
+
|
|
|
+ let mondayData = new Date(mondayTime);
|
|
|
+ //年
|
|
|
+ let mondayY = mondayData.getFullYear();
|
|
|
+ //月
|
|
|
+ let mondayM =
|
|
|
+ mondayData.getMonth() + 1 < 10
|
|
|
+ ? "0" + (mondayData.getMonth() + 1)
|
|
|
+ : mondayData.getMonth() + 1;
|
|
|
+ //日
|
|
|
+ let mondayD =
|
|
|
+ mondayData.getDate() < 10
|
|
|
+ ? "0" + mondayData.getDate()
|
|
|
+ : mondayData.getDate();
|
|
|
+
|
|
|
+ let str = mondayY + "-" + mondayM + "-" + mondayD;
|
|
|
+ return str;
|
|
|
+}
|
|
|
+export function getNowDateAndSunday(time: any) {
|
|
|
+ let timestamp = new Date(time.replace(/-/g, "/")).getTime();
|
|
|
+ let serverDate = new Date(time);
|
|
|
+
|
|
|
+ let num = 7 - serverDate.getDay();
|
|
|
+ if (num == 7) {
|
|
|
+ num = 0;
|
|
|
+ }
|
|
|
+ let sundayTiem = timestamp + num * 24 * 60 * 60 * 1000;
|
|
|
+ let SundayData = new Date(sundayTiem);
|
|
|
+ //年
|
|
|
+ let tomorrowY = SundayData.getFullYear(); //月
|
|
|
+ let tomorrowM =
|
|
|
+ SundayData.getMonth() + 1 < 10
|
|
|
+ ? "0" + (SundayData.getMonth() + 1)
|
|
|
+ : SundayData.getMonth() + 1;
|
|
|
+ //日
|
|
|
+ let tomorrowD =
|
|
|
+ SundayData.getDate() < 10
|
|
|
+ ? "0" + SundayData.getDate()
|
|
|
+ : SundayData.getDate();
|
|
|
+ let str = tomorrowY + "-" + tomorrowM + "-" + tomorrowD;
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ props: {
|
|
|
+ active: {
|
|
|
+ type: String,
|
|
|
+ default: 'all'
|
|
|
+ },
|
|
|
+ defaultTime: {
|
|
|
+ type: Number,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ },
|
|
|
+ name: 'train-model',
|
|
|
+ emits: ['load'],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const state = reactive({
|
|
|
+ showCalendar: false,
|
|
|
+ showMusicGroup: false,
|
|
|
+ musicGroupList: [] as any,
|
|
|
+ showClass: false,
|
|
|
+ classList: [] as any,
|
|
|
+ minDate: new Date(2000, 0, 1),
|
|
|
+ defaultDate: [] as any,
|
|
|
+ memberFlag: '',
|
|
|
+ studentType: '', // 1 -> musicFlag,2 -> hasEndVipFlag,3 -> hasNotStartVipFlag
|
|
|
+ // 类型为全部时
|
|
|
+ startDay: null as any,
|
|
|
+ endDay: null as any,
|
|
|
+ calendarStatus: false,
|
|
|
+ search: null,
|
|
|
+ searchArray: [null, null, null, null],
|
|
|
+ searchType: {
|
|
|
+ // ASC DESC
|
|
|
+ totalPlayTime: null,
|
|
|
+ trainNum: null,
|
|
|
+ trainDay: null,
|
|
|
+ recordNum: null
|
|
|
+ },
|
|
|
+ organId: '',
|
|
|
+ organName: '全部分部',
|
|
|
+ musicGroupId: '',
|
|
|
+ musicGroupName: '全部乐团',
|
|
|
+ classId: '',
|
|
|
+ className: '全部班级'
|
|
|
+ })
|
|
|
+ const dropDownRef = ref()
|
|
|
+ const calendarValue = computed(() => {
|
|
|
+ return `${dayjs(state.startDay).format('YYYY/MM/DD')} - ${dayjs(
|
|
|
+ state.endDay
|
|
|
+ ).format('YYYY/MM/DD')}`;
|
|
|
+ })
|
|
|
+
|
|
|
+ const onSetMusicGrouop = (val: any) => {
|
|
|
+ const option = val.selectedOptions[0]
|
|
|
+ state.musicGroupId = option.value;
|
|
|
+ state.musicGroupName = option.text;
|
|
|
+ state.showMusicGroup = false;
|
|
|
+ getClassList();
|
|
|
+ }
|
|
|
+ const onSetClass = (val: any) => {
|
|
|
+ const option = val.selectedOptions[0]
|
|
|
+ state.classId = option.value;
|
|
|
+ state.className = option.text;
|
|
|
+ state.showClass = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ const getOrchestraList = async () => {
|
|
|
+ try {
|
|
|
+ const { data } = await musicGroupPage({
|
|
|
+ organId: state.organId
|
|
|
+ });
|
|
|
+ const result = data || [];
|
|
|
+ const tempList = [
|
|
|
+ {
|
|
|
+ text: '全部乐团',
|
|
|
+ value: ''
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ tempList.push({
|
|
|
+ text: item.name,
|
|
|
+ value: item.id
|
|
|
+ });
|
|
|
+ });
|
|
|
+ state.musicGroupList = tempList;
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const getClassList = async () => {
|
|
|
+ try {
|
|
|
+ const { data } = await musicGroupClassPage({
|
|
|
+ organId: state.organId,
|
|
|
+ musicGroupId: state.musicGroupId
|
|
|
+ });
|
|
|
+ const result = data || [];
|
|
|
+ const tempList = [
|
|
|
+ {
|
|
|
+ text: '全部乐团',
|
|
|
+ value: ''
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ tempList.push({
|
|
|
+ text: item.name,
|
|
|
+ value: item.id
|
|
|
+ });
|
|
|
+ });
|
|
|
+ state.classList = tempList;
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const onCheckType = (type: string, value: string) => {
|
|
|
+ if (type === 'member') {
|
|
|
+ state.memberFlag = value;
|
|
|
+ } else if (type === 'type') {
|
|
|
+ state.studentType = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const onSort = (type?: any) => {
|
|
|
+ let searchArray: any = state.searchArray;
|
|
|
+ searchArray.forEach((item: any, index: any) => {
|
|
|
+ if (index != type) {
|
|
|
+ searchArray[index] = null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (searchArray[type] == 'ASC') {
|
|
|
+ searchArray[type] = 'DESC';
|
|
|
+ } else if (searchArray[type] == 'DESC') {
|
|
|
+ searchArray[type] = null;
|
|
|
+ } else {
|
|
|
+ searchArray[type] = 'ASC';
|
|
|
+ }
|
|
|
+ onAllFilter();
|
|
|
+ }
|
|
|
+
|
|
|
+ const onAllFilter = () => {
|
|
|
+ const searchArray = state.searchArray;
|
|
|
+ let currentIndex: any = null;
|
|
|
+ let currentType = null;
|
|
|
+ searchArray.forEach((item, index) => {
|
|
|
+ if (item) {
|
|
|
+ currentIndex = index;
|
|
|
+ currentType = item;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const searchType = ['totalPlayTime', 'trainNum', 'trainDay', 'recordNum'];
|
|
|
+ // 1 -> musicFlag,2 -> hasEndVipFlag,3 -> hasNotStartVipFlag
|
|
|
+ let params = {
|
|
|
+ search: state.search,
|
|
|
+ memberFlag: state.memberFlag,
|
|
|
+ musicFlag: state.studentType === '1' ? true : false,
|
|
|
+ hasEndVipFlag: state.studentType === '2' ? true : false,
|
|
|
+ hasNotStartVipFlag: state.studentType === '3' ? true : false,
|
|
|
+ startTime: state.startDay,
|
|
|
+ endTime: state.endDay,
|
|
|
+ classGroupId: state.classId,
|
|
|
+ musicGroupId: state.musicGroupId,
|
|
|
+ organId: state.organId,
|
|
|
+ page: 1,
|
|
|
+ sort: searchType[currentIndex],
|
|
|
+ order: currentType
|
|
|
+ };
|
|
|
+ emit('load', params);
|
|
|
+ }
|
|
|
+
|
|
|
+ const changeDropDownItemStatus = () => {
|
|
|
+ dropDownRef.value?.toggle(false);
|
|
|
+ }
|
|
|
+ const onSubmit = () => {
|
|
|
+ changeDropDownItemStatus();
|
|
|
+ onAllFilter();
|
|
|
+ }
|
|
|
+ const onReset = () => {
|
|
|
+ let defaultTime = props.defaultTime;
|
|
|
+ let day = defaultTime * 7;
|
|
|
+ let startTime: any = new Date(),
|
|
|
+ endTime: any = new Date();
|
|
|
+ if (day > 0) {
|
|
|
+ startTime = getNowDateAndMonday(
|
|
|
+ dayjs().add(day, 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ endTime = getNowDateAndSunday(
|
|
|
+ dayjs().add(day, 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ startTime = getNowDateAndMonday(
|
|
|
+ dayjs().subtract(Math.abs(day), 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ endTime = getNowDateAndSunday(
|
|
|
+ dayjs().subtract(Math.abs(day), 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ }
|
|
|
+ state.defaultDate = [new Date(startTime), new Date(endTime)];
|
|
|
+ state.startDay = startTime;
|
|
|
+ state.endDay = endTime;
|
|
|
+ state.memberFlag = "";
|
|
|
+ state.studentType = "";
|
|
|
+ state.musicGroupId = "";
|
|
|
+ state.musicGroupName = "全部乐团";
|
|
|
+ state.classId = "";
|
|
|
+ state.className = "全部班级";
|
|
|
+ onSubmit();
|
|
|
+ }
|
|
|
+
|
|
|
+ const selectDate = (date: any) => {
|
|
|
+ let [start, end] = date;
|
|
|
+ if (start) {
|
|
|
+ const num = dayjs(start).get('day');
|
|
|
+ if (num === 0) {
|
|
|
+ start = dayjs(start).subtract(6, 'day');
|
|
|
+ } else {
|
|
|
+ start = dayjs(start).subtract(num - 1, 'day');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (start) {
|
|
|
+ const num = 7 - dayjs(start).get('day');
|
|
|
+ if (num < 7) {
|
|
|
+ end = dayjs(start).add(num, 'day');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ state.defaultDate = [new Date(start.valueOf()), new Date(end.valueOf())];
|
|
|
+ }
|
|
|
+ const onConfirm = (date: any) => {
|
|
|
+ let [start, end] = date;
|
|
|
+ state.showCalendar = false;
|
|
|
+ if (start) {
|
|
|
+ const num = dayjs(start).get('day');
|
|
|
+ if (num === 0) {
|
|
|
+ start = dayjs(start).subtract(6, 'day');
|
|
|
+ } else {
|
|
|
+ start = dayjs(start).subtract(num - 1, 'day');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (end) {
|
|
|
+ const num = 7 - dayjs(end).get('day');
|
|
|
+ if (num < 7) {
|
|
|
+ end = dayjs(end).add(num, 'day');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ state.calendarStatus = true
|
|
|
+ state.startDay = dayjs(start).format('YYYY-MM-DD');
|
|
|
+ state.endDay = dayjs(end).format('YYYY-MM-DD');
|
|
|
+ //
|
|
|
+ // this.changeDropDownItemStatus();
|
|
|
+ // this.onAllFilter();
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ let defaultTime = props.defaultTime;
|
|
|
+ let day = defaultTime * 7;
|
|
|
+ let startTime: any = new Date(),
|
|
|
+ endTime: any = new Date();
|
|
|
+ if (day > 0) {
|
|
|
+ startTime = getNowDateAndMonday(
|
|
|
+ dayjs().add(day, 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ endTime = getNowDateAndSunday(
|
|
|
+ dayjs().add(day, 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ startTime = getNowDateAndMonday(
|
|
|
+ dayjs().subtract(Math.abs(day), 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ endTime = getNowDateAndSunday(
|
|
|
+ dayjs().subtract(Math.abs(day), 'day').format('YYYY-MM-DD')
|
|
|
+ );
|
|
|
+ }
|
|
|
+ state.defaultDate = [new Date(startTime), new Date(endTime)];
|
|
|
+ state.startDay = startTime;
|
|
|
+ state.endDay = endTime;
|
|
|
+
|
|
|
+ onSort();
|
|
|
+ getOrchestraList()
|
|
|
+ })
|
|
|
+ return () => <div class={styles.trainModel}>
|
|
|
+ <MSearch placeholder="学生姓名或手机号"
|
|
|
+ // disabled={forms.listState.refreshing}
|
|
|
+ onSearch={(val: string) => {
|
|
|
+ // forms.params.keyword = val;
|
|
|
+ // forms.listState.refreshing = true;
|
|
|
+ // onRefresh();
|
|
|
+ }}>
|
|
|
+ {{
|
|
|
+ left: () => (
|
|
|
+ <DropdownMenu
|
|
|
+ class={styles.patrolDetailDropDown}
|
|
|
+ style={{ 'padding-right': '10px' }}
|
|
|
+ closeOnClickOutside={false}>
|
|
|
+ <DropdownItem title={'筛选'} ref={dropDownRef} >
|
|
|
+ <div class="search-group">
|
|
|
+ <Cell title={'日期'}
|
|
|
+ isLink
|
|
|
+ onClick={() => {state.showCalendar = true
|
|
|
+ state.calendarStatus = false
|
|
|
+ }}
|
|
|
+ titleClass={styles.cellTitle}
|
|
|
+ value={calendarValue.value}
|
|
|
+ valueClass={styles.calendarColor}
|
|
|
+ class={styles.studentCell}></Cell>
|
|
|
+ <Cell title={'是否学员'} titleClass={styles.cellTitle} class={styles.studentCell}>
|
|
|
+ {{
|
|
|
+ label: () => <div class={styles['btn-group']}>
|
|
|
+ <Button plain={state.memberFlag === ''}
|
|
|
+ round
|
|
|
+ type={state.memberFlag === '' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('member', '')}>
|
|
|
+ 全部学员
|
|
|
+ </Button>
|
|
|
+ <Button plain={state.memberFlag === '1'}
|
|
|
+ round
|
|
|
+ type={state.memberFlag === '1' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('member', '1')}>
|
|
|
+ 会员学员
|
|
|
+ </Button>
|
|
|
+ <Button plain={state.memberFlag === '0'}
|
|
|
+ round
|
|
|
+ type={state.memberFlag === '0' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('member', '0')}>
|
|
|
+ 普通学员
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell title={'是否学员'} titleClass={styles.cellTitle} class={styles.studentCell}>
|
|
|
+ {{
|
|
|
+ label: () => <div class={styles['btn-group']}>
|
|
|
+ <Button plain={state.studentType === ''}
|
|
|
+ round
|
|
|
+ type={state.studentType === '' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('type', '')}>
|
|
|
+ 全部学员
|
|
|
+ </Button>
|
|
|
+ <Button plain={state.studentType === '1'}
|
|
|
+ round
|
|
|
+ type={state.studentType === '1' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('type', '1')}>
|
|
|
+ 乐团学员
|
|
|
+ </Button>
|
|
|
+ <Button plain={state.studentType === '2'}
|
|
|
+ round
|
|
|
+ type={state.studentType === '2' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('type', '2')}>
|
|
|
+ 已结束小课学员
|
|
|
+ </Button>
|
|
|
+ <Button plain={state.studentType === '3'}
|
|
|
+ round
|
|
|
+ type={state.studentType === '3' ? 'primary' : 'default'}
|
|
|
+ onClick={() => onCheckType('type', '3')}>
|
|
|
+ 进行中小课学员
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ <Cell title={'乐团'}
|
|
|
+ isLink
|
|
|
+ onClick={() => state.showMusicGroup = true}
|
|
|
+ titleClass={styles.cellTitle}
|
|
|
+ value={state.musicGroupName}
|
|
|
+ valueClass={styles.calendarColor}
|
|
|
+ class={styles.studentCell}></Cell>
|
|
|
+ <Cell title={'班级'}
|
|
|
+ isLink
|
|
|
+ onClick={() => {
|
|
|
+ if (!state.musicGroupId) {
|
|
|
+ showToast('请选择乐团');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ state.showClass = true
|
|
|
+ }}
|
|
|
+ titleClass={styles.cellTitle}
|
|
|
+ value={state.className}
|
|
|
+ valueClass={styles.calendarColor}
|
|
|
+ class={styles.studentCell}></Cell>
|
|
|
+ </div>
|
|
|
+ <div class={[styles['submit-group'], 'van-hairline--top']}>
|
|
|
+ <Button round block onClick={onReset} style={{ marginRight: '10px' }}>
|
|
|
+ 重置
|
|
|
+ </Button>
|
|
|
+ <Button type="primary" round block onClick={onSubmit}>
|
|
|
+ 确认
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </DropdownItem>
|
|
|
+ </DropdownMenu>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </MSearch>
|
|
|
+ <Row class={styles.searchArray}>
|
|
|
+ <Col span="6" class={styles['title-style']} onClick={() => onSort(0)}>
|
|
|
+ 训练时长
|
|
|
+ <div>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles["box-up"], state.searchArray[0] == 'ASC' && styles.active]}
|
|
|
+ style="margin-bottom: 0.03rem"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles['box-down'], state.searchArray[0] === 'DESC' && styles.active]}
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </Col >
|
|
|
+ <Col span="6" class={styles['title-style']} onClick={() => onSort(1)} >
|
|
|
+ 训练次数
|
|
|
+ <div>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles["box-up"], state.searchArray[1] == 'ASC' && styles.active]}
|
|
|
+ style="margin-bottom: 0.03rem"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles['box-down'], state.searchArray[1] === 'DESC' && styles.active]}
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col span="6" class={styles['title-style']} onClick={() => onSort(2)} >
|
|
|
+ 训练天数
|
|
|
+ <div>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles["box-up"], state.searchArray[2] == 'ASC' && styles.active]}
|
|
|
+ style="margin-bottom: 0.03rem"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles['box-down'], state.searchArray[2] === 'DESC' && styles.active]}
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ <Col span="6" class={styles['title-style']} onClick={() => onSort(3)} >
|
|
|
+ 评测次数
|
|
|
+ <div>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles["box-up"], state.searchArray[3] == 'ASC' && styles.active]}
|
|
|
+ style="margin-bottom: 0.03rem"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class={[styles['box'], styles['box-down'], state.searchArray[3] === 'DESC' && styles.active]}
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+
|
|
|
+ <Calendar v-model:show={state.showCalendar}
|
|
|
+ minDate={state.minDate}
|
|
|
+ defaultDate={state.defaultDate}
|
|
|
+ firstDayOfWeek={1} color="#01c1b5" type="range"
|
|
|
+ onSelect={selectDate}
|
|
|
+ onConfirm={onConfirm}
|
|
|
+ onUpdate:show={(val: any) => {
|
|
|
+ console.log('1111')
|
|
|
+ if (!state.calendarStatus) {
|
|
|
+ state.defaultDate = [new Date(state.startDay), new Date(state.endDay)];
|
|
|
+ }
|
|
|
+ }} />
|
|
|
+
|
|
|
+ <Popup v-model:show={state.showMusicGroup} position="bottom" round>
|
|
|
+ <Picker columns={state.musicGroupList} showToolbar onCancel={() => state.showMusicGroup = false} onConfirm={onSetMusicGrouop} />
|
|
|
+ </Popup>
|
|
|
+
|
|
|
+ <Popup v-model:show={state.showClass} position="bottom" round>
|
|
|
+ <Picker columns={state.classList} showToolbar onCancel={() => state.showClass = false} onConfirm={onSetClass} />
|
|
|
+ </Popup>
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+})
|