浏览代码

Merge branch 'iteration-20240912-pdf' into develop

lex-xin 7 月之前
父节点
当前提交
abe78593ad

+ 0 - 2
components.d.ts

@@ -15,7 +15,6 @@ declare module '@vue/runtime-core' {
     NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
     NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
     NButton: typeof import('naive-ui')['NButton']
-    NCheckbox: typeof import('naive-ui')['NCheckbox']
     NConfigProvider: typeof import('naive-ui')['NConfigProvider']
     NCountdown: typeof import('naive-ui')['NCountdown']
     NDialogProvider: typeof import('naive-ui')['NDialogProvider']
@@ -37,7 +36,6 @@ declare module '@vue/runtime-core' {
     NRadio: typeof import('naive-ui')['NRadio']
     NRadioGroup: typeof import('naive-ui')['NRadioGroup']
     NSpace: typeof import('naive-ui')['NSpace']
-    NSpin: typeof import('naive-ui')['NSpin']
     NTooltip: typeof import('naive-ui')['NTooltip']
     Recharge: typeof import('./src/components/Lockscreen/Recharge.vue')['default']
     RouterError: typeof import('./src/components/RouterError/RouterError.vue')['default']

+ 14 - 12
src/views/music-library/music-sheet/component/music-list.tsx

@@ -343,18 +343,20 @@ export default defineComponent({
                 >
                   生成图片
                 </NButton>
-                <NButton
-                  type="primary"
-                  size="small"
-                  text
-                  v-auth="musicSheet/addMix1819259767120539649"
-                  onClick={() => {
-                    state.productItem = row
-                    state.beatTimeOpen = true
-                  }}
-                >
-                  生成节拍器音频
-                </NButton>
+                { row.isMixBeat &&
+                  <NButton
+                    type="primary"
+                    size="small"
+                    text
+                    v-auth="musicSheet/addMix1819259767120539649"
+                    onClick={() => {
+                      state.productItem = row
+                      state.beatTimeOpen = true
+                    }}
+                  >
+                    生成节拍器音频
+                  </NButton>
+                }
                 <NButton
                   type="primary"
                   size="small"

+ 435 - 245
src/views/music-library/music-sheet/modal/music-operationV2.tsx

@@ -116,7 +116,7 @@ export const onlyVisible = (xml: any, partIndex: any) => {
     Array.from(notes).forEach((note, i) => {
       const graces = note.getElementsByTagName('grace')
       if (graces && graces.length && getNextvNoteDuration(i)) {
-          note?.appendChild(getNextvNoteDuration(i)?.cloneNode(true))
+        note?.appendChild(getNextvNoteDuration(i)?.cloneNode(true))
       }
     })
   }
@@ -369,6 +369,10 @@ export default defineComponent({
       isShowFingering: true, // 是否显示指法
       solmizationFileUrl: null, // 唱名文件
       isAllSubject: false, // 适用声部
+      isMixBeat: true, // 是否生成节拍器
+      musicPdfUrl: '', // 总谱五线谱PDF
+      firstPdfUrl: '',  // 总谱首调PDF
+      jianPdfUrl: '', // 总谱固定PDF
 
       fSongList: [] as any, // 范唱列表
       isScoreRender: true, // 总谱渲染
@@ -412,7 +416,7 @@ export default defineComponent({
 
       // 修改:修改内容XML(生成图片)、MP3(生成节拍器);其他情况无需生成图片、节拍器
       isCreateImg: false, // 是否生成图片
-      isBeatTime: false, // 是否生成节拍器
+      isBeatTime: false // 是否生成节拍器
     })
     const gradualData = reactive({
       list: [] as any[],
@@ -426,7 +430,7 @@ export default defineComponent({
       () => forms.multiTracksSelection,
       (value) => {
         // 在修改的时候不用自动更新
-        if(state.musicUpdateLoading)  {
+        if (state.musicUpdateLoading) {
           state.musicUpdateLoading = false
           return
         }
@@ -594,7 +598,7 @@ export default defineComponent({
                 forms.isScoreRender &&
                 forms.scoreAudioFileUrl
                   ? forms.scoreAudioFileUrl
-                  : null, 
+                  : null,
               audioPlayType: 'SING'
             })
           } else {
@@ -604,7 +608,6 @@ export default defineComponent({
               audioPlayType: 'SING'
             })
           }
-          
 
           if (state.musicSheetAccompanimentUrl) {
             forms.musicSheetAccompanimentList.push({
@@ -641,9 +644,13 @@ export default defineComponent({
             playSpeed: forms.playSpeed,
             playMode: forms.playMode,
             xmlFileUrl: forms.xmlFileUrl,
+            isMixBeat: forms.isMixBeat,
             musicImg: forms.musicImg,
             musicFirstImg: forms.musicFirstImg,
             musicJianImg: forms.musicJianImg,
+            musicPdfUrl: forms.musicPdfUrl,
+            firstPdfUrl: forms.firstPdfUrl,
+            jianPdfUrl: forms.jianPdfUrl,
             extConfigJson: JSON.stringify({
               repeatedBeats: forms.repeatedBeats ? 1 : 0,
               gradualTimes: forms.graduals,
@@ -678,7 +685,7 @@ export default defineComponent({
           } else if (props.type === 'edit') {
             resData = await musicSheetSave({ ...obj, id: props.data.id })
           }
-          if(state.isBeatTime) {
+          if (state.isBeatTime && forms.isMixBeat) {
             beatTimeData.beatTimeOpen = true
             beatTimeData.musicId = resData.data
             state.showUseProjectId = resData.data
@@ -690,7 +697,6 @@ export default defineComponent({
               state.isAutoSave = false
             }, 100)
           }
-          
         } catch (e) {
           console.log(e)
           setTimeout(() => {
@@ -702,14 +708,14 @@ export default defineComponent({
     }
     // 合成节拍器的回调
     function handlerMusiceBeatTimeClose(val: any) {
-      if(!val) {
+      if (!val) {
         if (props.type === 'add') {
           message.success('添加成功')
         } else if (props.type === 'edit') {
           message.success('修改成功')
         }
       }
-      
+
       emit('getList')
       emit('close')
       setTimeout(() => {
@@ -752,7 +758,7 @@ export default defineComponent({
 
     // 上传XML,初始化音轨 音轨速度 乐器、声部
     const readFileInputEventAsArrayBuffer = (file: any) => {
-      state.isCreateImg = true; // 更换XML
+      state.isCreateImg = true // 更换XML
       // 是否是evxml
       const xmlRead = new FileReader()
       xmlRead.onload = (res) => {
@@ -836,7 +842,7 @@ export default defineComponent({
         // }
 
         if (forms.musicSheetSoundList_YY.length == 0) {
-          forms.musicSheetSoundList_YY.push({ audioFileUrl: '', track: '' })
+          forms.musicSheetSoundList_YY.push({ audioFileUrl: '', track: '', musicPdfUrl: '', firstPdfUrl: '', jianPdfUrl: '' })
         }
       }
       xmlRead.readAsText(file)
@@ -884,13 +890,13 @@ export default defineComponent({
     const initInstrumentAndSubjectByTrack = async (tracks: string[]) => {
       // 选择一个声轨,独奏
       // 选择了多个声轨,合奏,乐器和声部自动反显,不可修改
-      if (!tracks || tracks.length <= 1) {
-        forms.musicSheetType = 'SINGLE'
-        state.subjectDisabled = false
-        state.instrumentDisabled = false
-        return
-      }
-      forms.musicSheetType = 'CONCERT'
+      // if (!tracks || tracks.length <= 1) {
+      //   forms.musicSheetType = 'SINGLE'
+      //   state.subjectDisabled = false
+      //   state.instrumentDisabled = false
+      //   return
+      // }
+      forms.musicSheetType = !tracks || tracks.length <= 1 ? 'SINGLE' : 'CONCERT'
       state.subjectDisabled = true
       state.instrumentDisabled = true
       await initInstrumentAndSubjectByCode(tracks)
@@ -1013,15 +1019,15 @@ export default defineComponent({
         //     track = id
         //   }
         // } else {
-          // 优先解析声轨,没有就取id值
-          if (part && part.textContent?.trim()) {
-            track = part.textContent || ''
-          } else {
-            let id = item.getAttribute('id')
-            if (id) {
-              track = id
-            }
+        // 优先解析声轨,没有就取id值
+        if (part && part.textContent?.trim()) {
+          track = part.textContent || ''
+        } else {
+          let id = item.getAttribute('id')
+          if (id) {
+            track = id
           }
+        }
         // }
         return {
           value: track.trim(),
@@ -1098,10 +1104,10 @@ export default defineComponent({
         const tempList = data.rows || []
         const tempSubject: any[] = []
         tempList.forEach((item: any) => {
-          if(item.enableFlag) {
+          if (item.enableFlag) {
             tempSubject.push(item.id + '')
           }
-        })  
+        })
         forms.subjectIds = tempSubject
       } catch {}
     }
@@ -1180,13 +1186,19 @@ export default defineComponent({
         state.ownerName = app[0].appName
       }
       if (forms.sourceType == 'ORG') {
-        state.ownerName = state.ownerName ? state.ownerName + '-' + forms.musicSheetExtend.organizationRole : forms.musicSheetExtend.organizationRole
+        state.ownerName = state.ownerName
+          ? state.ownerName + '-' + forms.musicSheetExtend.organizationRole
+          : forms.musicSheetExtend.organizationRole
       } else if (forms.sourceType == 'PERSON') {
-        state.ownerName = state.ownerName ? state.ownerName +
-          '-' +
-          getMapValueByKey(forms.musicSheetExtend.clientType, new Map(Object.entries(clientType))) : getMapValueByKey(forms.musicSheetExtend.clientType, new Map(Object.entries(clientType)))
+        state.ownerName = state.ownerName
+          ? state.ownerName +
+            '-' +
+            getMapValueByKey(forms.musicSheetExtend.clientType, new Map(Object.entries(clientType)))
+          : getMapValueByKey(forms.musicSheetExtend.clientType, new Map(Object.entries(clientType)))
         if (forms.musicSheetExtend.userName) {
-          state.ownerName = state.ownerName ? state.ownerName + '-' + forms.musicSheetExtend.userName : forms.musicSheetExtend.userName
+          state.ownerName = state.ownerName
+            ? state.ownerName + '-' + forms.musicSheetExtend.userName
+            : forms.musicSheetExtend.userName
         }
         if (forms.musicSheetExtend.phone) {
           state.ownerName += '(' + forms.musicSheetExtend.phone + ')'
@@ -1278,7 +1290,12 @@ export default defineComponent({
       {
         const appKeys = Object.keys(appKey)
 
-        const { data } = await sysApplicationPage({ page: 1, rows: 999, parentId: 0, hiddenFlag: true })
+        const { data } = await sysApplicationPage({
+          page: 1,
+          rows: 999,
+          parentId: 0,
+          hiddenFlag: true
+        })
         const tempList = data.rows || []
         const filter = tempList.filter((next: any) => {
           return appKeys.includes(next.appKey)
@@ -1309,7 +1326,7 @@ export default defineComponent({
 
       if (props.type === 'edit' || props.type === 'preview') {
         const detail = props.data
-        
+
         try {
           const { data } = await musicSheetDetail({ id: detail.id })
           forms.details = data
@@ -1335,6 +1352,10 @@ export default defineComponent({
           forms.appAuditFlag = data.appAuditFlag ? 1 : 0
           forms.midiFileUrl = data.midiFileUrl
           forms.isShowFingering = data.isShowFingering
+          forms.isMixBeat = data.isMixBeat
+          forms.musicPdfUrl = data.musicPdfUrl
+          forms.firstPdfUrl = data.firstPdfUrl
+          forms.jianPdfUrl = data.jianPdfUrl
           forms.isAllSubject = data.isAllSubject
           forms.isUseSingSystemBeat = data.isUseSingSystemBeat
           forms.isPlaySingBeat = data.isPlaySingBeat
@@ -1347,12 +1368,10 @@ export default defineComponent({
                 forms.subjectIds.push(subjectId)
               }
             })
-            
+
             state.subjectList = state.subjectList.filter((subject: any) => {
               return !subject.disabled || subjectIds.includes(subject.value)
             })
-
-            
           }
           forms.musicCategoryId = data.musicCategoryId
           forms.audioType = data.audioType
@@ -1425,7 +1444,7 @@ export default defineComponent({
           setOwnerName()
           axios.get(data.xmlFileUrl).then((res: any) => {
             if (res?.data) {
-              state.musicUpdateLoading = true;
+              state.musicUpdateLoading = true
               gradualData.list = getGradualLengthByXml(res?.data as any).filter(
                 (item: any) => item.length === 2
               )
@@ -1473,6 +1492,9 @@ export default defineComponent({
               state.partListNames.forEach((item: any) => {
                 let audioFileUrl = null
                 let musicalInstrumentId = null
+                let musicPdfUrl = null
+                let firstPdfUrl = null
+                let jianPdfUrl = null
                 if (forms.musicSheetType == 'CONCERT') {
                   existSoundList.forEach((next: any) => {
                     if (next.audioPlayType == 'PLAY') {
@@ -1483,12 +1505,18 @@ export default defineComponent({
                       if (track == item.value) {
                         audioFileUrl = next.audioFileUrl
                         musicalInstrumentId = next.musicalInstrumentId
+                        musicPdfUrl = next.musicPdfUrl
+                        firstPdfUrl = next.firstPdfUrl
+                        jianPdfUrl = next.jianPdfUrl
                       }
                     }
                   })
                 }
                 forms.musicSheetSoundList_YY.push({
                   audioFileUrl: audioFileUrl, // 原音
+                  musicPdfUrl, // 五线谱pdf
+                  firstPdfUrl,// 首调pdf
+                  jianPdfUrl,// 固定调pdf
                   musicalInstrumentId: musicalInstrumentId, // 乐器
                   track: item.value, // 轨道
                   audioPlayType: 'PLAY'
@@ -1836,6 +1864,78 @@ export default defineComponent({
                 />
               </NFormItemGi>
               <NFormItemGi
+                label="总谱五线谱PDF"
+                path="musicPdfUrl"
+                rule={[
+                  {
+                    required: false,
+                    message: '请选择总谱五线谱PDF',
+                    trigger: ['change', 'input']
+                  }
+                ]}
+              >
+                <UploadFile
+                  desc={'总谱五线谱PDF'}
+                  disabled={state.previewMode}
+                  size={30}
+                  max={1}
+                  v-model:fileList={forms.musicPdfUrl}
+                  tips="仅支持上传.pdf格式文件"
+                  listType="image"
+                  accept=".pdf"
+                  bucketName="cloud-coach"
+                  text="点击上传PDF"
+                />
+              </NFormItemGi>
+              <NFormItemGi
+                label="总谱首调PDF"
+                path="firstPdfUrl"
+                rule={[
+                  {
+                    required: false,
+                    message: '请选择总谱首调PDF',
+                    trigger: ['change', 'input']
+                  }
+                ]}
+              >
+                <UploadFile
+                  desc={'总谱首调PDF'}
+                  disabled={state.previewMode}
+                  size={30}
+                  max={1}
+                  v-model:fileList={forms.firstPdfUrl}
+                  tips="仅支持上传.pdf格式文件"
+                  listType="image"
+                  accept=".pdf"
+                  bucketName="cloud-coach"
+                  text="点击上传PDF"
+                />
+              </NFormItemGi>
+              <NFormItemGi
+                label="总谱固定PDF"
+                path="jianPdfUrl"
+                rule={[
+                  {
+                    required: false,
+                    message: '请选择总谱固定PDF',
+                    trigger: ['change', 'input']
+                  }
+                ]}
+              >
+                <UploadFile
+                  desc={'总谱固定PDF'}
+                  disabled={state.previewMode}
+                  size={30}
+                  max={1}
+                  v-model:fileList={forms.jianPdfUrl}
+                  tips="仅支持上传.pdf格式文件"
+                  listType="image"
+                  accept=".pdf"
+                  bucketName="cloud-coach"
+                  text="点击上传PDF"
+                />
+              </NFormItemGi>
+              <NFormItemGi
                 label="评分标准"
                 path="evaluationStandard"
                 rule={[
@@ -2056,211 +2156,16 @@ export default defineComponent({
               </NGrid>
             )}
             <NAlert showIcon={false} style={{ marginBottom: '12px' }}>
-              演唱文件
-            </NAlert>
-            <NGrid cols={2}>
-              <NFormItemGi
-                label="是否播放节拍器"
-                path="isPlaySingBeat"
-                rule={[
-                  {
-                    required: true,
-                    message: '请选择是否播放节拍器'
-                  }
-                ]}
-              >
-                <NRadioGroup v-model:value={forms.isPlaySingBeat}>
-                  <NRadio value={true}>是</NRadio>
-                  <NRadio value={false}>否</NRadio>
-                </NRadioGroup>
-              </NFormItemGi>
-              {forms.isPlaySingBeat && (
-                <NFormItemGi
-                  label="播放方式"
-                  path="isUseSingSystemBeat"
-                  rule={[
-                    {
-                      required: true,
-                      message: '请选择播放方式'
-                    }
-                  ]}
-                >
-                  <NRadioGroup v-model:value={forms.isUseSingSystemBeat}>
-                    <NRadio value={true}>系统节拍器</NRadio>
-                    <NRadio value={false}>MP3节拍器</NRadio>
-                  </NRadioGroup>
-                </NFormItemGi>
-              )}
-            </NGrid>
-            <NGrid cols={2}>
-              <NFormItemGi
-                label="重复节拍时长"
-                path="repeatedBeatsToSing"
-                rule={[
-                  {
-                    required: false,
-                    message: '请选择是否重复节拍时长'
-                  }
-                ]}
-              >
-                <NRadioGroup v-model:value={forms.repeatedBeatsToSing}>
-                  <NRadio value={true}>是</NRadio>
-                  <NRadio value={false}>否</NRadio>
-                </NRadioGroup>
-              </NFormItemGi>
-            </NGrid>
-            <NGrid cols={2}>
-              <NFormItemGi
-                label="上传伴唱"
-                path="bSongFile"
-                rule={[
-                  {
-                    required: false
-                  }
-                ]}
-              >
-                <UploadFile
-                  desc={'上传伴唱'}
-                  disabled={state.previewMode}
-                  size={30}
-                  v-model:fileList={state.bSongFile}
-                  onUpdate:fileList={() => {
-                    state.isBeatTime = true;
-                  }}
-                  tips="仅支持上传.mp3格式文件"
-                  listType="image"
-                  accept=".mp3"
-                  bucketName="cloud-coach"
-                  text="点击上传伴唱文件"
-                />
-              </NFormItemGi>
-            </NGrid>
-            {forms.fSongList.length > 0 &&
-              forms.fSongList.map((item: any) => {
-                return (
-                  <NGrid class={styles.audioSection}>
-                    <NFormItemGi
-                      span={12}
-                      label={item.track + '范唱'}
-                      path={item.audioFileUrl}
-                      rule={[
-                        {
-                          required: false
-                        }
-                      ]}
-                    >
-                      <UploadFile
-                        desc={'上传范唱'}
-                        disabled={state.previewMode}
-                        size={100}
-                        v-model:fileList={item.audioFileUrl}
-                        onUpdate:fileList={() => {
-                          state.isBeatTime = true;
-                        }}
-                        tips="仅支持上传.mp3格式文件"
-                        listType="image"
-                        accept=".mp3"
-                        bucketName="cloud-coach"
-                        text={'点击上传范唱文件'}
-                      />
-                    </NFormItemGi>
-                  </NGrid>
-                )
-              })}
-            {forms.multiTracksSelection.length > 1 && forms.isScoreRender && (
-              <NGrid cols={2} class={styles.audioSection}>
-                <NFormItemGi
-                  label="总谱范唱"
-                  path="scoreRenderFile"
-                  rule={[
-                    {
-                      required: false
-                    }
-                  ]}
-                >
-                  <UploadFile
-                    desc={'上传总谱范唱'}
-                    disabled={state.previewMode}
-                    size={30}
-                    v-model:fileList={forms.scoreAudioFileUrl}
-                    onUpdate:fileList={() => {
-                      state.isBeatTime = true;
-                    }}
-                    tips="仅支持上传.mp3格式文件"
-                    listType="image"
-                    accept=".mp3"
-                    bucketName="cloud-coach"
-                    text="点击上传总谱范唱"
-                  />
-                </NFormItemGi>
-              </NGrid>
-            )}
-            {forms.fSongList.length > 0 &&
-              forms.fSongList.map((item: any) => {
-                return (
-                  <NGrid cols={2}>
-                    <NFormItemGi
-                      label={item.track + '唱名(男)'}
-                      path={item.solmizationFileUrl}
-                      rule={[
-                        {
-                          required: false
-                        }
-                      ]}
-                    >
-                      <UploadFile
-                        desc={'上传范唱'}
-                        disabled={state.previewMode}
-                        size={100}
-                        v-model:fileList={item.solmizationFileUrl}
-                        onUpdate:fileList={() => {
-                          state.isBeatTime = true;
-                        }}
-                        tips="仅支持上传.mp3格式文件"
-                        listType="image"
-                        accept=".mp3"
-                        bucketName="cloud-coach"
-                        text={'点击上传唱名文件'}
-                      />
-                    </NFormItemGi>
-                    <NFormItemGi
-                      label={item.track + '唱名(女)'}
-                      path={item.femaleSolmizationFileUrl}
-                      rule={[
-                        {
-                          required: false
-                        }
-                      ]}
-                    >
-                      <UploadFile
-                        desc={'上传范唱'}
-                        disabled={state.previewMode}
-                        size={100}
-                        v-model:fileList={item.femaleSolmizationFileUrl}
-                        onUpdate:fileList={() => {
-                          state.isBeatTime = true;
-                        }}
-                        tips="仅支持上传.mp3格式文件"
-                        listType="image"
-                        accept=".mp3"
-                        bucketName="cloud-coach"
-                        text={'点击上传唱名文件'}
-                      />
-                    </NFormItemGi>
-                  </NGrid>
-                )
-              })}
-            <NAlert showIcon={false} style={{ marginBottom: '12px' }}>
               演奏文件
             </NAlert>
             <NGrid cols={2}>
               <NFormItemGi
-                label="是否播放节拍器"
+                label="是否播放预备拍"
                 path="isPlayBeat"
                 rule={[
                   {
                     required: true,
-                    message: '请选择是否播放节拍器'
+                    message: '请选择是否播放预备拍'
                   }
                 ]}
               >
@@ -2281,8 +2186,8 @@ export default defineComponent({
                   ]}
                 >
                   <NRadioGroup v-model:value={forms.isUseSystemBeat}>
-                    <NRadio value={true}>系统节拍器</NRadio>
-                    <NRadio value={false}>MP3节拍器</NRadio>
+                    <NRadio value={true}>系统预备拍</NRadio>
+                    <NRadio value={false}>MP3预备拍</NRadio>
                   </NRadioGroup>
                 </NFormItemGi>
               )}
@@ -2318,6 +2223,21 @@ export default defineComponent({
                   <NRadio value={false}>否</NRadio>
                 </NRadioGroup>
               </NFormItemGi>
+              <NFormItemGi
+                label="是否生成节拍器"
+                path="isMixBeat"
+                rule={[
+                  {
+                    required: true,
+                    message: '请选择是否生成节拍器'
+                  }
+                ]}
+              >
+                <NRadioGroup v-model:value={forms.isMixBeat} onUpdate:value={()=>{ state.isBeatTime = true }}>
+                  <NRadio value={true}>是</NRadio>
+                  <NRadio value={false}>否</NRadio>
+                </NRadioGroup>
+              </NFormItemGi>
             </NGrid>
             <NGrid cols={2}>
               {forms.playMode === 'MP3' && (
@@ -2336,7 +2256,7 @@ export default defineComponent({
                     size={30}
                     v-model:fileList={state.musicSheetAccompanimentUrl}
                     onUpdate:fileList={() => {
-                      state.isBeatTime = true;
+                      state.isBeatTime = true
                     }}
                     tips="仅支持上传.mp3格式文件"
                     listType="image"
@@ -2368,7 +2288,7 @@ export default defineComponent({
                     max={1}
                     v-model:fileList={forms.musicSheetSoundList_all_subject}
                     onUpdate:fileList={() => {
-                      state.isBeatTime = true;
+                      state.isBeatTime = true
                     }}
                     tips="仅支持上传.mp3格式文件"
                     listType="image"
@@ -2462,7 +2382,7 @@ export default defineComponent({
                             size={100}
                             v-model:fileList={item.audioFileUrl}
                             onUpdate:fileList={() => {
-                              state.isBeatTime = true;
+                              state.isBeatTime = true
                             }}
                             tips="仅支持上传.mp3格式文件"
                             listType="image"
@@ -2511,7 +2431,7 @@ export default defineComponent({
                                 size={100}
                                 v-model:fileList={item.audioFileUrl}
                                 onUpdate:fileList={() => {
-                                  state.isBeatTime = true;
+                                  state.isBeatTime = true
                                 }}
                                 tips="仅支持上传.mp3格式文件"
                                 listType="image"
@@ -2573,6 +2493,81 @@ export default defineComponent({
                                 />
                               </NFormItemGi>
                             )}
+                            <NFormItemGi
+                              span={12}
+                              label="五线谱PDF"
+                              path={`musicSheetSoundList_YY[${index}].musicPdfUrl`}
+                              rule={[
+                                {
+                                  required: false,
+                                  message: '请选择五线谱PDF',
+                                  trigger: ['change', 'input']
+                                }
+                              ]}
+                            >
+                              <UploadFile
+                                desc={'五线谱PDF'}
+                                disabled={state.previewMode}
+                                size={30}
+                                max={1}
+                                v-model:fileList={item.musicPdfUrl}
+                                tips="仅支持上传.pdf格式文件"
+                                listType="image"
+                                accept=".pdf"
+                                bucketName="cloud-coach"
+                                text="点击上传PDF"
+                              />
+                            </NFormItemGi>
+                            <NFormItemGi
+                              span={12}
+                              label="首调PDF"
+                              path={`musicSheetSoundList_YY[${index}].firstPdfUrl`}
+                              rule={[
+                                {
+                                  required: false,
+                                  message: '请选择首调PDF',
+                                  trigger: ['change', 'input']
+                                }
+                              ]}
+                            >
+                              <UploadFile
+                                desc={'首调PDF'}
+                                disabled={state.previewMode}
+                                size={30}
+                                max={1}
+                                v-model:fileList={item.firstPdfUrl}
+                                tips="仅支持上传.pdf格式文件"
+                                listType="image"
+                                accept=".pdf"
+                                bucketName="cloud-coach"
+                                text="点击上传PDF"
+                              />
+                            </NFormItemGi>
+                            <NFormItemGi
+                              span={12}
+                              label="固定PDF"
+                              path={`musicSheetSoundList_YY[${index}].jianPdfUrl`}
+                              rule={[
+                                {
+                                  required: false,
+                                  message: '请选择固定PDF',
+                                  trigger: ['change', 'input']
+                                }
+                              ]}
+                            >
+                              <UploadFile
+                                desc={'固定PDF'}
+                                disabled={state.previewMode}
+                                size={30}
+                                max={1}
+                                v-model:fileList={item.jianPdfUrl}
+                                tips="仅支持上传.pdf格式文件"
+                                listType="image"
+                                accept=".pdf"
+                                bucketName="cloud-coach"
+                                text="点击上传PDF"
+                              />
+                            </NFormItemGi>
                             <NGi class={styles.btnRemove}>
                               <NButton
                                 type="primary"
@@ -2590,6 +2585,201 @@ export default defineComponent({
                   })}
                 </>
               )}
+            <NAlert showIcon={false} style={{ marginBottom: '12px' }}>
+              演唱文件
+            </NAlert>
+            <NGrid cols={2}>
+              <NFormItemGi
+                label="是否播放节拍器"
+                path="isPlaySingBeat"
+                rule={[
+                  {
+                    required: true,
+                    message: '请选择是否播放节拍器'
+                  }
+                ]}
+              >
+                <NRadioGroup v-model:value={forms.isPlaySingBeat}>
+                  <NRadio value={true}>是</NRadio>
+                  <NRadio value={false}>否</NRadio>
+                </NRadioGroup>
+              </NFormItemGi>
+              {forms.isPlaySingBeat && (
+                <NFormItemGi
+                  label="播放方式"
+                  path="isUseSingSystemBeat"
+                  rule={[
+                    {
+                      required: true,
+                      message: '请选择播放方式'
+                    }
+                  ]}
+                >
+                  <NRadioGroup v-model:value={forms.isUseSingSystemBeat}>
+                    <NRadio value={true}>系统节拍器</NRadio>
+                    <NRadio value={false}>MP3节拍器</NRadio>
+                  </NRadioGroup>
+                </NFormItemGi>
+              )}
+            </NGrid>
+            <NGrid cols={2}>
+              <NFormItemGi
+                label="重复节拍时长"
+                path="repeatedBeatsToSing"
+                rule={[
+                  {
+                    required: false,
+                    message: '请选择是否重复节拍时长'
+                  }
+                ]}
+              >
+                <NRadioGroup v-model:value={forms.repeatedBeatsToSing}>
+                  <NRadio value={true}>是</NRadio>
+                  <NRadio value={false}>否</NRadio>
+                </NRadioGroup>
+              </NFormItemGi>
+            </NGrid>
+            <NGrid cols={2}>
+              <NFormItemGi
+                label="上传伴唱"
+                path="bSongFile"
+                rule={[
+                  {
+                    required: false
+                  }
+                ]}
+              >
+                <UploadFile
+                  desc={'上传伴唱'}
+                  disabled={state.previewMode}
+                  size={30}
+                  v-model:fileList={state.bSongFile}
+                  onUpdate:fileList={() => {
+                    state.isBeatTime = true
+                  }}
+                  tips="仅支持上传.mp3格式文件"
+                  listType="image"
+                  accept=".mp3"
+                  bucketName="cloud-coach"
+                  text="点击上传伴唱文件"
+                />
+              </NFormItemGi>
+            </NGrid>
+            {forms.fSongList.length > 0 &&
+              forms.fSongList.map((item: any) => {
+                return (
+                  <NGrid class={styles.audioSection}>
+                    <NFormItemGi
+                      span={12}
+                      label={item.track + '范唱'}
+                      path={item.audioFileUrl}
+                      rule={[
+                        {
+                          required: false
+                        }
+                      ]}
+                    >
+                      <UploadFile
+                        desc={'上传范唱'}
+                        disabled={state.previewMode}
+                        size={100}
+                        v-model:fileList={item.audioFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true
+                        }}
+                        tips="仅支持上传.mp3格式文件"
+                        listType="image"
+                        accept=".mp3"
+                        bucketName="cloud-coach"
+                        text={'点击上传范唱文件'}
+                      />
+                    </NFormItemGi>
+                  </NGrid>
+                )
+              })}
+            {forms.multiTracksSelection.length > 1 && forms.isScoreRender && (
+              <NGrid cols={2} class={styles.audioSection}>
+                <NFormItemGi
+                  label="总谱范唱"
+                  path="scoreRenderFile"
+                  rule={[
+                    {
+                      required: false
+                    }
+                  ]}
+                >
+                  <UploadFile
+                    desc={'上传总谱范唱'}
+                    disabled={state.previewMode}
+                    size={30}
+                    v-model:fileList={forms.scoreAudioFileUrl}
+                    onUpdate:fileList={() => {
+                      state.isBeatTime = true
+                    }}
+                    tips="仅支持上传.mp3格式文件"
+                    listType="image"
+                    accept=".mp3"
+                    bucketName="cloud-coach"
+                    text="点击上传总谱范唱"
+                  />
+                </NFormItemGi>
+              </NGrid>
+            )}
+            {forms.fSongList.length > 0 &&
+              forms.fSongList.map((item: any) => {
+                return (
+                  <NGrid cols={2}>
+                    <NFormItemGi
+                      label={item.track + '唱名(男)'}
+                      path={item.solmizationFileUrl}
+                      rule={[
+                        {
+                          required: false
+                        }
+                      ]}
+                    >
+                      <UploadFile
+                        desc={'上传范唱'}
+                        disabled={state.previewMode}
+                        size={100}
+                        v-model:fileList={item.solmizationFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true
+                        }}
+                        tips="仅支持上传.mp3格式文件"
+                        listType="image"
+                        accept=".mp3"
+                        bucketName="cloud-coach"
+                        text={'点击上传唱名文件'}
+                      />
+                    </NFormItemGi>
+                    <NFormItemGi
+                      label={item.track + '唱名(女)'}
+                      path={item.femaleSolmizationFileUrl}
+                      rule={[
+                        {
+                          required: false
+                        }
+                      ]}
+                    >
+                      <UploadFile
+                        desc={'上传范唱'}
+                        disabled={state.previewMode}
+                        size={100}
+                        v-model:fileList={item.femaleSolmizationFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true
+                        }}
+                        tips="仅支持上传.mp3格式文件"
+                        listType="image"
+                        accept=".mp3"
+                        bucketName="cloud-coach"
+                        text={'点击上传唱名文件'}
+                      />
+                    </NFormItemGi>
+                  </NGrid>
+                )
+              })}
           </NForm>
         </NSpin>
         {props.type !== 'preview' && (
@@ -2668,9 +2858,9 @@ export default defineComponent({
           <MusiceBeatTime
             id={beatTimeData.musicId}
             // onClose={handlerMusiceBeatTimeClose}
-            onClose={(val: any)=> {
+            onClose={(val: any) => {
               beatTimeData.beatTimeOpen = false
-              if(val) return
+              if (val) return
 
               state.showUseProject = true
             }}
@@ -2698,7 +2888,7 @@ export default defineComponent({
             id={state.showUseProjectId}
             useProject={state.useProjectData}
             onClose={handlerMusiceBeatTimeClose}
-            />
+          />
         </NModal>
       </div>
     )