|  | @@ -0,0 +1,536 @@
 | 
	
		
			
				|  |  | +import { computed, defineComponent, onMounted, reactive } from 'vue'
 | 
	
		
			
				|  |  | +import styles from './add-unit-item.module.less'
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  Button,
 | 
	
		
			
				|  |  | +  Cell,
 | 
	
		
			
				|  |  | +  CellGroup,
 | 
	
		
			
				|  |  | +  Dialog,
 | 
	
		
			
				|  |  | +  Field,
 | 
	
		
			
				|  |  | +  Icon,
 | 
	
		
			
				|  |  | +  Popup,
 | 
	
		
			
				|  |  | +  Radio,
 | 
	
		
			
				|  |  | +  RadioGroup,
 | 
	
		
			
				|  |  | +  showToast
 | 
	
		
			
				|  |  | +} from 'vant'
 | 
	
		
			
				|  |  | +import iconDelete from '../image/icon-delete2.png'
 | 
	
		
			
				|  |  | +import iconMusic from '../image/icon-music.png'
 | 
	
		
			
				|  |  | +import iconRadioDefault from '../image/icon-radio-default.png'
 | 
	
		
			
				|  |  | +import iconReadioChecked from '../image/icon-radio-checked.png'
 | 
	
		
			
				|  |  | +import OHeader from '@/components/o-header'
 | 
	
		
			
				|  |  | +import OPopup from '@/components/o-popup'
 | 
	
		
			
				|  |  | +import MusicList from './music-list'
 | 
	
		
			
				|  |  | +import { difficultyCoefficients } from '.'
 | 
	
		
			
				|  |  | +import OActionSheet from '@/components/o-action-sheet'
 | 
	
		
			
				|  |  | +import requestOrigin from 'umi-request'
 | 
	
		
			
				|  |  | +import OSticky from '@/components/o-sticky'
 | 
	
		
			
				|  |  | +import { useRoute, useRouter } from 'vue-router'
 | 
	
		
			
				|  |  | +import { unitData } from './data'
 | 
	
		
			
				|  |  | +import request from '@/helpers/request'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'add-unit-item',
 | 
	
		
			
				|  |  | +  setup() {
 | 
	
		
			
				|  |  | +    const route = useRoute()
 | 
	
		
			
				|  |  | +    const router = useRouter()
 | 
	
		
			
				|  |  | +    const state = reactive({
 | 
	
		
			
				|  |  | +      musicStatus: false,
 | 
	
		
			
				|  |  | +      // selectMusic: {} as any,
 | 
	
		
			
				|  |  | +      level: route.query.level,
 | 
	
		
			
				|  |  | +      dialogShow: false,
 | 
	
		
			
				|  |  | +      activeIndex: 0, // 选择的索引
 | 
	
		
			
				|  |  | +      activeRow: {} as any,
 | 
	
		
			
				|  |  | +      musicLevelShow: false,
 | 
	
		
			
				|  |  | +      actions: [] as any,
 | 
	
		
			
				|  |  | +      partShow: false,
 | 
	
		
			
				|  |  | +      checkedPart: null as any, // 选择小节类型
 | 
	
		
			
				|  |  | +      startPart: null, // 开始小节
 | 
	
		
			
				|  |  | +      endPart: null // 结束小节
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const isEdit = computed(() => {
 | 
	
		
			
				|  |  | +      return route.query.musicId ? true : false
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    difficultyCoefficients.forEach((item: any) => {
 | 
	
		
			
				|  |  | +      state.actions.push({
 | 
	
		
			
				|  |  | +        name: item.label,
 | 
	
		
			
				|  |  | +        value: item.value
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 格式化难度数据
 | 
	
		
			
				|  |  | +    const filterDifficulty = (difficulty: string) => {
 | 
	
		
			
				|  |  | +      let str = ''
 | 
	
		
			
				|  |  | +      state.actions.forEach((action: any) => {
 | 
	
		
			
				|  |  | +        if (action.value === difficulty) {
 | 
	
		
			
				|  |  | +          str = action.name
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +      return str
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 格式化小节数
 | 
	
		
			
				|  |  | +    const filterPart = (item: any) => {
 | 
	
		
			
				|  |  | +      if (item.partStart && item.partEnd) {
 | 
	
		
			
				|  |  | +        return item.partStart + '-' + item.partEnd + '小节'
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        return ''
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const onSubmit = async () => {
 | 
	
		
			
				|  |  | +      let pass = true
 | 
	
		
			
				|  |  | +      for (let i = 0; i < forms.length; i++) {
 | 
	
		
			
				|  |  | +        if (!forms[i].musicId) {
 | 
	
		
			
				|  |  | +          pass = false
 | 
	
		
			
				|  |  | +          showToast('请选择曲目')
 | 
	
		
			
				|  |  | +          break
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (!forms[i].partName) {
 | 
	
		
			
				|  |  | +          pass = false
 | 
	
		
			
				|  |  | +          showToast('请选择小节')
 | 
	
		
			
				|  |  | +          break
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (!forms[i].difficulty) {
 | 
	
		
			
				|  |  | +          pass = false
 | 
	
		
			
				|  |  | +          showToast('请选择难度')
 | 
	
		
			
				|  |  | +          break
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (!forms[i].musicScore) {
 | 
	
		
			
				|  |  | +          pass = false
 | 
	
		
			
				|  |  | +          showToast('请输入曲目分数')
 | 
	
		
			
				|  |  | +          break
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!forms[i].passScore) {
 | 
	
		
			
				|  |  | +          pass = false
 | 
	
		
			
				|  |  | +          showToast('请输入合格分数')
 | 
	
		
			
				|  |  | +          break
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (!pass) return
 | 
	
		
			
				|  |  | +      console.log(true, '1212')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (isEdit.value) {
 | 
	
		
			
				|  |  | +        const questionList = unitData['level' + state.level]?.questionList
 | 
	
		
			
				|  |  | +        for (let i = 0; i < questionList.length; i++) {
 | 
	
		
			
				|  |  | +          if (questionList[i].question.mediaUrls === route.query.musicId) {
 | 
	
		
			
				|  |  | +            questionList[i].question = {
 | 
	
		
			
				|  |  | +              name: forms[0].musicName,
 | 
	
		
			
				|  |  | +              mediaUrls: forms[0].musicId,
 | 
	
		
			
				|  |  | +              questionTypeCode: 'PLAY',
 | 
	
		
			
				|  |  | +              totalScore: forms[0].musicScore,
 | 
	
		
			
				|  |  | +              questionExtendsInfo: JSON.stringify({
 | 
	
		
			
				|  |  | +                musicName: forms[0].musicName,
 | 
	
		
			
				|  |  | +                musicSheetId: forms[0].musicId,
 | 
	
		
			
				|  |  | +                start: forms[0].partStart,
 | 
	
		
			
				|  |  | +                end: forms[0].partEnd,
 | 
	
		
			
				|  |  | +                score: forms[0].passScore,
 | 
	
		
			
				|  |  | +                difficulty: forms[0].difficulty
 | 
	
		
			
				|  |  | +              })
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            break
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        const tempList: any = []
 | 
	
		
			
				|  |  | +        forms.forEach((item: any) => {
 | 
	
		
			
				|  |  | +          tempList.push({
 | 
	
		
			
				|  |  | +            unitExaminationId: null,
 | 
	
		
			
				|  |  | +            question: {
 | 
	
		
			
				|  |  | +              name: item.musicName,
 | 
	
		
			
				|  |  | +              mediaUrls: item.musicId,
 | 
	
		
			
				|  |  | +              questionTypeCode: 'PLAY',
 | 
	
		
			
				|  |  | +              totalScore: item.musicScore,
 | 
	
		
			
				|  |  | +              questionExtendsInfo: JSON.stringify({
 | 
	
		
			
				|  |  | +                musicName: item.musicName,
 | 
	
		
			
				|  |  | +                musicSheetId: item.musicId,
 | 
	
		
			
				|  |  | +                start: item.partStart,
 | 
	
		
			
				|  |  | +                end: item.partEnd,
 | 
	
		
			
				|  |  | +                score: item.passScore,
 | 
	
		
			
				|  |  | +                difficulty: item.difficulty
 | 
	
		
			
				|  |  | +              })
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +          })
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        // 添加曲目
 | 
	
		
			
				|  |  | +        unitData['level' + state.level]?.questionList.push(...tempList)
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      router.back()
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const _init = () => [
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        musicName: '',
 | 
	
		
			
				|  |  | +        musicId: null,
 | 
	
		
			
				|  |  | +        partName: '',
 | 
	
		
			
				|  |  | +        partLength: 0, // 总的小节数
 | 
	
		
			
				|  |  | +        partStart: null as any, // 开始小节数
 | 
	
		
			
				|  |  | +        partEnd: null as any, // 结束小节数
 | 
	
		
			
				|  |  | +        difficulty: null as any, // 难度
 | 
	
		
			
				|  |  | +        musicScore: null as any, // 曲目分数
 | 
	
		
			
				|  |  | +        passScore: null as any // 合格分数
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    ]
 | 
	
		
			
				|  |  | +    const forms = reactive(_init())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const getXMLPart = async (xmlFileUrl: string) => {
 | 
	
		
			
				|  |  | +      let xmlStatus = 'init'
 | 
	
		
			
				|  |  | +      // 第一个声部小节
 | 
	
		
			
				|  |  | +      let firstMeasures: any = null
 | 
	
		
			
				|  |  | +      let partLength = 0
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        // 获取文件
 | 
	
		
			
				|  |  | +        const res = await requestOrigin.get(xmlFileUrl, {
 | 
	
		
			
				|  |  | +          mode: 'cors'
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        const xmlParse = new DOMParser().parseFromString(res, 'text/xml')
 | 
	
		
			
				|  |  | +        const parts = xmlParse.getElementsByTagName('part')
 | 
	
		
			
				|  |  | +        firstMeasures = parts[0]?.getElementsByTagName('measure')
 | 
	
		
			
				|  |  | +        xmlStatus = 'success'
 | 
	
		
			
				|  |  | +      } catch (error) {
 | 
	
		
			
				|  |  | +        xmlStatus = 'error'
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // 判断读取小节数
 | 
	
		
			
				|  |  | +      if (xmlStatus == 'success') {
 | 
	
		
			
				|  |  | +        partLength = firstMeasures.length
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      return {
 | 
	
		
			
				|  |  | +        xmlStatus,
 | 
	
		
			
				|  |  | +        partLength
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    onMounted(async () => {
 | 
	
		
			
				|  |  | +      if (!route.query.musicId) return
 | 
	
		
			
				|  |  | +      const tData = unitData['level' + state.level]
 | 
	
		
			
				|  |  | +      let tempQ: any = null
 | 
	
		
			
				|  |  | +      tData?.questionList.forEach((item: any) => {
 | 
	
		
			
				|  |  | +        if (item.question.mediaUrls === route.query.musicId) {
 | 
	
		
			
				|  |  | +          tempQ = item
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +      if (tempQ) {
 | 
	
		
			
				|  |  | +        const questionExtendsInfo = tempQ.question.questionExtendsInfo
 | 
	
		
			
				|  |  | +          ? JSON.parse(tempQ.question.questionExtendsInfo)
 | 
	
		
			
				|  |  | +          : {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        forms[0] = {
 | 
	
		
			
				|  |  | +          musicName: tempQ.question.name,
 | 
	
		
			
				|  |  | +          musicId: tempQ.question.mediaUrls,
 | 
	
		
			
				|  |  | +          partName: '',
 | 
	
		
			
				|  |  | +          partLength: 0, // 总的小节数
 | 
	
		
			
				|  |  | +          partStart: questionExtendsInfo.start || 0, // 开始小节数
 | 
	
		
			
				|  |  | +          partEnd: questionExtendsInfo.end || 0, // 结束小节数
 | 
	
		
			
				|  |  | +          difficulty: questionExtendsInfo.difficulty, // 难度
 | 
	
		
			
				|  |  | +          musicScore: tempQ.question.totalScore, // 曲目分数
 | 
	
		
			
				|  |  | +          passScore: questionExtendsInfo.score // 合格分数
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 初始化名称
 | 
	
		
			
				|  |  | +        forms[0].partName = filterPart(forms[0])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const { data } = await request.get('/api-teacher/musicSheet/detail/' + route.query.musicId)
 | 
	
		
			
				|  |  | +        const partData = await getXMLPart(data.xmlFileUrl)
 | 
	
		
			
				|  |  | +        forms[0].partLength = partData.partLength
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +    return () => (
 | 
	
		
			
				|  |  | +      <div class={styles.addUnitItem}>
 | 
	
		
			
				|  |  | +        <OHeader />
 | 
	
		
			
				|  |  | +        {forms.map((item: any, index: number) => (
 | 
	
		
			
				|  |  | +          <CellGroup class={styles.cellGroup}>
 | 
	
		
			
				|  |  | +            <Cell center>
 | 
	
		
			
				|  |  | +              {{
 | 
	
		
			
				|  |  | +                title: () => (
 | 
	
		
			
				|  |  | +                  <div style={{ display: 'flex', 'align-items': 'center' }}>
 | 
	
		
			
				|  |  | +                    <Icon name={iconMusic} class={styles.iconMusic} />
 | 
	
		
			
				|  |  | +                    <div class={styles.title}>曲目{index + 1}</div>
 | 
	
		
			
				|  |  | +                  </div>
 | 
	
		
			
				|  |  | +                ),
 | 
	
		
			
				|  |  | +                value: () =>
 | 
	
		
			
				|  |  | +                  !isEdit.value && (
 | 
	
		
			
				|  |  | +                    <Icon
 | 
	
		
			
				|  |  | +                      name={iconDelete}
 | 
	
		
			
				|  |  | +                      class={[styles.iconDelete, forms.length <= 1 ? styles.disabled : '']}
 | 
	
		
			
				|  |  | +                      onClick={() => {
 | 
	
		
			
				|  |  | +                        state.dialogShow = true
 | 
	
		
			
				|  |  | +                        state.activeRow = {
 | 
	
		
			
				|  |  | +                          ...item,
 | 
	
		
			
				|  |  | +                          index
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                      }}
 | 
	
		
			
				|  |  | +                    />
 | 
	
		
			
				|  |  | +                  )
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            </Cell>
 | 
	
		
			
				|  |  | +            <Field
 | 
	
		
			
				|  |  | +              isLink
 | 
	
		
			
				|  |  | +              clearable={false}
 | 
	
		
			
				|  |  | +              inputAlign="right"
 | 
	
		
			
				|  |  | +              label="练习内容"
 | 
	
		
			
				|  |  | +              placeholder="请选择曲目"
 | 
	
		
			
				|  |  | +              autocomplete="off"
 | 
	
		
			
				|  |  | +              readonly
 | 
	
		
			
				|  |  | +              modelValue={item.musicName}
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                state.activeIndex = index
 | 
	
		
			
				|  |  | +                state.musicStatus = true
 | 
	
		
			
				|  |  | +                state.activeRow = item
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            />
 | 
	
		
			
				|  |  | +            <Field
 | 
	
		
			
				|  |  | +              isLink
 | 
	
		
			
				|  |  | +              clearable={false}
 | 
	
		
			
				|  |  | +              inputAlign="right"
 | 
	
		
			
				|  |  | +              label="练习小节"
 | 
	
		
			
				|  |  | +              autocomplete="off"
 | 
	
		
			
				|  |  | +              readonly
 | 
	
		
			
				|  |  | +              modelValue={item.partName}
 | 
	
		
			
				|  |  | +              placeholder="请选择小节"
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                if (!item.musicId) {
 | 
	
		
			
				|  |  | +                  return showToast('请选择曲目')
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                state.activeRow = item
 | 
	
		
			
				|  |  | +                state.partShow = true
 | 
	
		
			
				|  |  | +                state.startPart = item.partStart
 | 
	
		
			
				|  |  | +                state.endPart = item.partEnd
 | 
	
		
			
				|  |  | +                if (item.partEnd === item.partLength) {
 | 
	
		
			
				|  |  | +                  state.checkedPart = '1'
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                  state.checkedPart = '2'
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            />
 | 
	
		
			
				|  |  | +            <Field
 | 
	
		
			
				|  |  | +              isLink
 | 
	
		
			
				|  |  | +              clearable={false}
 | 
	
		
			
				|  |  | +              inputAlign="right"
 | 
	
		
			
				|  |  | +              label="练习难度"
 | 
	
		
			
				|  |  | +              autocomplete="off"
 | 
	
		
			
				|  |  | +              readonly
 | 
	
		
			
				|  |  | +              modelValue={filterDifficulty(item.difficulty)}
 | 
	
		
			
				|  |  | +              placeholder="请选择曲目难度"
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                state.musicLevelShow = true
 | 
	
		
			
				|  |  | +                state.activeRow = item
 | 
	
		
			
				|  |  | +                if (item.difficulty) {
 | 
	
		
			
				|  |  | +                  state.actions.forEach((action: any) => {
 | 
	
		
			
				|  |  | +                    if (action.value === item.difficulty) {
 | 
	
		
			
				|  |  | +                      action.selected = true
 | 
	
		
			
				|  |  | +                    } else {
 | 
	
		
			
				|  |  | +                      action.selected = false
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                  })
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                  state.actions.forEach((action: any) => {
 | 
	
		
			
				|  |  | +                    action.selected = false
 | 
	
		
			
				|  |  | +                  })
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            />
 | 
	
		
			
				|  |  | +            <Field
 | 
	
		
			
				|  |  | +              inputAlign="right"
 | 
	
		
			
				|  |  | +              label="曲目分数"
 | 
	
		
			
				|  |  | +              type="number"
 | 
	
		
			
				|  |  | +              autocomplete="off"
 | 
	
		
			
				|  |  | +              maxlength={3}
 | 
	
		
			
				|  |  | +              class={styles.inputControl}
 | 
	
		
			
				|  |  | +              v-model={item.musicScore}
 | 
	
		
			
				|  |  | +              center
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +              {{
 | 
	
		
			
				|  |  | +                extra: () => (
 | 
	
		
			
				|  |  | +                  <div class={styles.loctionIconWrap}>
 | 
	
		
			
				|  |  | +                    <span> 分</span>
 | 
	
		
			
				|  |  | +                  </div>
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            </Field>
 | 
	
		
			
				|  |  | +            <Field
 | 
	
		
			
				|  |  | +              inputAlign="right"
 | 
	
		
			
				|  |  | +              label="合格分数"
 | 
	
		
			
				|  |  | +              type="number"
 | 
	
		
			
				|  |  | +              maxlength={3}
 | 
	
		
			
				|  |  | +              autocomplete="off"
 | 
	
		
			
				|  |  | +              class={styles.inputControl}
 | 
	
		
			
				|  |  | +              v-model={item.passScore}
 | 
	
		
			
				|  |  | +              center
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +              {{
 | 
	
		
			
				|  |  | +                extra: () => (
 | 
	
		
			
				|  |  | +                  <div class={styles.loctionIconWrap}>
 | 
	
		
			
				|  |  | +                    <span> 分</span>
 | 
	
		
			
				|  |  | +                  </div>
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            </Field>
 | 
	
		
			
				|  |  | +          </CellGroup>
 | 
	
		
			
				|  |  | +        ))}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {!isEdit.value && (
 | 
	
		
			
				|  |  | +          <Button
 | 
	
		
			
				|  |  | +            round
 | 
	
		
			
				|  |  | +            class={styles.addBtn}
 | 
	
		
			
				|  |  | +            onClick={() => {
 | 
	
		
			
				|  |  | +              forms.push(..._init())
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          >
 | 
	
		
			
				|  |  | +            <Icon name="plus" />
 | 
	
		
			
				|  |  | +            添加测验曲目
 | 
	
		
			
				|  |  | +          </Button>
 | 
	
		
			
				|  |  | +        )}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <OSticky position="bottom">
 | 
	
		
			
				|  |  | +          <div class={'btnGroup'}>
 | 
	
		
			
				|  |  | +            <Button type="primary" round block onClick={onSubmit}>
 | 
	
		
			
				|  |  | +              确认
 | 
	
		
			
				|  |  | +            </Button>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </OSticky>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <OPopup v-model:modelValue={state.musicStatus} style={{ background: '#F8F8F8' }}>
 | 
	
		
			
				|  |  | +          <MusicList
 | 
	
		
			
				|  |  | +            onConfirm={async (row: any) => {
 | 
	
		
			
				|  |  | +              // 判断是否选择一样的曲目
 | 
	
		
			
				|  |  | +              if (row.id === state.activeRow.musicId) {
 | 
	
		
			
				|  |  | +                state.musicStatus = false
 | 
	
		
			
				|  |  | +                return
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +              state.activeRow.musicId = row.id
 | 
	
		
			
				|  |  | +              state.activeRow.musicName = row.musicSheetName
 | 
	
		
			
				|  |  | +              state.musicStatus = false
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              const partData = await getXMLPart(row.xmlFileUrl)
 | 
	
		
			
				|  |  | +              if (partData.xmlStatus === 'success') {
 | 
	
		
			
				|  |  | +                state.activeRow.partLength = partData.partLength
 | 
	
		
			
				|  |  | +                state.activeRow.partStart = 1
 | 
	
		
			
				|  |  | +                state.activeRow.partEnd = partData.partLength
 | 
	
		
			
				|  |  | +              } else {
 | 
	
		
			
				|  |  | +                state.activeRow.partLength = 0
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              state.activeRow.partName = ''
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        </OPopup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <Dialog
 | 
	
		
			
				|  |  | +          v-model:show={state.dialogShow}
 | 
	
		
			
				|  |  | +          showCancelButton
 | 
	
		
			
				|  |  | +          message={`请确认是否删除曲目${state.activeRow.index + 1}?`}
 | 
	
		
			
				|  |  | +          confirmButtonText="删除"
 | 
	
		
			
				|  |  | +          onConfirm={() => {
 | 
	
		
			
				|  |  | +            forms.splice(state.activeRow.index, 1)
 | 
	
		
			
				|  |  | +          }}
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +          {{ title: () => <div class={styles.dialogDelete}>删除题目</div> }}
 | 
	
		
			
				|  |  | +        </Dialog>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 曲目难度 */}
 | 
	
		
			
				|  |  | +        <OActionSheet
 | 
	
		
			
				|  |  | +          v-model:show={state.musicLevelShow}
 | 
	
		
			
				|  |  | +          actions={state.actions}
 | 
	
		
			
				|  |  | +          onSelect={(val: any) => {
 | 
	
		
			
				|  |  | +            state.actions.forEach((child: any) => {
 | 
	
		
			
				|  |  | +              child.selected = false
 | 
	
		
			
				|  |  | +            })
 | 
	
		
			
				|  |  | +            val.selected = true
 | 
	
		
			
				|  |  | +            state.activeRow.difficulty = val.value
 | 
	
		
			
				|  |  | +            state.musicLevelShow = false
 | 
	
		
			
				|  |  | +          }}
 | 
	
		
			
				|  |  | +        />
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {/* 选择小节 */}
 | 
	
		
			
				|  |  | +        <Popup
 | 
	
		
			
				|  |  | +          round
 | 
	
		
			
				|  |  | +          position="bottom"
 | 
	
		
			
				|  |  | +          v-model:show={state.partShow}
 | 
	
		
			
				|  |  | +          closeable
 | 
	
		
			
				|  |  | +          class={styles.partPopup}
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +          <div class={styles.partContainer}>
 | 
	
		
			
				|  |  | +            <div class={styles.partTitle}>请选择练习小节</div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <RadioGroup v-model={state.checkedPart}>
 | 
	
		
			
				|  |  | +              <Cell
 | 
	
		
			
				|  |  | +                title={'全部小节'}
 | 
	
		
			
				|  |  | +                onClick={() => (state.checkedPart = '1')}
 | 
	
		
			
				|  |  | +                class={state.checkedPart == '1' && styles.activeCell}
 | 
	
		
			
				|  |  | +              >
 | 
	
		
			
				|  |  | +                {{
 | 
	
		
			
				|  |  | +                  icon: () => (
 | 
	
		
			
				|  |  | +                    <Radio name="1">
 | 
	
		
			
				|  |  | +                      {{
 | 
	
		
			
				|  |  | +                        icon: (props: any) => (
 | 
	
		
			
				|  |  | +                          <img src={props.checked ? iconReadioChecked : iconRadioDefault} />
 | 
	
		
			
				|  |  | +                        )
 | 
	
		
			
				|  |  | +                      }}
 | 
	
		
			
				|  |  | +                    </Radio>
 | 
	
		
			
				|  |  | +                  )
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +              </Cell>
 | 
	
		
			
				|  |  | +              <Cell
 | 
	
		
			
				|  |  | +                title={'部分小节'}
 | 
	
		
			
				|  |  | +                onClick={() => (state.checkedPart = '2')}
 | 
	
		
			
				|  |  | +                class={state.checkedPart == '2' && styles.activeCell}
 | 
	
		
			
				|  |  | +              >
 | 
	
		
			
				|  |  | +                {{
 | 
	
		
			
				|  |  | +                  icon: () => (
 | 
	
		
			
				|  |  | +                    <Radio name="2">
 | 
	
		
			
				|  |  | +                      {{
 | 
	
		
			
				|  |  | +                        icon: (props: any) => (
 | 
	
		
			
				|  |  | +                          <img src={props.checked ? iconReadioChecked : iconRadioDefault} />
 | 
	
		
			
				|  |  | +                        )
 | 
	
		
			
				|  |  | +                      }}
 | 
	
		
			
				|  |  | +                    </Radio>
 | 
	
		
			
				|  |  | +                  ),
 | 
	
		
			
				|  |  | +                  label: () => (
 | 
	
		
			
				|  |  | +                    <div class={styles.partContent}>
 | 
	
		
			
				|  |  | +                      <Field
 | 
	
		
			
				|  |  | +                        type="number"
 | 
	
		
			
				|  |  | +                        maxlength={3}
 | 
	
		
			
				|  |  | +                        class={styles.partInput}
 | 
	
		
			
				|  |  | +                        v-model={state.startPart}
 | 
	
		
			
				|  |  | +                      />
 | 
	
		
			
				|  |  | +                      <span>至</span>
 | 
	
		
			
				|  |  | +                      <Field
 | 
	
		
			
				|  |  | +                        type="number"
 | 
	
		
			
				|  |  | +                        maxlength={3}
 | 
	
		
			
				|  |  | +                        class={styles.partInput}
 | 
	
		
			
				|  |  | +                        v-model={state.endPart}
 | 
	
		
			
				|  |  | +                      />
 | 
	
		
			
				|  |  | +                      <span>小节</span>
 | 
	
		
			
				|  |  | +                    </div>
 | 
	
		
			
				|  |  | +                  )
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +              </Cell>
 | 
	
		
			
				|  |  | +            </RadioGroup>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            <Button
 | 
	
		
			
				|  |  | +              round
 | 
	
		
			
				|  |  | +              block
 | 
	
		
			
				|  |  | +              type="primary"
 | 
	
		
			
				|  |  | +              class={styles.partBtn}
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                if (state.checkedPart === '1') {
 | 
	
		
			
				|  |  | +                  state.activeRow.partStart = 1
 | 
	
		
			
				|  |  | +                  state.activeRow.partEnd = state.activeRow.partLength
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                  state.activeRow.partStart = state.startPart
 | 
	
		
			
				|  |  | +                  state.activeRow.partEnd = state.endPart
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                state.activeRow.partName = filterPart(state.activeRow)
 | 
	
		
			
				|  |  | +                state.partShow = false
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            >
 | 
	
		
			
				|  |  | +              确认
 | 
	
		
			
				|  |  | +            </Button>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </Popup>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +})
 |