瀏覽代碼

创建曲目时添加适用项目

lex-xin 10 月之前
父節點
當前提交
87e1dd2902

+ 1 - 0
src/utils/constant.ts

@@ -257,6 +257,7 @@ export const appKey = {
   GYM: '管乐迷',
   GYT: '管乐团',
   KLX: '酷乐秀',
+  KLX_JG: '酷乐秀机构',
   KT: '音乐数字课堂'
 } as any
 

+ 11 - 5
src/views/music-library/music-sheet/component/music-list.tsx

@@ -45,6 +45,7 @@ import TheTooltip from '@components/TheTooltip'
 import { HelpCircleOutline } from '@vicons/ionicons5'
 import { musicalInstrumentPage } from '@views/system-manage/subject-manage/api'
 import MusiceBeatTime from '../modal/musiceBeatTime'
+import MusicPlatform from '../modal/music-platform'
 
 export default defineComponent({
   name: 'music-list',
@@ -160,7 +161,6 @@ export default defineComponent({
         },
         {
           title: '作者属性',
-          minWidth: '250px',
           key: 'sourceType',
           render(row: any) {
             return (
@@ -208,6 +208,7 @@ export default defineComponent({
                     </svg>
                   </NIcon>
                 </NButton>
+                {/* <NButton text onClick={()=>state.showUseProject = true}>显示适用项目</NButton> */}
               </NSpace>
             )
           }
@@ -527,7 +528,7 @@ export default defineComponent({
     const initUseAppList = async () => {
       try {
         const appKeys = Object.keys(appKey)
-        const { data } = await sysApplicationPage({ page: 1, rows: 999 })
+        const { data } = await sysApplicationPage({ page: 1, rows: 999, hiddenFlag: true })
         const tempList = data.rows || []
         state.useProjectData = []
         const filter = tempList.filter((next: any) => {
@@ -935,14 +936,19 @@ export default defineComponent({
           preset="dialog"
           showIcon={false}
           title={'适用项目'}
-          style={{ width: '500px' }}
+          style={{ width: '1200px' }}
         >
-          <UseProject
+          {/* <UseProject
             id={state.showUseProjectId}
             useProject={state.useProjectData}
             onClose={() => (state.showUseProject = false)}
             onGetList={getList}
-          />
+          /> */}
+          <MusicPlatform  
+            id={state.showUseProjectId}
+            useProject={state.useProjectData}
+            onClose={() => (state.showUseProject = false)}
+            onGetList={getList} />
         </NModal>
 
         <NModal

+ 6 - 4
src/views/music-library/music-sheet/component/music-sheet-categories-list.tsx

@@ -134,7 +134,8 @@ export default defineComponent({
                 >
                   修改
                 </NButton>
-                <NButton
+                {/* 最多只能添加4层数据 */}
+                {row.currentLevel < 4 && <NButton
                   type="primary"
                   size="small"
                   text
@@ -146,7 +147,8 @@ export default defineComponent({
                   v-auth="musicSheetCategories/save1751239479284203521"
                 >
                   添加子分类
-                </NButton>
+                </NButton>}
+                
               </NSpace>
             )
           }
@@ -206,7 +208,7 @@ export default defineComponent({
           preset="dialog"
           showIcon={false}
           title={state.saveRowData ? '修改分类' : '新增分类'}
-          style={{ width: '400px' }}
+          style={{ width: '600px' }}
         >
           <SaveCategroyDialog
             onGetList={() => {
@@ -218,7 +220,7 @@ export default defineComponent({
             }}
             list={state.dataList}
             saveMode={state.saveMode}
-            actvieRow={state.saveRowData}
+            activeRow={state.saveRowData}
           ></SaveCategroyDialog>
         </NModal>
       </div>

+ 93 - 12
src/views/music-library/music-sheet/modal/music-operationV2.tsx

@@ -39,6 +39,7 @@ import { sysApplicationPage } from '@views/menu-manage/api'
 import { filterPointCategory } from '@views/teaching-manage/unit-test'
 import MusicCreateImg from './music-create-img'
 import MusiceBeatTime from './musiceBeatTime'
+import MusicPlatform from './music-platform'
 
 /**
  * 获取指定元素下一个Note元素
@@ -403,7 +404,15 @@ export default defineComponent({
 
       subjectDisabled: false, // 声部不可用
       instrumentDisabled: false, // 乐器不可用
-      initFSongMap: new Map() as any //初始化的范唱
+      initFSongMap: new Map() as any, //初始化的范唱
+
+      showUseProject: false,
+      showUseProjectId: null as any,
+      useProjectData: [] as any,
+
+      // 修改:修改内容XML(生成图片)、MP3(生成节拍器);其他情况无需生成图片、节拍器
+      isCreateImg: false, // 是否生成图片
+      isBeatTime: false, // 是否生成节拍器
     })
     const gradualData = reactive({
       list: [] as any[],
@@ -564,7 +573,7 @@ export default defineComponent({
           }
 
           // 生成图片
-          if (!state.isAutoSave) {
+          if (!state.isAutoSave && state.isCreateImg) {
             state.isAutoSave = true
             state.productOpen = true
             return
@@ -655,8 +664,19 @@ export default defineComponent({
           } else if (props.type === 'edit') {
             resData = await musicSheetSave({ ...obj, id: props.data.id })
           }
-          beatTimeData.beatTimeOpen = true
-          beatTimeData.musicId = resData.data
+          if(state.isBeatTime) {
+            beatTimeData.beatTimeOpen = true
+            beatTimeData.musicId = resData.data
+            state.showUseProjectId = resData.data
+          } else {
+            state.showUseProjectId = resData.data
+            state.showUseProject = true
+            setTimeout(() => {
+              btnLoading.value = false
+              state.isAutoSave = false
+            }, 100)
+          }
+          
         } catch (e) {
           console.log(e)
           setTimeout(() => {
@@ -667,12 +687,15 @@ export default defineComponent({
       })
     }
     // 合成节拍器的回调
-    function handlerMusiceBeatTimeClose() {
-      if (props.type === 'add') {
-        message.success('添加成功')
-      } else if (props.type === 'edit') {
-        message.success('修改成功')
+    function handlerMusiceBeatTimeClose(val: any) {
+      if(!val) {
+        if (props.type === 'add') {
+          message.success('添加成功')
+        } else if (props.type === 'edit') {
+          message.success('修改成功')
+        }
       }
+      
       emit('getList')
       emit('close')
       setTimeout(() => {
@@ -715,6 +738,7 @@ export default defineComponent({
 
     // 上传XML,初始化音轨 音轨速度 乐器、声部
     const readFileInputEventAsArrayBuffer = (file: any) => {
+      state.isCreateImg = true; // 更换XML
       // 是否是evxml
       const xmlRead = new FileReader()
       xmlRead.onload = (res) => {
@@ -1237,7 +1261,7 @@ export default defineComponent({
       {
         const appKeys = Object.keys(appKey)
 
-        const { data } = await sysApplicationPage({ page: 1, rows: 999, parentId: 0 })
+        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)
@@ -1246,7 +1270,16 @@ export default defineComponent({
           item.label = item.appName
           item.value = item.id
         })
-        state.appData = filter
+        state.useProjectData = filter
+
+        const tempFilter = tempList.filter((next: any) => {
+          return appKeys.includes(next.appKey) && next.appKey !== 'KLX_JG'
+        })
+        tempFilter.forEach((item: any) => {
+          item.label = item.appName
+          item.value = item.id
+        })
+        state.appData = tempFilter
       }
 
       // 获取分类信息
@@ -2068,6 +2101,9 @@ export default defineComponent({
                   disabled={state.previewMode}
                   size={30}
                   v-model:fileList={state.bSongFile}
+                  onUpdate:fileList={() => {
+                    state.isBeatTime = true;
+                  }}
                   tips="仅支持上传.mp3格式文件"
                   listType="image"
                   accept=".mp3"
@@ -2095,6 +2131,9 @@ export default defineComponent({
                         disabled={state.previewMode}
                         size={100}
                         v-model:fileList={item.audioFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true;
+                        }}
                         tips="仅支持上传.mp3格式文件"
                         listType="image"
                         accept=".mp3"
@@ -2121,6 +2160,9 @@ export default defineComponent({
                     disabled={state.previewMode}
                     size={30}
                     v-model:fileList={forms.scoreAudioFileUrl}
+                    onUpdate:fileList={() => {
+                      state.isBeatTime = true;
+                    }}
                     tips="仅支持上传.mp3格式文件"
                     listType="image"
                     accept=".mp3"
@@ -2148,6 +2190,9 @@ export default defineComponent({
                         disabled={state.previewMode}
                         size={100}
                         v-model:fileList={item.solmizationFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true;
+                        }}
                         tips="仅支持上传.mp3格式文件"
                         listType="image"
                         accept=".mp3"
@@ -2169,6 +2214,9 @@ export default defineComponent({
                         disabled={state.previewMode}
                         size={100}
                         v-model:fileList={item.femaleSolmizationFileUrl}
+                        onUpdate:fileList={() => {
+                          state.isBeatTime = true;
+                        }}
                         tips="仅支持上传.mp3格式文件"
                         listType="image"
                         accept=".mp3"
@@ -2264,6 +2312,9 @@ export default defineComponent({
                     disabled={state.previewMode}
                     size={30}
                     v-model:fileList={state.musicSheetAccompanimentUrl}
+                    onUpdate:fileList={() => {
+                      state.isBeatTime = true;
+                    }}
                     tips="仅支持上传.mp3格式文件"
                     listType="image"
                     accept=".mp3"
@@ -2293,6 +2344,9 @@ export default defineComponent({
                     size={30}
                     max={1}
                     v-model:fileList={forms.musicSheetSoundList_all_subject}
+                    onUpdate:fileList={() => {
+                      state.isBeatTime = true;
+                    }}
                     tips="仅支持上传.mp3格式文件"
                     listType="image"
                     accept=".mp3"
@@ -2384,6 +2438,9 @@ export default defineComponent({
                             disabled={state.previewMode}
                             size={100}
                             v-model:fileList={item.audioFileUrl}
+                            onUpdate:fileList={() => {
+                              state.isBeatTime = true;
+                            }}
                             tips="仅支持上传.mp3格式文件"
                             listType="image"
                             accept=".mp3"
@@ -2430,6 +2487,9 @@ export default defineComponent({
                                 disabled={state.previewMode}
                                 size={100}
                                 v-model:fileList={item.audioFileUrl}
+                                onUpdate:fileList={() => {
+                                  state.isBeatTime = true;
+                                }}
                                 tips="仅支持上传.mp3格式文件"
                                 listType="image"
                                 accept=".mp3"
@@ -2584,9 +2644,30 @@ export default defineComponent({
         {beatTimeData.beatTimeOpen && (
           <MusiceBeatTime
             id={beatTimeData.musicId}
-            onClose={handlerMusiceBeatTimeClose}
+            // onClose={handlerMusiceBeatTimeClose}
+            onClose={(val: any)=> {
+              beatTimeData.beatTimeOpen = false
+              if(val) return
+
+              state.showUseProject = true
+            }}
           ></MusiceBeatTime>
         )}
+
+        <NModal
+          blockScroll={true}
+          v-model:show={state.showUseProject}
+          preset="dialog"
+          showIcon={false}
+          title={'适用项目'}
+          style={{ width: '1200px' }}
+        >
+          <MusicPlatform  
+            id={state.showUseProjectId}
+            useProject={state.useProjectData}
+            onClose={handlerMusiceBeatTimeClose}
+            />
+        </NModal>
       </div>
     )
   }

+ 707 - 0
src/views/music-library/music-sheet/modal/music-platform.tsx

@@ -0,0 +1,707 @@
+import { appKey, musicSheetAvailableType, musicSheetPaymentType, musicSheetSourceType, musicSheetType, scoreType } from '@/utils/constant'
+import { getSelectDataFromObj } from '@/utils/objectUtil'
+import { NButton, NCheckbox, NForm, NFormItem, NGi, NGrid, NInputNumber, NSelect, NSpace, NSpin, useMessage } from 'naive-ui'
+import {computed, defineComponent, onMounted, reactive, ref} from 'vue'
+import { musicSheetApplicationExtendCategoryList, musicSheetApplicationExtendTagList, musicSheetApplicationExtendCategoryApplicationExtendInfo, musicSheetApplicationExtendSave } from '../../api'
+import { Console } from 'console'
+export default defineComponent({
+    name: 'music-platform',
+    props: {
+        type: {
+            type: String,
+            default: ''
+        },
+        useProject: {
+          type: Array,
+          required: true,
+          default: []
+        },
+        id: {
+          type: String,
+          required: true,
+          default: null
+        }
+    },
+    emits: ['close', 'getList'],
+    setup(props, { emit }) {
+        // 'KT' | 'GYT' | 'KLX' | 'GYM' | 'KLXT'
+        const message = useMessage()
+        const forms = reactive({
+            gym: {
+                applicationId: '',
+                checked: true,
+                
+                paymentType: 'VIP',
+                isConvertibleScore: false,
+                scoreType: 'STAVE',
+                status: false,
+                sortNo: null
+            },
+            gyt: {
+                applicationId: '',
+                checked: true,
+
+                availableType: 'PLATFORM',
+                isConvertibleScore: false,
+                scoreType: 'STAVE',
+                status: false,
+                sortNo: null
+            },
+            klxt: {
+                applicationId: '',
+                checked: true,
+
+                isConvertibleScore: false,
+                scoreType: 'STAVE',
+                status: false,
+                sortNo: null
+            },
+            klx: {
+                applicationId: '',
+                checked: true,
+
+                musicTagIds: [] as any, // 标签
+                paymentType: ['VIP'] as any, // 收费方式
+                musicPrice: null as any, // 曲目价格
+                availableType: 'PLATFORM',
+                topFlag: false,
+                exquisiteFlag: false,
+                isConvertibleScore: true,
+                scoreType: 'FIRST',
+                status: false,
+                sortNo: null
+            },
+            kt: {
+                applicationId: '',
+                checked: true,
+
+                musicSheetCategoryId: null, // 乐谱教材
+                paymentType: 'VIP',
+                isConvertibleScore: true,
+                scoreType: 'FIRST',
+                status: false,
+                sortNo: null
+            }
+        })
+
+        // 类型是否支持
+        const useProjectStatus = computed(() => {
+            return {
+                GYM: checkHasProject('GYM'),
+                KLX_JG: checkHasProject("KLX_JG"),
+                KLX: checkHasProject("KLX"),
+                KT: checkHasProject("KT"),
+                GYT: checkHasProject("GYT")
+            }
+        })
+        const formsRef = ref()
+        const dataLoading  = ref(false)
+        const musicSheetTagList = ref<any[]>([])
+        const musicSheetCategories = ref<any[]>([])
+        const btnLoading = ref(false)
+
+        // 检测是否存在
+        const checkHasProject = (name: string) => {
+            const useProject = props.useProject || []
+            return useProject.findIndex((item: any) => item.appKey === name) !== -1 ? true : false
+        }
+
+        /** 检测数据 */
+        const checkSubmitForms = () => {
+            let status = false
+            const gym = forms.gym
+            if(gym.checked) {
+                if(!gym.paymentType) {
+                    message.error('请选择收费方式')
+                    return true
+                }
+                if(!gym.isConvertibleScore == null) {
+                    message.error('请选择是否支持转谱')
+                    return true
+                }
+                if(!gym.scoreType) {
+                    message.error('请选择默认谱面')
+                    return true
+                }
+                if(gym.status == null) {
+                    message.error('请选择是否启用')
+                    return true
+                }
+            }
+
+            const gyt = forms.gyt
+            if(gyt.checked) {
+                if(!gyt.availableType) {
+                    message.error('请选择可用途径')
+                    return true
+                }
+                if(!gyt.isConvertibleScore == null) {
+                    message.error('请选择是否支持转谱')
+                    return true
+                }
+                if(!gyt.scoreType) {
+                    message.error('请选择默认谱面')
+                    return true
+                }
+                if(gyt.status == null) {
+                    message.error('请选择是否启用')
+                    return true
+                }
+            }
+
+            const klxt = forms.klxt
+            if(klxt.checked) {
+                if(!klxt.isConvertibleScore == null) {
+                    message.error('请选择是否支持转谱')
+                    return true
+                }
+                if(!klxt.scoreType) {
+                    message.error('请选择默认谱面')
+                    return true
+                }
+                if(klxt.status == null) {
+                    message.error('请选择是否启用')
+                    return true
+                }
+            }
+
+            const klx = forms.klx
+            if(klx.checked) {
+                if(klx.musicTagIds.length <= 0) {
+                    message.error('请选择曲目标签')
+                    return true
+                }
+                if(!klx.paymentType) {
+                    message.error('请选择收费方式')
+                    return true
+                }
+
+                if (!klx.paymentType.includes('CHARGE')) {
+                    klx.musicPrice = 0
+                  } else {
+                    if (klx.musicPrice === null || klx.musicPrice === undefined || klx.musicPrice === '') {
+                      message.error('曲目价格不能为空')
+                      return true
+                    }
+                  }
+                
+                if(!klx.availableType == null) {
+                    message.error('请选择可用途径')
+                    return true
+                }
+
+                if (typeof klx.topFlag !== 'boolean') {
+                    message.error('请选择是否置顶')
+                    return
+                  }
+                  if (typeof klx.exquisiteFlag !== 'boolean') {
+                    message.error('请选择是否精品')
+                    return
+                  }
+
+                if(klx.isConvertibleScore == null) {
+                    message.error('请选择是否支持转谱')
+                    return true
+                }
+                if(!klx.scoreType) {
+                    message.error('请选择默认谱面')
+                    return true
+                }
+                if(klx.status == null) {
+                    message.error('请选择是否启用')
+                    return true
+                }
+            }
+
+            const kt = forms.kt
+            if(kt.checked) {
+                if(!kt.musicSheetCategoryId) {
+                    message.error('请选择乐谱教材')
+                    return true
+                }
+                if(!kt.paymentType) {
+                    message.error('请选择收费方式')
+                    return true
+                }
+                if(!kt.isConvertibleScore == null) {
+                    message.error('请选择是否支持转谱')
+                    return true
+                }
+                if(!kt.scoreType) {
+                    message.error('请选择默认谱面')
+                    return true
+                }
+                if(kt.status == null) {
+                    message.error('请选择是否启用')
+                    return true
+                }
+            }
+
+            return status
+        }
+
+        /** 获取参数 */
+        const getSubmitParams = () => {
+            const params: any = []
+            const useApplicationIds: any = []
+            if(forms.gym.checked) {
+                params.push({
+                    ...forms.gym
+                })
+                useApplicationIds.push(forms.gym.applicationId)
+            }
+            if(forms.gyt.checked) {
+                params.push({
+                    ...forms.gyt
+                })
+                useApplicationIds.push(forms.gyt.applicationId)
+            }
+            if(forms.klxt.checked) {
+                params.push({
+                    ...forms.klxt
+                })
+                useApplicationIds.push(forms.klxt.applicationId)
+            }
+            if(forms.klx.checked) {
+                params.push({
+                    ...forms.klx,
+                    musicTagIds: forms.klx.musicTagIds.join(','),
+                    paymentType: forms.klx.paymentType.join(',')
+                })
+                useApplicationIds.push(forms.klx.applicationId)
+            }
+            if(forms.kt.checked) {
+                params.push({
+                    ...forms.kt
+                })
+                useApplicationIds.push(forms.kt.applicationId)
+            }
+            return {
+                musicSheetId: props.id,
+                applicationExtends: params || {},
+                useApplicationIds: useApplicationIds.join(',') || ''
+            }
+        }
+
+        // 提交数据
+        const onSubmit = async () => {
+            try {
+                if(checkSubmitForms()) return
+                const params = getSubmitParams()
+
+                await musicSheetApplicationExtendSave(params)
+                message.success('保存成功')
+                emit('close')
+                emit('getList')
+            } catch {}
+        }
+
+        /** 酷乐秀 加载曲目标签 */
+        const getMusicTags = async () => {
+            try {
+                const useProject = props.useProject || []
+                const item: any = useProject.find((item: any) => item.appKey === 'KLX')
+                if(!item) return
+                const { data } = await musicSheetApplicationExtendTagList({ 
+                    applicationId: item.id 
+                })
+                if (data && data.length > 0) {
+                data.forEach((item: any) => {
+                    musicSheetTagList.value.push({
+                        ...item,
+                        label: item.name,
+                        value: item.id
+                    })
+                })
+                }
+            } catch (err) {}
+        }
+
+        /** 课堂乐器 乐谱教材 */
+        const getMusicSheetCategories = async () => {
+            //加载曲目分类列表
+            const useProject = props.useProject || []
+            const item: any = useProject.find((item: any) => item.appKey === 'KT')
+            if(!item) return
+            const categoryRes = await musicSheetApplicationExtendCategoryList({
+            applicationIds: item.id
+          })
+          if (categoryRes.data && categoryRes.data.length > 0) {
+            musicSheetCategories.value = categoryRes.data[0].musicSheetCategories
+          }
+        }
+
+        const getDetail = async () => {
+            try {
+                // 加载已经配置的APP
+                const { data } = await musicSheetApplicationExtendCategoryApplicationExtendInfo({ musicSheetId: props.id })
+                const result = data || []
+                result.forEach((item: any) => {
+                    if(item.appKey === 'GYM') {
+                        forms.gym.checked = true;
+
+                        forms.gym.paymentType = item.paymentType
+                        forms.gym.isConvertibleScore = item.isConvertibleScore
+                        forms.gym.scoreType = item.scoreType
+                        forms.gym.status = item.status
+                        forms.gym.sortNo = item.sortNo
+                    } else if(item.appKey === 'GYT') {
+                        forms.gyt.checked = true
+
+                        forms.gyt.availableType = item.availableType
+                        forms.gyt.isConvertibleScore = item.isConvertibleScore
+                        forms.gyt.scoreType = item.scoreType
+                        forms.gyt.status = item.status
+                        forms.gyt.sortNo = item.sortNo
+                    } else if(item.appKey === 'KLX_JG') {
+                        forms.klxt.checked = true
+
+                        forms.klxt.isConvertibleScore =  false
+                        forms.klxt.scoreType =  'STAVE'
+                        forms.klxt.status =  false
+                        forms.klxt.sortNo =  null
+                    } else if(item.appKey === 'KLX') {
+                        forms.klx.checked = true
+
+                        forms.klx.musicTagIds = item.musicTagIds ? item.musicTagIds.split(',') : []  // 标签
+                        forms.klx.paymentType = item.paymentType ? item.paymentType.split(',') : []  // 收费方式
+                        forms.klx.musicPrice = item.musicPrice // 曲目价格
+                        forms.klx.availableType = item.availableType
+                        forms.klx.topFlag = item.topFlag
+                        forms.klx.exquisiteFlag = item.exquisiteFlag
+                        forms.klx.isConvertibleScore = item.isConvertibleScore
+                        forms.klx.scoreType = item.scoreType
+                        forms.klx.status = item.status
+                        forms.klx.sortNo = item.sortNo
+                    } else if(item.appKey === 'KT') {
+                        forms.kt.checked = true
+
+                        forms.kt.musicSheetCategoryId = item.musicSheetCategoryId // 乐谱教材
+                        forms.kt.paymentType = item.paymentType
+                        forms.kt.isConvertibleScore = item.isConvertibleScore
+                        forms.kt.scoreType = item.scoreType
+                        forms.kt.status = item.status
+                        forms.kt.sortNo = item.sortNo
+                    }
+                })
+            } catch {
+
+            }
+        }
+
+        onMounted(async () => {
+            dataLoading.value = true
+            if(props.type !== 'add') {
+                // 默认重置为false
+                forms.gym.checked = false
+                forms.gyt.checked = false
+                forms.klxt.checked = false
+                forms.klx.checked = false
+                forms.kt.checked = false
+            }
+            // 初始话应用编号
+            const useProject = props.useProject || []
+            useProject.forEach((item: any) => {
+                if(item.appKey === 'GYM') {
+                    forms.gym.applicationId = item.id
+                } else if(item.appKey === 'KLX_JG') {
+                    forms.klxt.applicationId = item.id
+                } else if(item.appKey === 'KLX') {
+                    forms.klx.applicationId = item.id
+                } else if(item.appKey === 'KT') {
+                    forms.kt.applicationId = item.id
+                } else if(item.appKey === 'GYT') {
+                    forms.gyt.applicationId = item.id
+                } 
+            })
+            await getMusicTags()
+            await getMusicSheetCategories()
+            await getDetail()
+            dataLoading.value = false
+        })
+        
+        return () => <NSpin show={dataLoading.value}>
+            <NForm
+            model={forms}
+            ref={formsRef}
+            label-placement="top"
+            label-width="85"
+            >
+            {useProjectStatus.value.GYM && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
+                <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
+                    <NCheckbox v-model:checked={forms.gym.checked}>管乐迷</NCheckbox>
+                </NGi>
+                <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
+                    <NGrid cols={6} xGap={12}>
+                        <NGi>
+                        <NFormItem label='收费方式' path="paymentType">
+                            <NSelect v-model:value={forms.gym.paymentType} clearable options={[
+                                { label: '免费', value: 'FREE' },
+                                { label: '收费', value: 'VIP' }]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore">
+                            <NSelect v-model:value={forms.gym.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType">
+                            <NSelect v-model:value={forms.gym.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status">
+                            <NSelect v-model:value={forms.gym.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber min={0} max={9999} v-model:value={forms.gym.sortNo} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                    </NGrid>
+                </NGi>
+            </NGrid>}
+
+            {useProjectStatus.value.GYT && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
+                <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
+                    <NCheckbox v-model:checked={forms.gyt.checked}>管乐团</NCheckbox>
+                </NGi>
+                <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
+                    <NGrid cols={6} xGap={12}>
+                        <NGi>
+                        <NFormItem label='可以途径' path="availableType">
+                            <NSelect v-model:value={forms.gyt.availableType} clearable options={[
+                                {
+                                    label: '学校',
+                                    value: 'ORG'
+                                },
+                                {
+                                    label: '平台',
+                                    value: 'PLATFORM'
+                                }
+                                ]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore">
+                            <NSelect v-model:value={forms.gyt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType">
+                            <NSelect v-model:value={forms.gyt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status">
+                            <NSelect v-model:value={forms.gyt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber min={0} max={9999} v-model:value={forms.gyt.sortNo} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                    </NGrid>
+                </NGi>
+            </NGrid>}
+
+            {useProjectStatus.value.KLX_JG && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
+                <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
+                    <NCheckbox v-model:checked={forms.klxt.checked}>酷乐秀机构</NCheckbox>
+                </NGi>
+                <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
+                    <NGrid cols={6} xGap={12}>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore">
+                            <NSelect v-model:value={forms.klxt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType">
+                            <NSelect v-model:value={forms.klxt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status">
+                            <NSelect v-model:value={forms.klxt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber min={0} max={9999} v-model:value={forms.klxt.sortNo} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                    </NGrid>
+                </NGi>
+            </NGrid>}
+
+            {useProjectStatus.value.KLX && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
+                <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
+                    <NCheckbox v-model:checked={forms.klx.checked}>酷乐秀平台</NCheckbox>
+                </NGi>
+                <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
+                    <NGrid cols={6} xGap={12}>
+                        <NGi>
+                        <NFormItem label='曲目标签'>
+                            <NSelect v-model:value={forms.klx.musicTagIds} multiple maxTagCount={1} clearable options={musicSheetTagList.value} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='收费方式' path="paymentType">
+                            <NSelect v-model:value={forms.klx.paymentType} multiple maxTagCount={1} clearable options={getSelectDataFromObj(musicSheetPaymentType)}
+                                onUpdate:value={(v: any) => {
+                                    forms.klx.paymentType = v
+                                    const free = 'FREE'
+                                    if (forms.klx.paymentType[forms.klx.paymentType.length - 1] == free) {
+                                    forms.klx.paymentType = [free]
+                                    } else if (forms.klx.paymentType.length > 1 && forms.klx.paymentType.includes(free)) {
+                                    forms.klx.paymentType.splice(forms.klx.paymentType.indexOf(free), 1)
+                                    }
+                                    if (!forms.klx.paymentType.includes('CHARGE')) {
+                                        forms.klx.musicPrice = 0
+                                    }
+                                }} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='曲目价格' path="musicPrice">
+                            <NInputNumber disabled={!forms.klx.paymentType?.includes('CHARGE')} precision={2    } min={0} max={9999} v-model:value={forms.klx.musicPrice} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='可用途径' path="availableType">
+                            <NSelect v-model:value={forms.klx.availableType} clearable options={getSelectDataFromObj(musicSheetAvailableType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否置顶' path="topFlag">
+                            <NSelect v-model:value={forms.klx.topFlag} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否精品' path="exquisiteFlag">
+                            <NSelect v-model:value={forms.klx.exquisiteFlag} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore">
+                            <NSelect v-model:value={forms.klx.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType">
+                            <NSelect v-model:value={forms.klx.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status">
+                            <NSelect v-model:value={forms.klx.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber min={0} max={9999} v-model:value={forms.klx.sortNo} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                    </NGrid>
+                </NGi>
+            </NGrid>}
+
+            {useProjectStatus.value.KT && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
+                <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
+                    <NCheckbox v-model:checked={forms.kt.checked}>音乐数字课堂</NCheckbox>
+                </NGi>
+                <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
+                    <NGrid cols={6} xGap={12}>
+                        <NGi>
+                        <NFormItem label='乐谱教材' path="musicSheetCategoryId">
+                            <NSelect v-model:value={forms.kt.musicSheetCategoryId} clearable options={musicSheetCategories.value} labelField='name' valueField='id' />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='收费方式' path="paymentType">
+                            <NSelect v-model:value={forms.kt.paymentType} clearable options={[
+                                { label: '免费', value: 'FREE' },
+                                { label: '会员', value: 'VIP' }]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore">
+                            <NSelect v-model:value={forms.kt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType">
+                            <NSelect v-model:value={forms.kt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status">
+                            <NSelect v-model:value={forms.kt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber min={0} max={9999} v-model:value={forms.kt.sortNo} showButton={false} />
+                        </NFormItem>
+                        </NGi>
+                    </NGrid>
+                </NGi>
+            </NGrid>}
+
+            <NSpace justify="end" style={'margin-top: 10px'}>
+            <NButton type="default" onClick={() => emit('close', true)}>
+                取消
+            </NButton>
+            <NButton
+                type="primary"
+                onClick={() => onSubmit()}
+                loading={btnLoading.value}
+                disabled={btnLoading.value}
+            >
+                确认
+            </NButton>
+            </NSpace>
+        </NForm>
+        </NSpin>
+    },
+})

+ 1 - 1
src/views/music-library/music-sheet/modal/musiceBeatTime/index.tsx

@@ -42,7 +42,7 @@ export default defineComponent({
       }catch (err){
         console.log('🚀 ~ 音频合成失败', err)
         message.error('节拍器生成失败')
-        emit("close")
+        emit("close", true)
       }
     }
     const iframeShow = ref(true)

+ 12 - 0
src/views/music-library/music-sheet/modal/save-categroy-dialog.module.less

@@ -0,0 +1,12 @@
+.instrumentSave {
+    background: #fff;
+    padding-top: 12px;
+  
+    .updateFile {
+      :global {
+        img {
+          object-fit: cover !important;
+        }
+      }
+    }
+  }

+ 44 - 7
src/views/music-library/music-sheet/modal/save-categroy-dialog.tsx

@@ -2,10 +2,12 @@ import {NButton, NCascader, NForm, NFormItem, NInput, NSpace, useMessage} from '
 import {defineComponent, onMounted, reactive, ref} from 'vue'
 import {filterPointCategory} from '@/views/teaching-manage/unit-test'
 import {musicSheetCategoriesSave, musicSheetCategoriesUpdate} from "@views/music-library/api";
+import UploadFile from '@/components/upload-file';
+import styles from './save-categroy-dialog.module.less'
 
 export default defineComponent({
   emits: ['close', 'getList'],
-  props: ['actvieRow', 'saveMode', 'list'],
+  props: ['activeRow', 'saveMode', 'list'],
   name: 'save-categroy-dialog',
   setup(props, {emit}) {
     const message = useMessage()
@@ -17,11 +19,18 @@ export default defineComponent({
     const state = reactive({
       loading: false,
       dataList: [] as any,
-      btnLoading: false
+      btnLoading: false,
+      options: {
+        enlarge: 2,
+        autoCropWidth: 350, //默认生成截图框宽度
+        autoCropHeight: 140 //默认生成截图框高度
+      },
+      messageTip: '请上传尺寸为700*280大小5M以内的JPG、PNG图片'
     })
     const forms = reactive({
       id: '',
       name: '',
+      coverImg: '',
       enable: true,
       parentId: '0'
     } as any)
@@ -51,19 +60,24 @@ export default defineComponent({
     onMounted(() => {
       if (props.saveMode === 'add') {
         // 添加子分类
-        if (props.actvieRow && props.actvieRow.id) {
-          forms.parentId = props?.actvieRow.id + ''
+        if (props.activeRow && props.activeRow.id) {
+          forms.parentId = props?.activeRow.id + ''
         }
       } else {
-        for (let key in props?.actvieRow) {
-          forms[key] = props?.actvieRow[key]
+        for (let key in props?.activeRow) {
+          forms[key] = props?.activeRow[key]
+        }
+        if(props?.activeRow.currentLevel > 1) {
+          state.options.autoCropWidth = 210
+          state.options.autoCropHeight = 268
+          state.messageTip = '请上传尺寸为210*268大小5M以内的JPG、PNG图片'
         }
       }
     })
     return () => (
         <div>
           <NForm ref={formRef} model={forms}>
-            {props.saveMode === 'add' && props.actvieRow && (
+            {props.saveMode === 'add' && props.activeRow && (
                 <NFormItem label="父级分类" path="parentId">
                   <NCascader
                       placeholder="请选择父级分类"
@@ -98,6 +112,29 @@ export default defineComponent({
                   clearable
               ></NInput>
             </NFormItem>
+
+            <NFormItem
+            label="封面图"
+            path="img"
+            rule={[
+              {
+                required: true,
+                message: '请上传封面图',
+                trigger: ['input', 'blur']
+              }
+            ]}
+          >
+            <UploadFile
+              v-model:fileList={forms.coverImg}
+              accept=".jpg,.jpeg,.png"
+              cropper
+              size={5}
+              class={styles.updateFile}
+              bucketName="news-info"
+              options={state.options}
+              tips={state.messageTip}
+            />
+          </NFormItem>
           </NForm>
           <NSpace justify="end">
             <NButton type="default" onClick={() => emit('close')}>

+ 1 - 1
src/views/music-library/project-music-sheet/index.tsx

@@ -14,7 +14,7 @@ export default defineComponent({
   name: 'project-music-sheet',
   setup() {
     const state = reactive({
-      tabName: 'KT' as 'KT' | 'GYT' | 'KLX' | 'GYM',
+      tabName: 'KLX' as 'KT' | 'GYT' | 'KLX' | 'GYM' | 'KLXT',
       appKeyList: [] as any,
       appNameList: [] as any
     })