|
@@ -1,121 +1,270 @@
|
|
|
import OHeader from '@/components/o-header'
|
|
|
import OSearch from '@/components/o-search'
|
|
|
-import { Cell, Icon, Popover, Image, Checkbox, CheckboxGroup, Button } from 'vant'
|
|
|
-import { defineComponent, reactive } from 'vue'
|
|
|
+import {
|
|
|
+ Cell,
|
|
|
+ Icon,
|
|
|
+ Popover,
|
|
|
+ Image,
|
|
|
+ Checkbox,
|
|
|
+ CheckboxGroup,
|
|
|
+ Button,
|
|
|
+ Popup,
|
|
|
+ Picker,
|
|
|
+ List
|
|
|
+} from 'vant'
|
|
|
+import { defineComponent, onMounted, reactive, watch } from 'vue'
|
|
|
import styles from './student-list.module.less'
|
|
|
import checkboxCheck from '@/common/images/icon-checkbox-check.png'
|
|
|
import checkboxDefault from '@/common/images/icon-checkbox-default.png'
|
|
|
+import iconStudent from '@/common/images/icon_student.png'
|
|
|
import OSticky from '@/components/o-sticky'
|
|
|
+import { state as baseState } from '@/state'
|
|
|
+import request from '@/helpers/request'
|
|
|
+import OEmpty from '@/components/o-empty'
|
|
|
+
|
|
|
+export const classStr = {
|
|
|
+ 1: '一年级',
|
|
|
+ 2: '二年级',
|
|
|
+ 3: '三年级',
|
|
|
+ 4: '四年级',
|
|
|
+ 5: '五年级',
|
|
|
+ 6: '六年级'
|
|
|
+}
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: 'student-list',
|
|
|
- emits: ['close'],
|
|
|
+ props: {
|
|
|
+ orchestraList: {
|
|
|
+ // 乐团列表
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ subjectId: {
|
|
|
+ // 声部编号
|
|
|
+ type: [String, Number],
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ selectStudentIds: {
|
|
|
+ // 选中的学生列表
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emits: ['close', 'select'],
|
|
|
setup(props, { slots, attrs, emit }) {
|
|
|
const state = reactive({
|
|
|
showPopover: false,
|
|
|
- actions: [
|
|
|
- { text: '全部乐团', color: 'var(--van-primary-color)' },
|
|
|
- { text: '交付团' },
|
|
|
- { text: '晋升团' }
|
|
|
- ],
|
|
|
oPopover: false,
|
|
|
- check: [],
|
|
|
- checkboxRefs: [] as any
|
|
|
+ isLoad: false,
|
|
|
+ classList: [
|
|
|
+ { text: '一年级', value: 1 },
|
|
|
+ { text: '二年级', value: 2 },
|
|
|
+ { text: '三年级', value: 3 },
|
|
|
+ { text: '四年级', value: 4 },
|
|
|
+ { text: '五年级', value: 5 }
|
|
|
+ ] as any, // 年级列表
|
|
|
+ check: [] as any,
|
|
|
+ checkboxRefs: [] as any,
|
|
|
+ orchestra: {
|
|
|
+ id: null,
|
|
|
+ name: '全部乐团'
|
|
|
+ } as any,
|
|
|
+ class: {
|
|
|
+ id: null,
|
|
|
+ name: '年级'
|
|
|
+ } as any,
|
|
|
+ list: [] as any,
|
|
|
+ listState: {
|
|
|
+ dataShow: true, // 判断是否有数据
|
|
|
+ loading: false,
|
|
|
+ finished: false
|
|
|
+ },
|
|
|
+ params: {
|
|
|
+ keyword: null,
|
|
|
+ page: 1,
|
|
|
+ rows: 20
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
const onSelect = (type: string) => {
|
|
|
- console.log(type, 'tye')
|
|
|
- console.log(state.checkboxRefs[type])
|
|
|
+ // console.log(state.checkboxRefs[type])
|
|
|
state.checkboxRefs[type].toggle()
|
|
|
}
|
|
|
|
|
|
+ const getList = async () => {
|
|
|
+ try {
|
|
|
+ if (state.isLoad) return
|
|
|
+ state.isLoad = true
|
|
|
+ const res = await request.post('/api-school/student/page', {
|
|
|
+ data: {
|
|
|
+ ...state.params,
|
|
|
+ subjectId: props.subjectId,
|
|
|
+ orchestraId: state.orchestra.id,
|
|
|
+ classId: state.class.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.listState.loading = false
|
|
|
+ const result = res.data || {}
|
|
|
+ // 处理重复请求数据
|
|
|
+ if (state.list.length > 0 && result.current === 1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ state.list = state.list.concat(result.rows || [])
|
|
|
+ state.listState.finished = result.current >= result.pages
|
|
|
+ state.params.page = result.current + 1
|
|
|
+ state.listState.dataShow = state.list.length > 0
|
|
|
+
|
|
|
+ state.isLoad = false
|
|
|
+ } catch {
|
|
|
+ state.listState.dataShow = false
|
|
|
+ state.listState.finished = true
|
|
|
+ state.isLoad = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索
|
|
|
+ const onSearch = () => {
|
|
|
+ state.params.page = 1
|
|
|
+ state.list = []
|
|
|
+ state.listState.dataShow = true // 判断是否有数据
|
|
|
+ state.listState.loading = false
|
|
|
+ state.listState.finished = false
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+
|
|
|
const onSubmit = () => {
|
|
|
emit('close')
|
|
|
+ emit('select', state.check)
|
|
|
+ setTimeout(() => {
|
|
|
+ state.check = []
|
|
|
+ }, 100)
|
|
|
}
|
|
|
|
|
|
+ // 监听声部是否变化
|
|
|
+ watch(
|
|
|
+ () => props.subjectId,
|
|
|
+ () => {
|
|
|
+ onSearch()
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ // 监听选择学生变化
|
|
|
+ watch(
|
|
|
+ () => props.selectStudentIds,
|
|
|
+ () => {
|
|
|
+ state.check = [...props.selectStudentIds]
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ // 判断年级
|
|
|
+ if (baseState.user.data.school.schoolSystem === 'sixYearSystem') {
|
|
|
+ state.classList.push({ text: '六年级', value: 6 })
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.orchestraList.length > 0) {
|
|
|
+ const o: any = props.orchestraList[0]
|
|
|
+ state.orchestra.id = o.value
|
|
|
+ state.orchestra.name = o.text
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取学生列表
|
|
|
+ getList()
|
|
|
+
|
|
|
+ state.check = [...props.selectStudentIds]
|
|
|
+ })
|
|
|
+
|
|
|
return () => (
|
|
|
<div class={styles.studentList}>
|
|
|
<OSticky position="top">
|
|
|
<OHeader title="选择学生" />
|
|
|
- <OSearch inputBackground="white" background="#F8F8F8" />
|
|
|
+ <OSearch
|
|
|
+ inputBackground="white"
|
|
|
+ background="#F8F8F8"
|
|
|
+ placeholder="学生名称/手机号"
|
|
|
+ onSearch={(val: any) => {
|
|
|
+ state.params.keyword = val
|
|
|
+ onSearch()
|
|
|
+ }}
|
|
|
+ />
|
|
|
<div style={{ padding: '8px 13px 16px', background: '#F8F8F8' }}>
|
|
|
- <Popover
|
|
|
- v-model:show={state.showPopover}
|
|
|
- actions={state.actions}
|
|
|
- showArrow={false}
|
|
|
- placement="bottom-start"
|
|
|
- offset={[0, 12]}
|
|
|
- style={{ zIndex: '9999' }}
|
|
|
+ <div class={styles.searchBand} onClick={() => (state.showPopover = true)}>
|
|
|
+ {state.class.name} <Icon name={state.showPopover ? 'arrow-up' : 'arrow-down'} />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={styles.searchBand}
|
|
|
+ style="margin-left: 16px"
|
|
|
+ onClick={() => (state.oPopover = true)}
|
|
|
>
|
|
|
- {{
|
|
|
- reference: () => (
|
|
|
- <div class={styles.searchBand}>
|
|
|
- 全部乐团 <Icon name={state.showPopover ? 'arrow-up' : 'arrow-down'} />
|
|
|
- </div>
|
|
|
- )
|
|
|
- }}
|
|
|
- </Popover>
|
|
|
- <Popover
|
|
|
- v-model:show={state.oPopover}
|
|
|
- actions={state.actions}
|
|
|
- showArrow={false}
|
|
|
- placement="bottom"
|
|
|
- offset={[0, 12]}
|
|
|
- style={{ zIndex: '9999' }}
|
|
|
- >
|
|
|
- {{
|
|
|
- reference: () => (
|
|
|
- <div class={styles.searchBand} style="margin-left: 16px">
|
|
|
- 武汉小学2022预备团 <Icon name={state.oPopover ? 'arrow-up' : 'arrow-down'} />
|
|
|
- </div>
|
|
|
- )
|
|
|
- }}
|
|
|
- </Popover>
|
|
|
+ {state.orchestra.name} <Icon name={state.oPopover ? 'arrow-up' : 'arrow-down'} />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</OSticky>
|
|
|
|
|
|
- <CheckboxGroup v-model={state.check}>
|
|
|
- {[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6].map((value: any) => (
|
|
|
- <Cell v-model={state.check} center onClick={() => onSelect(value)}>
|
|
|
- {{
|
|
|
- icon: () => (
|
|
|
- <Image
|
|
|
- class={styles.img}
|
|
|
- src="https://daya.ks3-cn-beijing.ksyuncs.com/12/1670231208704.png"
|
|
|
- />
|
|
|
- ),
|
|
|
- title: () => (
|
|
|
- <div class={styles.content}>
|
|
|
- <p class={styles.name}>长毛</p>
|
|
|
- <p class={styles.class}>三年级</p>
|
|
|
- </div>
|
|
|
- ),
|
|
|
- 'right-icon': () => (
|
|
|
- <Checkbox
|
|
|
- name={value}
|
|
|
- ref={(el: any) => (state.checkboxRefs[value] = el)}
|
|
|
- onClick={(e: any) => {
|
|
|
- e.stopPropagation()
|
|
|
- e.preventDefault()
|
|
|
- }}
|
|
|
- v-slots={{
|
|
|
- icon: (props: any) => (
|
|
|
- <Icon
|
|
|
- class={styles.iconChecked}
|
|
|
- name={props.checked ? checkboxCheck : checkboxDefault}
|
|
|
- />
|
|
|
- )
|
|
|
- }}
|
|
|
- />
|
|
|
- )
|
|
|
- }}
|
|
|
- </Cell>
|
|
|
- ))}
|
|
|
- </CheckboxGroup>
|
|
|
+ {state.listState.dataShow ? (
|
|
|
+ <List
|
|
|
+ v-model:loading={state.listState.loading}
|
|
|
+ finished={state.listState.finished}
|
|
|
+ finishedText=" "
|
|
|
+ class={[styles.liveList]}
|
|
|
+ onLoad={getList}
|
|
|
+ immediateCheck={false}
|
|
|
+ >
|
|
|
+ <CheckboxGroup v-model={state.check}>
|
|
|
+ {state.list.map((item: any) => (
|
|
|
+ <Cell v-model={state.check} center onClick={() => onSelect(item.id)}>
|
|
|
+ {{
|
|
|
+ icon: () => <Image class={styles.img} src={item.avatar || iconStudent} />,
|
|
|
+ title: () => (
|
|
|
+ <div class={styles.content}>
|
|
|
+ <p class={styles.name}>{item.nickname}</p>
|
|
|
+ <p class={styles.class}>
|
|
|
+ {item.currentGradeNum > 0 ? classStr[item.currentGradeNum] : ''}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ 'right-icon': () => (
|
|
|
+ <Checkbox
|
|
|
+ name={item.id}
|
|
|
+ ref={(el: any) => (state.checkboxRefs[item.id] = el)}
|
|
|
+ onClick={(e: any) => {
|
|
|
+ e.stopPropagation()
|
|
|
+ e.preventDefault()
|
|
|
+ }}
|
|
|
+ v-slots={{
|
|
|
+ icon: (props: any) => (
|
|
|
+ <Icon
|
|
|
+ class={styles.iconChecked}
|
|
|
+ name={props.checked ? checkboxCheck : checkboxDefault}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Cell>
|
|
|
+ ))}
|
|
|
+ </CheckboxGroup>
|
|
|
+ </List>
|
|
|
+ ) : (
|
|
|
+ <OEmpty btnStatus={false} classImgSize="SMALL" tips="暂无学生" />
|
|
|
+ )}
|
|
|
|
|
|
<OSticky position="bottom">
|
|
|
<div class={['btnGroup', styles.btnMore]}>
|
|
|
- <Button type="primary" plain round>
|
|
|
+ <Button
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ round
|
|
|
+ onClick={() => {
|
|
|
+ state.list.forEach((item: any) => {
|
|
|
+ if (!state.check.includes(item.id)) {
|
|
|
+ state.check.push(item.id)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.check
|
|
|
+ }}
|
|
|
+ >
|
|
|
全选
|
|
|
</Button>
|
|
|
<Button type="primary" round block onClick={onSubmit}>
|
|
@@ -123,6 +272,38 @@ export default defineComponent({
|
|
|
</Button>
|
|
|
</div>
|
|
|
</OSticky>
|
|
|
+
|
|
|
+ {/* 乐团 */}
|
|
|
+ <Popup v-model:show={state.oPopover} position="bottom" round>
|
|
|
+ <Picker
|
|
|
+ columns={props.orchestraList as any}
|
|
|
+ onCancel={() => (state.oPopover = false)}
|
|
|
+ onConfirm={(item: any) => {
|
|
|
+ const selectedOptions = item.selectedOptions[0]
|
|
|
+ state.orchestra.id = selectedOptions.value
|
|
|
+ state.orchestra.name = selectedOptions.text
|
|
|
+
|
|
|
+ state.oPopover = false
|
|
|
+ onSearch()
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Popup>
|
|
|
+
|
|
|
+ {/* 年级 */}
|
|
|
+ <Popup v-model:show={state.showPopover} position="bottom" round>
|
|
|
+ <Picker
|
|
|
+ columns={state.classList as any}
|
|
|
+ onCancel={() => (state.showPopover = false)}
|
|
|
+ onConfirm={(item: any) => {
|
|
|
+ const selectedOptions = item.selectedOptions[0]
|
|
|
+ state.class.id = selectedOptions.value
|
|
|
+ state.class.name = selectedOptions.text
|
|
|
+
|
|
|
+ state.showPopover = false
|
|
|
+ onSearch()
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Popup>
|
|
|
</div>
|
|
|
)
|
|
|
}
|