|
@@ -0,0 +1,311 @@
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ Checkbox,
|
|
|
+ CheckboxGroup,
|
|
|
+ Icon,
|
|
|
+ Image,
|
|
|
+ Loading,
|
|
|
+ Radio,
|
|
|
+ RadioGroup,
|
|
|
+ Sticky,
|
|
|
+ Toast
|
|
|
+} from 'vant'
|
|
|
+import { defineComponent, PropType } from 'vue'
|
|
|
+import styles from './index.module.less'
|
|
|
+
|
|
|
+import checkBoxActive from '@/teacher/teacher-cert/images/checkbox_active.png'
|
|
|
+import checkBoxDefault from '@/teacher/teacher-cert/images/checkbox_default.png'
|
|
|
+import ColResult from '@/components/col-result'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'SubjectList',
|
|
|
+ props: {
|
|
|
+ onChoice: {
|
|
|
+ type: Function,
|
|
|
+ default: (item: any) => {}
|
|
|
+ },
|
|
|
+ choiceSubjectIds: {
|
|
|
+ type: Array,
|
|
|
+ default: []
|
|
|
+ },
|
|
|
+ subjectList: {
|
|
|
+ type: Array,
|
|
|
+ default: []
|
|
|
+ },
|
|
|
+ max: {
|
|
|
+ // 最多可选数量
|
|
|
+ type: Number,
|
|
|
+ default: 5
|
|
|
+ },
|
|
|
+ selectType: {
|
|
|
+ // 选择类型,Radio:单选,Checkbox:多选
|
|
|
+ type: String as PropType<'Checkbox' | 'Radio'>,
|
|
|
+ default: 'Checkbox'
|
|
|
+ },
|
|
|
+ single: {
|
|
|
+ // 单选模式
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ checkBox: [],
|
|
|
+ checkboxRefs: [] as any,
|
|
|
+ radio: null as any // 单选
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ this.checkBox = this.choiceSubjectIds as never[]
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ choiceSubjectIds(val: any, oldVal) {
|
|
|
+ // 同步更新显示数据
|
|
|
+ this.checkBox = [...val] as never[]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onSelect(id: number) {
|
|
|
+ if (this.selectType === 'Checkbox') {
|
|
|
+ if (
|
|
|
+ this.max === this.checkBox.length &&
|
|
|
+ !this.checkBox.includes(id as never)
|
|
|
+ ) {
|
|
|
+ Toast(`乐器最多选择${this.max}个`)
|
|
|
+ }
|
|
|
+ this.checkboxRefs[id].toggle()
|
|
|
+ } else if (this.selectType === 'Radio') {
|
|
|
+ this.radio = id
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <div class={styles.subjects}>
|
|
|
+ <div class={styles.subjectContainer}>
|
|
|
+ {this.subjectList.length ? (
|
|
|
+ this.selectType === 'Checkbox' ? (
|
|
|
+ <CheckboxGroup v-model={this.checkBox} max={this.max}>
|
|
|
+ {!this.single &&
|
|
|
+ this.subjectList.map((item: any) =>
|
|
|
+ item.subjects && item.subjects.length > 0 ? (
|
|
|
+ <>
|
|
|
+ <div class={styles.title}>{item.name}</div>
|
|
|
+ <div class={styles['subject-list']}>
|
|
|
+ {item.subjects &&
|
|
|
+ item.subjects.map((sub: any) => (
|
|
|
+ <div
|
|
|
+ class={styles['subject-item']}
|
|
|
+ onClick={() => this.onSelect(sub.id)}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src={sub.img || 'xxx'}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ v-slots={{
|
|
|
+ loading: () => (
|
|
|
+ <Loading type="spinner" size={20} />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={styles.topBg}>
|
|
|
+ <Checkbox
|
|
|
+ name={sub.id}
|
|
|
+ class={styles.checkbox}
|
|
|
+ disabled
|
|
|
+ ref={(el: any) =>
|
|
|
+ (this.checkboxRefs[sub.id] = el)
|
|
|
+ }
|
|
|
+ v-slots={{
|
|
|
+ icon: (props: any) => (
|
|
|
+ <Icon
|
|
|
+ name={
|
|
|
+ props.checked
|
|
|
+ ? checkBoxActive
|
|
|
+ : checkBoxDefault
|
|
|
+ }
|
|
|
+ size="20"
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <p class={styles.name}>{sub.name}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ ) : null
|
|
|
+ )}
|
|
|
+ {this.single ? (
|
|
|
+ <div class={styles['subject-list']}>
|
|
|
+ {this.subjectList.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={styles['subject-item']}
|
|
|
+ onClick={() => this.onSelect(item.id)}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src={item.img || 'xxx'}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ v-slots={{
|
|
|
+ loading: () => <Loading type="spinner" size={20} />
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={styles.topBg}>
|
|
|
+ <Checkbox
|
|
|
+ name={item.id}
|
|
|
+ class={styles.checkbox}
|
|
|
+ disabled
|
|
|
+ ref={(el: any) => (this.checkboxRefs[item.id] = el)}
|
|
|
+ v-slots={{
|
|
|
+ icon: (props: any) => (
|
|
|
+ <Icon
|
|
|
+ name={
|
|
|
+ props.checked
|
|
|
+ ? checkBoxActive
|
|
|
+ : checkBoxDefault
|
|
|
+ }
|
|
|
+ size="20"
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <p class={styles.name}>{item.name}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ </CheckboxGroup>
|
|
|
+ ) : (
|
|
|
+ <RadioGroup v-model={this.radio}>
|
|
|
+ {!this.single &&
|
|
|
+ this.subjectList.map((item: any) =>
|
|
|
+ item.subjects && item.subjects.length > 0 ? (
|
|
|
+ <>
|
|
|
+ <div class={styles.title}>{item.name}</div>
|
|
|
+ <div class={styles['subject-list']}>
|
|
|
+ {item.subjects &&
|
|
|
+ item.subjects.map((sub: any) => (
|
|
|
+ <div
|
|
|
+ class={styles['subject-item']}
|
|
|
+ onClick={() => this.onSelect(sub.id)}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src={sub.img || 'xxx'}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ v-slots={{
|
|
|
+ loading: () => (
|
|
|
+ <Loading type="spinner" size={20} />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={styles.topBg}>
|
|
|
+ <Radio
|
|
|
+ name={sub.id}
|
|
|
+ class={styles.checkbox}
|
|
|
+ v-slots={{
|
|
|
+ icon: (props: any) => (
|
|
|
+ <Icon
|
|
|
+ name={
|
|
|
+ props.checked
|
|
|
+ ? checkBoxActive
|
|
|
+ : checkBoxDefault
|
|
|
+ }
|
|
|
+ size="20"
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <p class={styles.name}>{sub.name}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ ) : null
|
|
|
+ )}
|
|
|
+ {this.single ? (
|
|
|
+ <div class={styles['subject-list']}>
|
|
|
+ {this.subjectList.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={styles['subject-item']}
|
|
|
+ onClick={() => this.onSelect(item.id)}
|
|
|
+ >
|
|
|
+ <Image
|
|
|
+ src={item.img || 'xxx'}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ v-slots={{
|
|
|
+ loading: () => <Loading type="spinner" size={20} />
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div class={styles.topBg}>
|
|
|
+ <Radio
|
|
|
+ name={item.id}
|
|
|
+ class={styles.checkbox}
|
|
|
+ v-slots={{
|
|
|
+ icon: (props: any) => (
|
|
|
+ <Icon
|
|
|
+ name={
|
|
|
+ props.checked
|
|
|
+ ? checkBoxActive
|
|
|
+ : checkBoxDefault
|
|
|
+ }
|
|
|
+ size="20"
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <p class={styles.name}>{item.name}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ </RadioGroup>
|
|
|
+ )
|
|
|
+ ) : (
|
|
|
+ <ColResult tips="暂无声部数据" btnStatus={false} />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {this.subjectList.length > 0 && (
|
|
|
+ <Sticky offsetBottom={0} position="bottom">
|
|
|
+ <div class={['btnGroup', styles.btns]}>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ block
|
|
|
+ onClick={() => {
|
|
|
+ this.checkBox = []
|
|
|
+ this.radio = ''
|
|
|
+ this.onChoice()
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ 重置
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ block
|
|
|
+ type="primary"
|
|
|
+ onClick={() =>
|
|
|
+ this.onChoice(
|
|
|
+ this.selectType === 'Checkbox' ? this.checkBox : this.radio
|
|
|
+ )
|
|
|
+ }
|
|
|
+ >
|
|
|
+ 确定
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </Sticky>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|