|  | @@ -1,8 +1,487 @@
 | 
	
		
			
				|  |  | -import { defineComponent } from "vue";
 | 
	
		
			
				|  |  | +import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
 | 
	
		
			
				|  |  | +import styles from './index.module.less';
 | 
	
		
			
				|  |  | +import MSticky from '@/components/m-sticky';
 | 
	
		
			
				|  |  | +import MHeader from '@/components/m-header';
 | 
	
		
			
				|  |  | +import icon_detail_bg from '../images/icon_detail_bg.png';
 | 
	
		
			
				|  |  | +import icon_music from '@common/images/icon-music.png';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  Button,
 | 
	
		
			
				|  |  | +  Cell,
 | 
	
		
			
				|  |  | +  CellGroup,
 | 
	
		
			
				|  |  | +  Checkbox,
 | 
	
		
			
				|  |  | +  CheckboxGroup,
 | 
	
		
			
				|  |  | +  Field,
 | 
	
		
			
				|  |  | +  Grid,
 | 
	
		
			
				|  |  | +  GridItem,
 | 
	
		
			
				|  |  | +  Image,
 | 
	
		
			
				|  |  | +  Picker,
 | 
	
		
			
				|  |  | +  Popup,
 | 
	
		
			
				|  |  | +  showToast
 | 
	
		
			
				|  |  | +} from 'vant';
 | 
	
		
			
				|  |  | +import MStudent from '../component/m-student';
 | 
	
		
			
				|  |  | +import { IMusicGroup, IStudentDetail } from '../type';
 | 
	
		
			
				|  |  | +import Assignment from '../component/Assignment';
 | 
	
		
			
				|  |  | +import Attendance from '../component/Attendance';
 | 
	
		
			
				|  |  | +import icon_pen from '@common/images/icon_pen.png';
 | 
	
		
			
				|  |  | +import icon_phone from '../images/icon-phone.png';
 | 
	
		
			
				|  |  | +import icon_message from '../images/icon-message.png';
 | 
	
		
			
				|  |  | +import SkeletionDetail from './skeletion-detail';
 | 
	
		
			
				|  |  | +import { useRoute } from 'vue-router';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  api_organizationGetGradeList,
 | 
	
		
			
				|  |  | +  api_studentManageQuitMusicGroup,
 | 
	
		
			
				|  |  | +  api_studentManageUpdateGrade,
 | 
	
		
			
				|  |  | +  api_studentManageUserDetail,
 | 
	
		
			
				|  |  | +  api_studentManageUserMusicGroup
 | 
	
		
			
				|  |  | +} from '../api';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export default defineComponent({
 | 
	
		
			
				|  |  | -    name: 'student-manage-detail',
 | 
	
		
			
				|  |  | -    setup(){
 | 
	
		
			
				|  |  | -        return () => <div></div>
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -})
 | 
	
		
			
				|  |  | +  name: 'student-manage-detail',
 | 
	
		
			
				|  |  | +  setup() {
 | 
	
		
			
				|  |  | +    const route = useRoute();
 | 
	
		
			
				|  |  | +    const studentId: string | undefined =
 | 
	
		
			
				|  |  | +      route.query?.studentId?.toString() || '';
 | 
	
		
			
				|  |  | +    const musicGroupIds: string[] =
 | 
	
		
			
				|  |  | +      route.query.musicGroupIds?.toString()?.split(',') || [];
 | 
	
		
			
				|  |  | +    const detailData = reactive({
 | 
	
		
			
				|  |  | +      skelet: true,
 | 
	
		
			
				|  |  | +      /** 加载 */
 | 
	
		
			
				|  |  | +      loading: false,
 | 
	
		
			
				|  |  | +      /** 乐团 */
 | 
	
		
			
				|  |  | +      groupShow: false,
 | 
	
		
			
				|  |  | +      /** 退团 */
 | 
	
		
			
				|  |  | +      quitShow: false,
 | 
	
		
			
				|  |  | +      /** 确定退团 */
 | 
	
		
			
				|  |  | +      quitConfirmShow: false,
 | 
	
		
			
				|  |  | +      /** 联系方式 */
 | 
	
		
			
				|  |  | +      cancelShow: false,
 | 
	
		
			
				|  |  | +      /** 年级 */
 | 
	
		
			
				|  |  | +      gradeShow: false,
 | 
	
		
			
				|  |  | +      gradeOptions: [[], []] as any,
 | 
	
		
			
				|  |  | +      musicGroup: [] as IMusicGroup[],
 | 
	
		
			
				|  |  | +      musicGroupTitle: '全部乐团',
 | 
	
		
			
				|  |  | +      musicGroupId: musicGroupIds[0] || '',
 | 
	
		
			
				|  |  | +      student: {} as IStudentDetail,
 | 
	
		
			
				|  |  | +      /** 年级列表 */
 | 
	
		
			
				|  |  | +      gradeList: null as any,
 | 
	
		
			
				|  |  | +      /** 退团列表 */
 | 
	
		
			
				|  |  | +      quitList: [] as any[],
 | 
	
		
			
				|  |  | +      /** 退团原因 */
 | 
	
		
			
				|  |  | +      reason: '',
 | 
	
		
			
				|  |  | +      quitLoading: false
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const checkboxRefs = ref<any[]>([]);
 | 
	
		
			
				|  |  | +    /** 获取学生乐团 */
 | 
	
		
			
				|  |  | +    const getMusicGroup = () => {
 | 
	
		
			
				|  |  | +      api_studentManageUserMusicGroup(studentId).then(res => {
 | 
	
		
			
				|  |  | +        if (Array.isArray(res.data)) {
 | 
	
		
			
				|  |  | +          detailData.musicGroup = res.data.map((item: any) => {
 | 
	
		
			
				|  |  | +            return {
 | 
	
		
			
				|  |  | +              text: item.name,
 | 
	
		
			
				|  |  | +              value: item.id,
 | 
	
		
			
				|  |  | +              gradeType: item.gradeType
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  | +          if (detailData.musicGroup.length === 1) {
 | 
	
		
			
				|  |  | +            detailData.musicGroupTitle = detailData.musicGroup[0].text;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 获取年级分布 */
 | 
	
		
			
				|  |  | +    const getGradeList = () => {
 | 
	
		
			
				|  |  | +      if (detailData.student.organId && detailData.musicGroup.length) {
 | 
	
		
			
				|  |  | +        if (detailData.gradeList) return;
 | 
	
		
			
				|  |  | +        console.log(detailData.musicGroup);
 | 
	
		
			
				|  |  | +        const gradeType = Array.from(
 | 
	
		
			
				|  |  | +          new Set(detailData.musicGroup.map(group => group.gradeType))
 | 
	
		
			
				|  |  | +        ).join(',');
 | 
	
		
			
				|  |  | +        console.log('🚀 ~ gradeType:', gradeType);
 | 
	
		
			
				|  |  | +        api_organizationGetGradeList(
 | 
	
		
			
				|  |  | +          detailData.student.organId,
 | 
	
		
			
				|  |  | +          gradeType
 | 
	
		
			
				|  |  | +        ).then(res => {
 | 
	
		
			
				|  |  | +          detailData.gradeList = res.data;
 | 
	
		
			
				|  |  | +          detailData.gradeOptions[0] = Object.entries(res.data).map(
 | 
	
		
			
				|  |  | +            (value: any) => {
 | 
	
		
			
				|  |  | +              return {
 | 
	
		
			
				|  |  | +                text: value[1],
 | 
	
		
			
				|  |  | +                value: value[0]
 | 
	
		
			
				|  |  | +              };
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          );
 | 
	
		
			
				|  |  | +          detailData.gradeOptions[1] = new Array(30)
 | 
	
		
			
				|  |  | +            .fill(1)
 | 
	
		
			
				|  |  | +            .map((_, index: number) => ({
 | 
	
		
			
				|  |  | +              text: `${index + 1}班`,
 | 
	
		
			
				|  |  | +              value: `${index + 1}班`
 | 
	
		
			
				|  |  | +            }));
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      setTimeout(() => {
 | 
	
		
			
				|  |  | +        getGradeList();
 | 
	
		
			
				|  |  | +      }, 30);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const getDatail = () => {
 | 
	
		
			
				|  |  | +      detailData.loading = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      api_studentManageUserDetail({
 | 
	
		
			
				|  |  | +        studentId: studentId,
 | 
	
		
			
				|  |  | +        musicGroupId: detailData.musicGroupId || ''
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +        .then(res => {
 | 
	
		
			
				|  |  | +          if (res.data) {
 | 
	
		
			
				|  |  | +            if (res.data.phone) {
 | 
	
		
			
				|  |  | +              res.data.phone =
 | 
	
		
			
				|  |  | +                res.data.phone.slice(0, 3) + '****' + res.data.phone.slice(-4);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            detailData.student = res.data;
 | 
	
		
			
				|  |  | +            getGradeList();
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        .finally(() => {
 | 
	
		
			
				|  |  | +          setTimeout(() => {
 | 
	
		
			
				|  |  | +            detailData.loading = false;
 | 
	
		
			
				|  |  | +            detailData.skelet = false;
 | 
	
		
			
				|  |  | +          }, 500);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    onMounted(() => {
 | 
	
		
			
				|  |  | +      getMusicGroup();
 | 
	
		
			
				|  |  | +      getDatail();
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const quitName = computed(() => {
 | 
	
		
			
				|  |  | +      const text = detailData.musicGroup
 | 
	
		
			
				|  |  | +        .filter(group => detailData.quitList.includes(group.value))
 | 
	
		
			
				|  |  | +        .map(group => {
 | 
	
		
			
				|  |  | +          return '“' + group.text + '”';
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        .join('、');
 | 
	
		
			
				|  |  | +      return `${detailData.student.studentName}从${text}`;
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 设置学生班级 */
 | 
	
		
			
				|  |  | +    const handleSetGrade = async (selectedOptions: any[]) => {
 | 
	
		
			
				|  |  | +      const res = await api_studentManageUpdateGrade({
 | 
	
		
			
				|  |  | +        currentClass: selectedOptions[1].value, // 班级
 | 
	
		
			
				|  |  | +        currentGrade: selectedOptions[0].text, // 年级
 | 
	
		
			
				|  |  | +        currentGradeNum: selectedOptions[0].value, // 年级(数字表示)
 | 
	
		
			
				|  |  | +        musicGroupId: detailData.musicGroupId, // 乐团ID
 | 
	
		
			
				|  |  | +        studentId: detailData.student.studentId // 学生ID
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      console.log(res);
 | 
	
		
			
				|  |  | +      if (res.code === 200) {
 | 
	
		
			
				|  |  | +        showToast('修改成功');
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      getDatail();
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 退团 */
 | 
	
		
			
				|  |  | +    const handleQuite = async () => {
 | 
	
		
			
				|  |  | +      if (!detailData.reason) {
 | 
	
		
			
				|  |  | +        showToast('请填写退团原因');
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      detailData.quitLoading = true;
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res = await api_studentManageQuitMusicGroup({
 | 
	
		
			
				|  |  | +          musicGroupId: detailData.quitList.join(','),
 | 
	
		
			
				|  |  | +          reason: detailData.reason,
 | 
	
		
			
				|  |  | +          reasonEnum: 'OTHER',
 | 
	
		
			
				|  |  | +          userId: detailData.student.studentId
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        detailData.quitConfirmShow = false;
 | 
	
		
			
				|  |  | +        if (res.code === 200) {
 | 
	
		
			
				|  |  | +          detailData.quitList = [];
 | 
	
		
			
				|  |  | +          getDatail();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch (error) {}
 | 
	
		
			
				|  |  | +      detailData.quitLoading = false;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 去聊天 */
 | 
	
		
			
				|  |  | +    const openIm = () => {
 | 
	
		
			
				|  |  | +      postMessage({
 | 
	
		
			
				|  |  | +        api: 'joinChatGroup',
 | 
	
		
			
				|  |  | +        content: {
 | 
	
		
			
				|  |  | +          type: 'single', // single 单人 multi 多人
 | 
	
		
			
				|  |  | +          id: detailData.student.studentId
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /** 打电话 */
 | 
	
		
			
				|  |  | +    const hanldeCallPhone = () => {
 | 
	
		
			
				|  |  | +      postMessage({
 | 
	
		
			
				|  |  | +        api: 'callPhone',
 | 
	
		
			
				|  |  | +        content: {
 | 
	
		
			
				|  |  | +          phone: detailData.student.phone
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <div class={styles.studentDetail}>
 | 
	
		
			
				|  |  | +        <Image class={styles.bg} src={icon_detail_bg} />
 | 
	
		
			
				|  |  | +        <MSticky position="top">
 | 
	
		
			
				|  |  | +          <MHeader background="transparent" />
 | 
	
		
			
				|  |  | +        </MSticky>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <SkeletionDetail loading={detailData.skelet}>
 | 
	
		
			
				|  |  | +          <Cell
 | 
	
		
			
				|  |  | +            class={styles.musicGroup}
 | 
	
		
			
				|  |  | +            title={detailData.musicGroupTitle}
 | 
	
		
			
				|  |  | +            isLink={detailData.musicGroup.length > 1 ? true : false}
 | 
	
		
			
				|  |  | +            clickable={detailData.musicGroup.length > 1 ? true : false}
 | 
	
		
			
				|  |  | +            center
 | 
	
		
			
				|  |  | +            border={false}
 | 
	
		
			
				|  |  | +            onClick={() => {
 | 
	
		
			
				|  |  | +              if (detailData.musicGroup.length < 2) return;
 | 
	
		
			
				|  |  | +              detailData.groupShow = true;
 | 
	
		
			
				|  |  | +            }}>
 | 
	
		
			
				|  |  | +            {{
 | 
	
		
			
				|  |  | +              icon: () => <Image class={styles.iconMusic} src={icon_music} />
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          </Cell>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.box}>
 | 
	
		
			
				|  |  | +            <MStudent
 | 
	
		
			
				|  |  | +              item={detailData.student}
 | 
	
		
			
				|  |  | +              valueType={
 | 
	
		
			
				|  |  | +                detailData.student.inGroupStatus === 'OUT'
 | 
	
		
			
				|  |  | +                  ? 'statued'
 | 
	
		
			
				|  |  | +                  : detailData.student.inGroupStatus === 'APPLY_OUT'
 | 
	
		
			
				|  |  | +                  ? 'statuing'
 | 
	
		
			
				|  |  | +                  : 'status'
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +              isLink={false}
 | 
	
		
			
				|  |  | +              onQuit={() => (detailData.quitShow = true)}
 | 
	
		
			
				|  |  | +              onContact={() => (detailData.cancelShow = true)}
 | 
	
		
			
				|  |  | +            />
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.infobox}>
 | 
	
		
			
				|  |  | +            <div class={styles.attendanceTitle}>
 | 
	
		
			
				|  |  | +              <span>基本信息</span>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.infoItem}>
 | 
	
		
			
				|  |  | +              <div>性别</div>
 | 
	
		
			
				|  |  | +              <div>{detailData.student.gender ? '男' : '女'}</div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.infoItem}>
 | 
	
		
			
				|  |  | +              <div>联系电话</div>
 | 
	
		
			
				|  |  | +              <div>{detailData.student.phone}</div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.infoItem}>
 | 
	
		
			
				|  |  | +              <div>年级</div>
 | 
	
		
			
				|  |  | +              <div
 | 
	
		
			
				|  |  | +                class={styles.edit}
 | 
	
		
			
				|  |  | +                onClick={() => {
 | 
	
		
			
				|  |  | +                  if (detailData.student.inGroupStatus === 'OUT') return;
 | 
	
		
			
				|  |  | +                  detailData.gradeShow = true;
 | 
	
		
			
				|  |  | +                }}>
 | 
	
		
			
				|  |  | +                {detailData.student.currentGrade}年级
 | 
	
		
			
				|  |  | +                {detailData.student.currentClass}
 | 
	
		
			
				|  |  | +                {detailData.student.inGroupStatus !== 'OUT' && (
 | 
	
		
			
				|  |  | +                  <Image class={styles.iconPen} src={icon_pen} />
 | 
	
		
			
				|  |  | +                )}
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.infoItem}>
 | 
	
		
			
				|  |  | +              <div>艺术实践</div>
 | 
	
		
			
				|  |  | +              <div>{detailData.student.artPracticeCount}次</div>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            {detailData.student.quitTime && (
 | 
	
		
			
				|  |  | +              <div class={styles.infoItem}>
 | 
	
		
			
				|  |  | +                <div>退团时间</div>
 | 
	
		
			
				|  |  | +                <div style={{ color: '#FF5A56' }}>
 | 
	
		
			
				|  |  | +                  {detailData.student.quitTime}
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            )}
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.box}>
 | 
	
		
			
				|  |  | +            <Assignment item={detailData.student} />
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          <div class={styles.box}>
 | 
	
		
			
				|  |  | +            <Attendance item={detailData.student} />
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </SkeletionDetail>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 切换乐团 */}
 | 
	
		
			
				|  |  | +        <Popup v-model:show={detailData.groupShow} position="bottom" round>
 | 
	
		
			
				|  |  | +          <Picker
 | 
	
		
			
				|  |  | +            visibleOptionNum={5}
 | 
	
		
			
				|  |  | +            columns={detailData.musicGroup}
 | 
	
		
			
				|  |  | +            onCancel={() => (detailData.groupShow = false)}
 | 
	
		
			
				|  |  | +            onConfirm={value => {
 | 
	
		
			
				|  |  | +              const option = value.selectedOptions[0];
 | 
	
		
			
				|  |  | +              const oldGroupId = detailData.musicGroupId;
 | 
	
		
			
				|  |  | +              detailData.musicGroupId = option.value;
 | 
	
		
			
				|  |  | +              detailData.musicGroupTitle = option.text;
 | 
	
		
			
				|  |  | +              detailData.groupShow = false;
 | 
	
		
			
				|  |  | +              if (oldGroupId != option.value) {
 | 
	
		
			
				|  |  | +                getDatail();
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 联系方式 */}
 | 
	
		
			
				|  |  | +        <Popup
 | 
	
		
			
				|  |  | +          v-model:show={detailData.cancelShow}
 | 
	
		
			
				|  |  | +          position="bottom"
 | 
	
		
			
				|  |  | +          round
 | 
	
		
			
				|  |  | +          closeable>
 | 
	
		
			
				|  |  | +          <div class={styles.concatBox}>
 | 
	
		
			
				|  |  | +            <div class={styles.concatTitle}>联系方式</div>
 | 
	
		
			
				|  |  | +            <div class={styles.concatContent}>
 | 
	
		
			
				|  |  | +              <Grid columnNum={2} border={false} center>
 | 
	
		
			
				|  |  | +                <GridItem text="发送消息" onClick={openIm}>
 | 
	
		
			
				|  |  | +                  {{
 | 
	
		
			
				|  |  | +                    icon: () => (
 | 
	
		
			
				|  |  | +                      <Image class={styles.concatIcon} src={icon_message} />
 | 
	
		
			
				|  |  | +                    )
 | 
	
		
			
				|  |  | +                  }}
 | 
	
		
			
				|  |  | +                </GridItem>
 | 
	
		
			
				|  |  | +                <GridItem text="拨打电话" onClick={hanldeCallPhone}>
 | 
	
		
			
				|  |  | +                  {{
 | 
	
		
			
				|  |  | +                    icon: () => (
 | 
	
		
			
				|  |  | +                      <Image class={styles.concatIcon} src={icon_phone} />
 | 
	
		
			
				|  |  | +                    )
 | 
	
		
			
				|  |  | +                  }}
 | 
	
		
			
				|  |  | +                </GridItem>
 | 
	
		
			
				|  |  | +              </Grid>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 设置班级 */}
 | 
	
		
			
				|  |  | +        <Popup v-model:show={detailData.gradeShow} position="bottom" round>
 | 
	
		
			
				|  |  | +          <Picker
 | 
	
		
			
				|  |  | +            visibleOptionNum={5}
 | 
	
		
			
				|  |  | +            columns={detailData.gradeOptions}
 | 
	
		
			
				|  |  | +            onCancel={() => (detailData.gradeShow = false)}
 | 
	
		
			
				|  |  | +            onConfirm={value => {
 | 
	
		
			
				|  |  | +              detailData.gradeShow = false;
 | 
	
		
			
				|  |  | +              handleSetGrade(value.selectedOptions);
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 选择退团列表 */}
 | 
	
		
			
				|  |  | +        <Popup
 | 
	
		
			
				|  |  | +          v-model:show={detailData.quitShow}
 | 
	
		
			
				|  |  | +          class={['popup-custom', 'van-scale']}
 | 
	
		
			
				|  |  | +          transition="van-scale">
 | 
	
		
			
				|  |  | +          <div class={styles.quitBox}>
 | 
	
		
			
				|  |  | +            <div class={styles.quitTitle}>选择乐团</div>
 | 
	
		
			
				|  |  | +            <div class={styles.quitDes}>请选择要退出的乐团:</div>
 | 
	
		
			
				|  |  | +            <CheckboxGroup
 | 
	
		
			
				|  |  | +              v-model:modelValue={detailData.quitList}
 | 
	
		
			
				|  |  | +              class={styles.optionBox}>
 | 
	
		
			
				|  |  | +              <CellGroup border={false}>
 | 
	
		
			
				|  |  | +                {detailData.musicGroup.map(
 | 
	
		
			
				|  |  | +                  (group: IMusicGroup, index: number) => {
 | 
	
		
			
				|  |  | +                    return (
 | 
	
		
			
				|  |  | +                      <Cell
 | 
	
		
			
				|  |  | +                        class={[
 | 
	
		
			
				|  |  | +                          detailData.quitList.includes(group.value) &&
 | 
	
		
			
				|  |  | +                            styles.cellActive
 | 
	
		
			
				|  |  | +                        ]}
 | 
	
		
			
				|  |  | +                        title={group.text}
 | 
	
		
			
				|  |  | +                        center
 | 
	
		
			
				|  |  | +                        border={false}
 | 
	
		
			
				|  |  | +                        onClick={() => {
 | 
	
		
			
				|  |  | +                          checkboxRefs.value[index]?.toggle();
 | 
	
		
			
				|  |  | +                        }}>
 | 
	
		
			
				|  |  | +                        {{
 | 
	
		
			
				|  |  | +                          value: () => (
 | 
	
		
			
				|  |  | +                            <Checkbox
 | 
	
		
			
				|  |  | +                              ref={el => (checkboxRefs.value[index] = el)}
 | 
	
		
			
				|  |  | +                              shape="square"
 | 
	
		
			
				|  |  | +                              name={group.value}
 | 
	
		
			
				|  |  | +                              onClick={(e: Event) =>
 | 
	
		
			
				|  |  | +                                e.stopPropagation()
 | 
	
		
			
				|  |  | +                              }></Checkbox>
 | 
	
		
			
				|  |  | +                          )
 | 
	
		
			
				|  |  | +                        }}
 | 
	
		
			
				|  |  | +                      </Cell>
 | 
	
		
			
				|  |  | +                    );
 | 
	
		
			
				|  |  | +                  }
 | 
	
		
			
				|  |  | +                )}
 | 
	
		
			
				|  |  | +              </CellGroup>
 | 
	
		
			
				|  |  | +            </CheckboxGroup>
 | 
	
		
			
				|  |  | +            <div class={['btnGroupPopup']}>
 | 
	
		
			
				|  |  | +              <Button round onClick={() => (detailData.quitShow = false)}>
 | 
	
		
			
				|  |  | +                取消
 | 
	
		
			
				|  |  | +              </Button>
 | 
	
		
			
				|  |  | +              <Button
 | 
	
		
			
				|  |  | +                type="primary"
 | 
	
		
			
				|  |  | +                round
 | 
	
		
			
				|  |  | +                disabled={!detailData.quitList.length}
 | 
	
		
			
				|  |  | +                onClick={() => {
 | 
	
		
			
				|  |  | +                  // detailData.quitShow = false
 | 
	
		
			
				|  |  | +                  detailData.quitConfirmShow = true;
 | 
	
		
			
				|  |  | +                }}>
 | 
	
		
			
				|  |  | +                下一步
 | 
	
		
			
				|  |  | +              </Button>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 确定退团 */}
 | 
	
		
			
				|  |  | +        <Popup
 | 
	
		
			
				|  |  | +          v-model:show={detailData.quitConfirmShow}
 | 
	
		
			
				|  |  | +          class={['popup-custom', 'van-scale']}
 | 
	
		
			
				|  |  | +          transition="van-scale">
 | 
	
		
			
				|  |  | +          <div class={styles.quitBox}>
 | 
	
		
			
				|  |  | +            <div class={styles.quitTitle}>学员退团</div>
 | 
	
		
			
				|  |  | +            <div class={styles.quitDes}>
 | 
	
		
			
				|  |  | +              确认要将学员
 | 
	
		
			
				|  |  | +              <span style={{ color: '#FF5A56' }}>{quitName.value}</span>
 | 
	
		
			
				|  |  | +              中退团吗?
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div style={{ color: '#333' }} class={styles.quitLabel}>
 | 
	
		
			
				|  |  | +              <span style={{ color: '#FF5A56' }}>*</span>退团原因:
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class={styles.quitLabel}>
 | 
	
		
			
				|  |  | +              <Field
 | 
	
		
			
				|  |  | +                style={{ padding: 0 }}
 | 
	
		
			
				|  |  | +                v-model={detailData.reason}
 | 
	
		
			
				|  |  | +                type="textarea"
 | 
	
		
			
				|  |  | +                rows={3}
 | 
	
		
			
				|  |  | +                required
 | 
	
		
			
				|  |  | +                placeholder="请填写退团原因"></Field>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <div class={styles.quitLabel}>
 | 
	
		
			
				|  |  | +              确认后,我们将在7个工作日内与学生联系退费事宜
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <div class={['btnGroupPopup']}>
 | 
	
		
			
				|  |  | +              <Button
 | 
	
		
			
				|  |  | +                round
 | 
	
		
			
				|  |  | +                onClick={() => (detailData.quitConfirmShow = false)}>
 | 
	
		
			
				|  |  | +                取消
 | 
	
		
			
				|  |  | +              </Button>
 | 
	
		
			
				|  |  | +              <Button
 | 
	
		
			
				|  |  | +                loading={detailData.quitLoading}
 | 
	
		
			
				|  |  | +                type="primary"
 | 
	
		
			
				|  |  | +                round
 | 
	
		
			
				|  |  | +                onClick={() => handleQuite()}>
 | 
	
		
			
				|  |  | +                确定
 | 
	
		
			
				|  |  | +              </Button>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 |