|  | @@ -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>
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +})
 |