| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 | import { computed, defineComponent, onMounted, reactive } from 'vue';import styles from './index.module.less';import {  NAvatar,  NButton,  NCascader,  NCheckbox,  NCheckboxGroup,  NInput,  NScrollbar,  NSelect,  NSpace,  NSpin} from 'naive-ui';import defultHeade from '@/components/layout/images/teacherIcon.png';import SearchInput from '/src/components/searchInput';import { useCatchStore } from '/src/store/modules/catchData';import { getStudentList } from '/src/views/classList/api';import { useThrottleFn } from '@vueuse/core';import TheEmpty from '/src/components/TheEmpty';import { getGradeYearList } from '/src/views/home/api';import { api_getCurrentGradeYear } from '/src/views/studentList/api';export default defineComponent({  name: 'assign-student',  props: {    /** 班级列表 */    classList: {      type: Array,      default: () => []    },    /** 所选学生列表 */    studentList: {      type: Array,      default: () => []    },    /** 学年 */    currentGradeNum: {      type: [String || Number],      default: ''    },    selectIds: {      type: Array,      default: () => []    },    classGroupId: {      type: String,      default: ''    }  },  emits: ['close', 'confirm'],  setup(props, { emit }) {    const catchStore = useCatchStore();    const state = reactive({      studentName: '',      loading: false,      finshed: false, // 是否加载完      checkAllStatus: false,      indeterminate: false,      searchFrom: {        upgradeFlag: true,        currentGradeNums: null as any,        gradeYear: null,        classGroupId: props.classGroupId || '',        classInstrumentId: '',        keyword: ''      },      pagination: {        page: 1,        rows: 20,        pageTotal: 0      },      tableList: [] as any,      checkboxIds: [] as any,      selectStudents: [] as any,      selectKeyword: '',      popSelectYearList: [] as any    });    // 获取学年    const getYearList = async () => {      try {        const { data } = await api_getCurrentGradeYear({});        state.searchFrom.gradeYear = data;      } catch {        //      }    };    const getStudentLists = async () => {      try {        if (state.pagination.page === 1) {          state.loading = true;          state.tableList = [];        }        const { data } = await getStudentList({          ...state.searchFrom,          ...state.pagination        });        state.loading = false;        const rows = data.rows || [];        state.tableList.push(...rows);        state.finshed = data.pages <= data.current ? true : false;        onCheckStudents();      } catch {        //        state.loading = false;      }    };    const onSearch = () => {      state.pagination.page = 1;      getStudentLists();    };    const selectStudentEmpty = computed(() => {      let status = true;      state.selectStudents.forEach((item: any) => {        if (!item.hide) {          status = false;        }      });      return status;    });    const throttledFn = useThrottleFn(() => {      state.pagination.page = state.pagination.page + 1;      getStudentLists();    }, 500);    // 切换学生状态    const onCheckStudents = () => {      if (state.tableList.length <= 0) {        state.indeterminate = false;        state.checkAllStatus = false;        return;      }      // 右边数据      state.tableList.forEach((item: any) => {        if (state.checkboxIds.includes(item.id)) {          const index = state.selectStudents.findIndex(            (select: any) => select.id == item.id          );          if (index === -1) state.selectStudents.push(item);        } else {          const index = state.selectStudents.findIndex(            (select: any) => select.id == item.id          );          if(index >= 0) state.selectStudents.splice(index, 1)        }      });      let count = 0;      state.tableList.forEach((item: any) => {        const index = state.selectStudents.findIndex(          (select: any) => select.id === item.id        );        if(index >= 0) count++      })      if (count >= state.tableList.length) {        state.checkAllStatus = true;        state.indeterminate = false;      } else {        state.checkAllStatus = false;        state.indeterminate = count === 0 ? false : true;      }    };    // 删除用户    const onRemove = (item: any) => {      const index = state.checkboxIds.findIndex((id: any) => id == item.id);      if (index !== -1) {        state.checkboxIds.splice(index, 1);        const sIndex = state.selectStudents.findIndex(          (select: any) => select.id === item.id        );        if (sIndex !== -1) {          state.selectStudents.splice(sIndex, 1);        }        onCheckStudents();      }    };    const onSave = () => {      const studentInfo: any[] = [];      state.selectStudents.forEach((item: any) => {        studentInfo.push({          id: item.id,          name: item.nickname,          avatar: item.avatar        });      });      emit('confirm', studentInfo);    };    onMounted(async () => {      console.log(props.currentGradeNum, 'props.currentGradeNum-----')      if(Array.isArray(props.currentGradeNum)) {        state.searchFrom.currentGradeNums = props.currentGradeNum.join(',')      } else {        state.searchFrom.currentGradeNums = props.currentGradeNum      }      state.checkboxIds = props.selectIds || [];      state.loading = true;      await catchStore.getSubjects();      await getYearList();      await getStudentLists();      // onCheckStudents();      // 重置选择的学生      state.selectStudents = props.studentList?.map((item: any) => {        return {          ...item,          nickname: item.name        };      });    });    return () => (      <div class={[styles.assignStudent, 'assignStudent']}>        <div class={styles.studentListGroup}>          <div class={styles.searchSection}>            <div class={styles.searchSpace}>              <NSelect                placeholder="全部班级"                disabled={props.classGroupId ? true : false}                labelField="defaultLabel"                filterable                clearable                v-model:value={state.searchFrom.classGroupId}                onUpdate:value={() => onSearch()}                options={                  [{ defaultLabel: '全部班级', value: '' }, ...props.classList] as any                }              />              <NCascader                options={[                  { name: '全部乐器', id: '' },                  ...catchStore.getSubjectList                ]}                placeholder="全部乐器"                v-model:value={state.searchFrom.classInstrumentId}                onUpdate:value={() => onSearch()}                checkStrategy="child"                showPath={false}                childrenField="instruments"                expandTrigger="hover"                labelField="name"                valueField="id"                clearable                filterable              />            </div>            <SearchInput              {...{ placeholder: '请输入学生姓名/手机号' }}              class={styles.searchInput}              searchWord={state.searchFrom.keyword}              onChangeValue={(val: string) => {                state.searchFrom.keyword = val;              }}              onClear={() => {                state.searchFrom.keyword = '';                onSearch();              }}              onKeyup={(e: KeyboardEvent) => {                if (e.code === 'Enter') {                  onSearch();                }              }}></SearchInput>          </div>          <div class={styles.studentSection}>            <div class={styles.checkboxAll}>              <NCheckbox                v-model:checked={state.checkAllStatus}                indeterminate={state.indeterminate}                onUpdate:checked={(val: any) => {                  if (val) {                    const ids: any = [];                    state.tableList.forEach((item: any) => {                      ids.push(item.id);                    });                    ids.forEach((id: any) => {                      if(!state.checkboxIds.includes(id)) {                        state.checkboxIds.push(id)                      }                    })                  } else {                    const removeIds = state.tableList.map((item: any) => item.id)                    console.log(removeIds, 'removeIds', state.checkboxIds)                    removeIds.forEach((rid: any) => {                      const index = state.checkboxIds.findIndex((id: any) => id == rid);                      if(index !== -1) state.checkboxIds.splice(index, 1);                      const sindex = state.selectStudents.findIndex(                        (select: any) => select.id == rid                      );                      if(sindex !== -1) state.selectStudents.splice(sindex, 1)                     })                    state.indeterminate = false;                  }                  onCheckStudents();                }}></NCheckbox>              <p>                全选 <span class={styles.nums}>({state.tableList.length})</span>{' '}                :              </p>            </div>          </div>          <NScrollbar            class={styles.student}            onScroll={(e: any) => {              const clientHeight = e.target?.clientHeight;              const scrollTop = e.target?.scrollTop;              const scrollHeight = e.target?.scrollHeight;              // 是否到底,是否加载完              if (                clientHeight + scrollTop + 20 >= scrollHeight &&                !state.finshed &&                !state.loading              ) {                throttledFn();              }            }}>            <NSpin show={state.loading} class={styles.loadingSection}>              <NCheckboxGroup                v-model:value={state.checkboxIds}                onUpdate:value={() => {                  // state.selectStudents = [];                  onCheckStudents();                }}>                {state.tableList.map((item: any) => (                  <NCheckbox value={item.id} class={[styles.studentItem]}>                    <div class={styles.studentInfo}>                      <NAvatar                        src={item.avatar || defultHeade}                        class={styles.studentImg}                      />                      <div class={styles.studentValue}>                        <div class={styles.userInfo}>                          <span class={styles.name}>{item.nickname}</span>                          {item.membership && <i class={styles.iconMember}></i>}                          {item.classGroupName && (                            <span class={styles.className}>                              {item.classGroupName}                            </span>                          )}                        </div>                        <div class={styles.phone}>{item.phone}</div>                      </div>                    </div>                  </NCheckbox>                ))}              </NCheckboxGroup>              {state.tableList.length <= 0 && !state.loading && <TheEmpty />}            </NSpin>          </NScrollbar>        </div>        <div class={styles.selectStudentGroup}>          <div class={styles.selectCount}>            当前选中 <span>({state.selectStudents.length}) </span>:          </div>          <div class={styles.searchSection}>            <SearchInput              {...{ placeholder: '请输入学生姓名' }}              class={styles.searchInput}              searchWord={state.selectKeyword}              onChangeValue={(val: string) => {                state.selectKeyword = val;                state.selectStudents.forEach((item: any) => {                  if (item.nickname?.indexOf(val) === -1) {                    item.hide = true;                  } else {                    item.hide = false;                  }                });              }}></SearchInput>          </div>          <NScrollbar class={styles.student}>            {state.selectStudents.map((student: any) => (              <div class={[styles.studentItem, student.hide && styles.hide]}>                <div class={styles.studentInfo}>                  <NAvatar                    src={student.avatar || defultHeade}                    class={styles.studentImg}                  />                  <span class={styles.name}>{student.nickname}</span>                </div>                <i                  class={styles.iconClose}                  onClick={() => onRemove(student)}></i>              </div>            ))}            {selectStudentEmpty.value && <TheEmpty />}          </NScrollbar>          <NSpace justify="end" class={styles.btnGroup}>            <NButton type="default" onClick={() => emit('close')}>              取消            </NButton>            <NButton type="primary" onClick={onSave}>              保存            </NButton>          </NSpace>        </div>      </div>    );  }});
 |