Selaa lähdekoodia

Merge branch 'iteration-20240827' into online

lex-xin 6 kuukautta sitten
vanhempi
commit
0635ca4678
26 muutettua tiedostoa jossa 3608 lisäystä ja 310 poistoa
  1. 0 2
      components.d.ts
  2. 1 0
      src/utils/constant.ts
  3. 12 5
      src/views/music-library/music-sheet/component/music-list.tsx
  4. 6 4
      src/views/music-library/music-sheet/component/music-sheet-categories-list.tsx
  5. 94 13
      src/views/music-library/music-sheet/modal/music-operationV2.tsx
  6. 708 0
      src/views/music-library/music-sheet/modal/music-platform.tsx
  7. 1 1
      src/views/music-library/music-sheet/modal/musiceBeatTime/index.tsx
  8. 12 0
      src/views/music-library/music-sheet/modal/save-categroy-dialog.module.less
  9. 44 7
      src/views/music-library/music-sheet/modal/save-categroy-dialog.tsx
  10. 12 3
      src/views/music-library/project-music-sheet/index.tsx
  11. 181 81
      src/views/music-library/project-music-sheet/module/gym/addMusic.tsx
  12. 39 13
      src/views/music-library/project-music-sheet/module/gym/music-sheet-gym.tsx
  13. 29 7
      src/views/music-library/project-music-sheet/module/gym/updateMusic.tsx
  14. 143 46
      src/views/music-library/project-music-sheet/module/gyt/addMusic.tsx
  15. 39 13
      src/views/music-library/project-music-sheet/module/gyt/music-sheet-gyt.tsx
  16. 27 5
      src/views/music-library/project-music-sheet/module/gyt/updateMusic.tsx
  17. 168 76
      src/views/music-library/project-music-sheet/module/klx/addMusic.tsx
  18. 37 13
      src/views/music-library/project-music-sheet/module/klx/music-sheet-klx.tsx
  19. 25 3
      src/views/music-library/project-music-sheet/module/klx/updateMusic.tsx
  20. 898 0
      src/views/music-library/project-music-sheet/module/klx_jg/addMusic.tsx
  21. 773 0
      src/views/music-library/project-music-sheet/module/klx_jg/music-sheet-klx_jg.tsx
  22. 197 0
      src/views/music-library/project-music-sheet/module/klx_jg/updateMusic.tsx
  23. 97 0
      src/views/music-library/project-music-sheet/module/kt/addMusic.tsx
  24. 39 13
      src/views/music-library/project-music-sheet/module/kt/music-sheet-kt.tsx
  25. 25 4
      src/views/music-library/project-music-sheet/module/kt/updateMusic.tsx
  26. 1 1
      vite.config.ts

+ 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']

+ 1 - 0
src/utils/constant.ts

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

+ 12 - 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,8 +161,8 @@ export default defineComponent({
         },
         {
           title: '作者属性',
-          minWidth: '250px',
           key: 'sourceType',
+          minWidth: '120px',
           render(row: any) {
             return (
               <NDescriptions labelPlacement="left" column={1}>
@@ -208,6 +209,7 @@ export default defineComponent({
                     </svg>
                   </NIcon>
                 </NButton>
+                {/* <NButton text onClick={()=>state.showUseProject = true}>显示适用项目</NButton> */}
               </NSpace>
             )
           }
@@ -527,7 +529,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 +937,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>

+ 94 - 13
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元素
@@ -341,7 +342,7 @@ export default defineComponent({
       musicSheetSoundList_YZ: [] as any, // 演奏演奏
       musicSheetSoundList_all_subject: null, // 全部声部原音
       // musicSheetCategoriesId: null,
-      status: false,
+      status: true,
       musicSheetType: 'CONCERT', // 曲目类型
       sourceType: 'PLATFORM' as any, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
       // userId: null, // 所属人
@@ -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[],
@@ -568,7 +577,7 @@ export default defineComponent({
           }
 
           // 生成图片
-          if (!state.isAutoSave) {
+          if (!state.isAutoSave && state.isCreateImg) {
             state.isAutoSave = true
             state.productOpen = true
             return
@@ -669,8 +678,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(() => {
@@ -681,12 +701,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(() => {
@@ -729,6 +752,7 @@ export default defineComponent({
 
     // 上传XML,初始化音轨 音轨速度 乐器、声部
     const readFileInputEventAsArrayBuffer = (file: any) => {
+      state.isCreateImg = true; // 更换XML
       // 是否是evxml
       const xmlRead = new FileReader()
       xmlRead.onload = (res) => {
@@ -1254,7 +1278,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)
@@ -1263,7 +1287,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
       }
 
       // 获取分类信息
@@ -2091,6 +2124,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"
@@ -2118,6 +2154,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"
@@ -2144,6 +2183,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"
@@ -2171,6 +2213,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"
@@ -2192,6 +2237,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"
@@ -2287,6 +2335,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"
@@ -2316,6 +2367,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"
@@ -2407,6 +2461,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"
@@ -2453,6 +2510,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"
@@ -2607,9 +2667,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>
     )
   }

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

@@ -0,0 +1,708 @@
+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
+                }
+                console.log(gym.isConvertibleScore, 'gym.isConvertibleScore')
+                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 || klx.paymentType.length <= 0) {
+                    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 true
+                  }
+                  if (typeof klx.exquisiteFlag !== 'boolean') {
+                    message.error('请选择是否精品')
+                    return true
+                  }
+
+                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 =  item.isConvertibleScore
+                        forms.klxt.scoreType =  item.scoreType
+                        forms.klxt.status =  item.status
+                        forms.klxt.sortNo =  item.sortNo
+                    } 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" required>
+                            <NSelect v-model:value={forms.gym.paymentType} clearable options={[
+                                { label: '免费', value: 'FREE' },
+                                { label: '收费', value: 'VIP' }]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore" required>
+                            <NSelect v-model:value={forms.gym.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType" required>
+                            <NSelect v-model:value={forms.gym.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status" required>
+                            <NSelect v-model:value={forms.gym.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber precision={0} min={0} max={999999999} 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" required>
+                            <NSelect v-model:value={forms.gyt.availableType} clearable options={[
+                                {
+                                    label: '学校',
+                                    value: 'ORG'
+                                },
+                                {
+                                    label: '平台',
+                                    value: 'PLATFORM'
+                                }
+                                ]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore" required>
+                            <NSelect v-model:value={forms.gyt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType" required>
+                            <NSelect v-model:value={forms.gyt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status" required>
+                            <NSelect v-model:value={forms.gyt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber precision={0} min={0} max={999999999} 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" required>
+                            <NSelect v-model:value={forms.klxt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType" required>
+                            <NSelect v-model:value={forms.klxt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status" required>
+                            <NSelect v-model:value={forms.klxt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber precision={0} min={0} max={999999999} 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='曲目标签' required>
+                            <NSelect v-model:value={forms.klx.musicTagIds} multiple maxTagCount={1} clearable options={musicSheetTagList.value} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='收费方式' path="paymentType" required>
+                            <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" required>
+                            <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" required>
+                            <NSelect v-model:value={forms.klx.topFlag} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否精品' path="exquisiteFlag" required>
+                            <NSelect v-model:value={forms.klx.exquisiteFlag} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore" required>
+                            <NSelect v-model:value={forms.klx.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType" required>
+                            <NSelect v-model:value={forms.klx.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status" required>
+                            <NSelect v-model:value={forms.klx.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber precision={0} min={0} max={999999999} 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" required>
+                            <NSelect v-model:value={forms.kt.musicSheetCategoryId} clearable options={musicSheetCategories.value} labelField='name' valueField='id' />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='收费方式' path="paymentType" required>
+                            <NSelect v-model:value={forms.kt.paymentType} clearable options={[
+                                { label: '免费', value: 'FREE' },
+                                { label: '会员', value: 'VIP' }]} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否支持转谱' path="isConvertibleScore" required>
+                            <NSelect v-model:value={forms.kt.isConvertibleScore} clearable options={[
+                                { label: '是', value: true },
+                                { label: '否', value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='默认谱面' path="scoreType" required>
+                            <NSelect v-model:value={forms.kt.scoreType} options={getSelectDataFromObj(scoreType)} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='是否启用' path="status" required>
+                            <NSelect v-model:value={forms.kt.status} options={[
+                                {  label: '是',  value: true },
+                                { label: '否',  value: false }
+                                ] as any} />
+                        </NFormItem>
+                        </NGi>
+                        <NGi>
+                        <NFormItem label='排序' path="sortNo">
+                            <NInputNumber precision={0} min={0} max={999999999} 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="coverImg"
+            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')}>

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

@@ -8,13 +8,14 @@ import MusicSheetKt from '@views/music-library/project-music-sheet/module/kt/mus
 import MusicSheetGym from '@views/music-library/project-music-sheet/module/gym/music-sheet-gym'
 import MusicSheetGyt from '@views/music-library/project-music-sheet/module/gyt/music-sheet-gyt'
 import MusicSheetKlx from '@views/music-library/project-music-sheet/module/klx/music-sheet-klx'
+import MusicSheetKlxJG from '@views/music-library/project-music-sheet/module/klx_jg/music-sheet-klx_jg'
 import { disAuthCheckStatus } from '@/utils/directive/authDirective'
 
 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' | 'KLX_JG',
       appKeyList: [] as any,
       appNameList: [] as any
     })
@@ -33,7 +34,7 @@ export default defineComponent({
     onMounted(async () => {
       // 获取应用APP信息
       const appKeys = Object.keys(appKey)
-      const { data } = await sysApplicationPage({ page: 1, rows: 99, parentId: 0 })
+      const { data } = await sysApplicationPage({ page: 1, rows: 99, parentId: 0, hiddenFlag: true  })
       const tempList = data.rows || []
       tempList.forEach((next: any) => {
         if (appKeys.includes(next.appKey)) {
@@ -44,9 +45,11 @@ export default defineComponent({
 
       if (disAuthCheckStatus('musicSheet/pageByApplication1751225218734489601')) {
         state.tabName = 'KLX'
+      } else if (disAuthCheckStatus('musicSheet/pageByApplication1828630545792307201')) {
+        state.tabName = 'KLX_JG'
       } else if (disAuthCheckStatus('musicSheet/pageByApplication1751225314930851842')) {
         state.tabName = 'GYM'
-      } else if (disAuthCheckStatus('musicSheet/pageByApplication1751225386909302786')) {
+      }  else if (disAuthCheckStatus('musicSheet/pageByApplication1751225386909302786')) {
         state.tabName = 'KT'
       } else if (disAuthCheckStatus('musicSheet/pageByApplication1751225483038556162')) {
         state.tabName = 'GYT'
@@ -72,6 +75,12 @@ export default defineComponent({
                 </NTabPane>
               )}
 
+              {disAuthCheckStatus('musicSheet/pageByApplication1828630545792307201') && (
+                <NTabPane name={'KLX_JG'} tab={'酷乐秀机构'}>
+                  <MusicSheetKlxJG appKey={'KLX_JG'} />
+                </NTabPane>
+              )}
+
               {disAuthCheckStatus('musicSheet/pageByApplication1751225314930851842') && (
                 <NTabPane name={'GYM'} tab={'管乐迷'}>
                   <MusicSheetGym appKey={'GYM'} />

+ 181 - 81
src/views/music-library/project-music-sheet/module/gym/addMusic.tsx

@@ -76,9 +76,10 @@ export default defineComponent({
       selectRowData: [] as any, // 选择的数据列表
       musicSheetCategories: [] as any,
       startSortNum: null as any, // 排序起始值
-      projectMusicCategoryId: null as any, // 曲目分类ID
+      // projectMusicCategoryId: null as any, // 曲目分类ID
       globalPaymentType: null as any, //收费方式
       isConvertibleScore: null as any, //是否支持转简谱
+      status: false, // 是否启用
       scoreType: null as any, //默认谱面
 
       userIdDisable: true,
@@ -196,10 +197,10 @@ export default defineComponent({
       const params = [] as any[]
       for (let i = 0; i < state.selectRowData.length; i++) {
         const item = state.selectRowData[i]
-        if (!item.projectMusicCategoryId) {
-          message.error('曲目分类不能为空')
-          return
-        }
+        // if (!item.projectMusicCategoryId) {
+        //   message.error('曲目分类不能为空')
+        //   return
+        // }
         if (item.scoreType == null) {
           message.error('默认谱面不能为空')
           return
@@ -208,14 +209,18 @@ export default defineComponent({
           message.error('是否支持转谱不能为空')
           return
         }
-        if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
-          message.error('排序号不能为空')
+        if(item.status == null) {
+          message.error('是否启用不能为空')
           return
         }
+        // if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
+        //   message.error('排序号不能为空')
+        //   return
+        // }
         params.push({
           ...item,
           musicSheetId: item.id,
-          musicSheetCategoryId: item.projectMusicCategoryId,
+          // musicSheetCategoryId: item.projectMusicCategoryId,
           applicationId: props.appId,
           id: null
         })
@@ -258,6 +263,10 @@ export default defineComponent({
         title: '音乐人',
         key: 'composer'
       },
+      {
+        title: '曲目分类',
+        key: 'musicCategoryName'
+      },
       // {
       //   title: '谱面渲染',
       //   key: 'musicSheetType',
@@ -279,7 +288,6 @@ export default defineComponent({
       {
         title: '所属人',
         key: 'userName',
-        width: 200,
         render: (row: any) => {
           return <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
         }
@@ -293,18 +301,97 @@ export default defineComponent({
     const stepColumns = (): DataTableColumns => {
       const field = deepClone(columnsField)
       field.splice(0, 1)
+      // field.push({
+      //   title(column: any) {
+      //     return (
+      //       <NSpace>
+      //         曲目分类
+      //         <NButton
+      //           type="primary"
+      //           size="small"
+      //           text
+      //           onClick={() => {
+      //             dialogs.create({
+      //               title: '请选择曲目分类',
+      //               showIcon: false,
+      //               content: () => {
+      //                 return h(
+      //                   'div',
+      //                   {
+      //                     class: 'flex flex-col justify-center items-center text-14px'
+      //                   },
+      //                   [
+      //                     // icon
+      //                     h(NCascader, {
+      //                       onUpdateValue(v) {
+      //                         state.projectMusicCategoryId = v
+      //                       },
+      //                       valueField: 'id',
+      //                       labelField: 'name',
+      //                       childrenField: 'children',
+      //                       filterable: true,
+      //                       options: state.musicSheetCategories
+      //                     })
+      //                   ]
+      //                 )
+      //               },
+      //               positiveText: '确定',
+      //               negativeText: '取消',
+      //               onPositiveClick: () => {
+      //                 for (let i = 0; i < state.selectRowData.length; i++) {
+      //                   const item = state.selectRowData[i]
+      //                   item.projectMusicCategoryId = state.projectMusicCategoryId
+      //                 }
+      //               }
+      //             })
+      //           }}
+      //         >
+      //           <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+      //             <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+      //               <path d="M2 26h28v2H2z" fill="currentColor"></path>
+      //               <path
+      //                 d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+      //                 fill="currentColor"
+      //               ></path>
+      //             </svg>
+      //           </NIcon>
+      //         </NButton>
+      //       </NSpace>
+      //     )
+      //   },
+      //   key: 'projectMusicCategoryId',
+      //   width: 200,
+      //   render: (row: any) => {
+      //     // })
+      //     return (
+      //       <NCascader
+      //         valueField="id"
+      //         labelField="name"
+      //         children-field="children"
+      //         placeholder="请选择曲目分类"
+      //         value={row.projectMusicCategoryId}
+      //         options={state.musicSheetCategories}
+      //         onUpdateValue={(value: any) => {
+      //           row.projectMusicCategoryId = value
+      //         }}
+      //         filterable
+      //         clearable
+      //       />
+      //     )
+      //   }
+      // })
       field.push({
         title(column: any) {
           return (
             <NSpace>
-              曲目分类
+              收费方式
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '请选择曲目分类',
+                    title: '请选择收费方式',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -313,16 +400,21 @@ export default defineComponent({
                           class: 'flex flex-col justify-center items-center text-14px'
                         },
                         [
-                          // icon
-                          h(NCascader, {
+                          h(NSelect, {
                             onUpdateValue(v) {
-                              state.projectMusicCategoryId = v
+                              state.globalPaymentType = v
                             },
-                            valueField: 'id',
-                            labelField: 'name',
-                            childrenField: 'children',
-                            filterable: true,
-                            options: state.musicSheetCategories
+                            clearable: true,
+                            options: [
+                              {
+                                label: '免费',
+                                value: 'FREE'
+                              },
+                              {
+                                label: '收费',
+                                value: 'VIP'
+                              }
+                            ]
                           })
                         ]
                       )
@@ -332,7 +424,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.projectMusicCategoryId = state.projectMusicCategoryId
+                        item.paymentType = state.globalPaymentType
                       }
                     }
                   })
@@ -351,23 +443,27 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'projectMusicCategoryId',
+        key: 'paymentType',
         width: 200,
         render: (row: any) => {
-          // })
           return (
-            <NCascader
-              valueField="id"
-              labelField="name"
-              children-field="children"
-              placeholder="请选择曲目分类"
-              value={row.projectMusicCategoryId}
-              options={state.musicSheetCategories}
-              onUpdateValue={(value: any) => {
-                row.projectMusicCategoryId = value
-              }}
-              filterable
+            <NSelect
+              placeholder="请选择收费方式"
+              value={row.paymentType}
+              options={[
+                {
+                  label: '免费',
+                  value: 'FREE'
+                },
+                {
+                  label: '收费',
+                  value: 'VIP'
+                }
+              ]}
               clearable
+              onUpdateValue={(value) => {
+                row['paymentType'] = value
+              }}
             />
           )
         }
@@ -376,14 +472,14 @@ export default defineComponent({
         title(column: any) {
           return (
             <NSpace>
-              收费方式
+              默认谱面
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '请选择收费方式',
+                    title: '请选择默认谱面',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -392,21 +488,12 @@ export default defineComponent({
                           class: 'flex flex-col justify-center items-center text-14px'
                         },
                         [
+                          // icon
                           h(NSelect, {
                             onUpdateValue(v) {
-                              state.globalPaymentType = v
+                              state.scoreType = v
                             },
-                            clearable: true,
-                            options: [
-                              {
-                                label: '免费',
-                                value: 'FREE'
-                              },
-                              {
-                                label: '收费',
-                                value: 'VIP'
-                              }
-                            ]
+                            options: getSelectDataFromObj(scoreType)
                           })
                         ]
                       )
@@ -416,7 +503,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.paymentType = state.globalPaymentType
+                        item.scoreType = state.scoreType
                       }
                     }
                   })
@@ -435,27 +522,19 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'paymentType',
+        key: 'scoreType',
         width: 200,
         render: (row: any) => {
+          // })
           return (
             <NSelect
-              placeholder="请选择收费方式"
-              value={row.paymentType}
-              options={[
-                {
-                  label: '免费',
-                  value: 'FREE'
-                },
-                {
-                  label: '收费',
-                  value: 'VIP'
-                }
-              ]}
-              clearable
-              onUpdateValue={(value) => {
-                row['paymentType'] = value
+              placeholder="请选择默认谱面"
+              value={row.scoreType}
+              options={getSelectDataFromObj(scoreType)}
+              onUpdateValue={(value: any) => {
+                row.scoreType = value
               }}
+              clearable
             />
           )
         }
@@ -464,14 +543,14 @@ export default defineComponent({
         title(column: any) {
           return (
             <NSpace>
-              默认谱面
+              是否支持转谱
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '请选择默认谱面',
+                    title: '是否支持转谱',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -483,9 +562,18 @@ export default defineComponent({
                           // icon
                           h(NSelect, {
                             onUpdateValue(v) {
-                              state.scoreType = v
+                              state.isConvertibleScore = v
                             },
-                            options: getSelectDataFromObj(scoreType)
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
                           })
                         ]
                       )
@@ -495,7 +583,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.scoreType = state.scoreType
+                        item.isConvertibleScore = state.isConvertibleScore
                       }
                     }
                   })
@@ -514,35 +602,46 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'scoreType',
+        key: 'isConvertibleScore',
         width: 200,
         render: (row: any) => {
           // })
           return (
             <NSelect
-              placeholder="请选择默认谱面"
-              value={row.scoreType}
-              options={getSelectDataFromObj(scoreType)}
+              value={row.isConvertibleScore}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
               onUpdateValue={(value: any) => {
-                row.scoreType = value
+                row.isConvertibleScore = value
               }}
+              filterable
               clearable
             />
           )
         }
       })
+
+
       field.push({
         title(column: any) {
           return (
             <NSpace>
-              是否支持简谱
+              是否启用
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '是否支持转谱',
+                    title: '是否启用',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -554,7 +653,7 @@ export default defineComponent({
                           // icon
                           h(NSelect, {
                             onUpdateValue(v) {
-                              state.isConvertibleScore = v
+                              state.status = v
                             },
                             options: [
                               {
@@ -575,7 +674,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.isConvertibleScore = state.isConvertibleScore
+                        item.status = state.status
                       }
                     }
                   })
@@ -594,13 +693,13 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'isConvertibleScore',
+        key: 'status',
         width: 200,
         render: (row: any) => {
           // })
           return (
             <NSelect
-              value={row.isConvertibleScore}
+              value={row.status}
               options={[
                 {
                   label: '是',
@@ -612,7 +711,7 @@ export default defineComponent({
                 } as any
               ]}
               onUpdateValue={(value: any) => {
-                row.isConvertibleScore = value
+                row.status = value
               }}
               filterable
               clearable
@@ -620,6 +719,7 @@ export default defineComponent({
           )
         }
       })
+
       field.push({
         title(column: any) {
           return (

+ 39 - 13
src/views/music-library/project-music-sheet/module/gym/music-sheet-gym.tsx

@@ -76,7 +76,8 @@ export default defineComponent({
         // musicSheetType: null, //曲目类型(SINGLE:单曲 CONCERT:合奏)
         musicalInstrumentId: null, // 乐器ID
         musicCategoryIds: null, //曲目分类ID
-        status: null, //曲目状态(0:停用,1:启用)
+        clientStatus: null, //曲目状态(0:停用,1:启用)
+        status: null,
         sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
         paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
         userId: null, //所属人
@@ -220,7 +221,7 @@ export default defineComponent({
     }
 
     const onChangeStatus = (row: any) => {
-      const statusStr = row.status ? '停用' : '启用'
+      const statusStr = row.clientStatus ? '停用' : '启用'
       dialog.warning({
         title: '提示',
         content: `是否${statusStr}?`,
@@ -230,7 +231,7 @@ export default defineComponent({
           try {
             await musicSheetApplicationExtendStatus({
               ids: row.applicationExtendId,
-              status: !row.status
+              status: !row.clientStatus
             })
             getList()
             message.success(`${statusStr}成功`)
@@ -391,20 +392,26 @@ export default defineComponent({
           }
         },
         {
-          title: '上传',
+          title: '上传时间',
           minWidth: '150px',
           key: 'composer',
           render(row: any) {
             return (
-              <NDescriptions labelPlacement="left" column={1}>
-                <NDescriptionsItem label="上传人">{row.createByName}</NDescriptionsItem>
-                <NDescriptionsItem label="上传时间">{row.createTime}</NDescriptionsItem>
-              </NDescriptions>
+              row.createTime
+            )
+          }
+        },
+        {
+          title: '业务曲目状态',
+          key: 'clientStatus',
+          render(row: any) {
+            return (
+              <NTag type={row.clientStatus ? 'primary' : 'default'}>{row.clientStatus ? '启用' : '停用'}</NTag>
             )
           }
         },
         {
-          title: '状态',
+          title: '平台曲目状态',
           key: 'status',
           render(row: any) {
             return (
@@ -449,7 +456,7 @@ export default defineComponent({
                   v-auth="musicSheetApplicationExtend/status1751235150422736897"
                   onClick={() => onChangeStatus(row)}
                 >
-                  {row.status ? '停用' : '启用'}
+                  {row.clientStatus ? '停用' : '启用'}
                 </NButton>
                 <NButton
                   type="primary"
@@ -467,7 +474,7 @@ export default defineComponent({
                   type="primary"
                   size="small"
                   text
-                  disabled={!!row.status}
+                  disabled={!!row.clientStatus}
                   onClick={() => onRmove(row)}
                   v-auth="musicSheetApplicationExtend/del1770708555010191362"
                 >
@@ -612,10 +619,29 @@ export default defineComponent({
                 clearable
               ></NSelect>
             </NFormItem>
-            <NFormItem label="状态" path="status">
+            <NFormItem label="业务曲目状态" path="clientStatus">
+              <NSelect
+                v-model:value={state.searchForm.clientStatus}
+                placeholder="请选择业务曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="平台曲目状态" path="status">
               <NSelect
                 v-model:value={state.searchForm.status}
-                placeholder="请选择状态"
+                placeholder="请选择平台曲目状态"
                 options={
                   [
                     {

+ 29 - 7
src/views/music-library/project-music-sheet/module/gym/updateMusic.tsx

@@ -26,11 +26,12 @@ export default defineComponent({
     const message = useMessage()
     const btnLoading = ref(false)
     const forms = reactive({
-      musicSheetCategoryId: null as any,
+      // musicSheetCategoryId: null as any,
       sortNo: null as any,
       paymentType: null as any,
       isConvertibleScore: null as any,//是否支持转简谱
       scoreType: null as any,//默认谱面
+      status: null as any
     })
     const formsRef = ref()
 
@@ -48,11 +49,12 @@ export default defineComponent({
         message.error("加载应用失败")
         return
       }
-      forms.musicSheetCategoryId = data[0].musicSheetCategoryId
+      // forms.musicSheetCategoryId = data[0].musicSheetCategoryId
       forms.sortNo = data[0].sortNo
       forms.paymentType = data[0].paymentType
       forms.isConvertibleScore = data[0].isConvertibleScore
       forms.scoreType = data[0].scoreType
+      forms.status = data[0].status
 
     })
 
@@ -88,7 +90,7 @@ export default defineComponent({
                 label-placement="left"
                 label-width="auto"
             >
-              <NFormItem
+              {/* <NFormItem
                   label="曲目分类"
                   path="musicSheetCategoryId"
                   rule={[
@@ -111,7 +113,7 @@ export default defineComponent({
                     }}
                     clearable
                 />
-              </NFormItem>
+              </NFormItem> */}
               <NFormItem
                   label="收费方式"
                   path="paymentType"
@@ -192,15 +194,35 @@ export default defineComponent({
                 ></NSelect>
               </NFormItem>
               <NFormItem
-                  label="排序值"
-                  path="sortNo"
+                  label="是否启用"
+                  path="status"
                   rule={[
                     {
                       required: true,
-                      message: '请输入排序值'
+                      message: '请选择是否启用'
                     }
                   ]}
               >
+                <NSelect
+                    placeholder="请选择是否启用"
+                    options={[
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any}
+                    v-model:value={forms.status}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="排序值"
+                  path="sortNo"
+              >
                 <NInputNumber
                     v-model:value={forms.sortNo}
                     placeholder="请输入排序值"

+ 143 - 46
src/views/music-library/project-music-sheet/module/gyt/addMusic.tsx

@@ -86,8 +86,9 @@ export default defineComponent({
       selectRowData: [] as any, // 选择的数据列表
       musicSheetCategories: [] as any,
       startSortNum: null as any, // 排序起始值
-      projectMusicCategoryId: null as any, // 曲目分类ID
+      // projectMusicCategoryId: null as any, // 曲目分类ID
       isConvertibleScore: null as any, //是否支持转简谱
+      status: false, // 是否启用
       scoreType: null as any, //默认谱面
 
       useProjectData: [] as any, // 适用项目行数据
@@ -216,10 +217,10 @@ export default defineComponent({
           message.error('可用途径不能为空')
           return
         }
-        if (!item.projectMusicCategoryId) {
-          message.error('曲目分类不能为空')
-          return
-        }
+        // if (!item.projectMusicCategoryId) {
+        //   message.error('曲目分类不能为空')
+        //   return
+        // }
         if (item.scoreType == null) {
           message.error('默认谱面不能为空')
           return
@@ -228,14 +229,14 @@ export default defineComponent({
           message.error('是否支持转谱不能为空')
           return
         }
-        if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
-          message.error('排序号不能为空')
+        if (item.status == null) {
+          message.error('是否启用不能为空')
           return
         }
         params.push({
           ...item,
           musicSheetId: item.id,
-          musicSheetCategoryId: item.projectMusicCategoryId,
+          // musicSheetCategoryId: item.projectMusicCategoryId,
           availableType: item.availableType,
           applicationId: props.appId,
           id: null
@@ -279,6 +280,10 @@ export default defineComponent({
         title: '音乐人',
         key: 'composer'
       },
+      {
+        title: '曲目分类',
+        key: 'musicCategoryName'
+      },
       // {
       //   title: '谱面渲染',
       //   key: 'musicSheetType',
@@ -401,18 +406,98 @@ export default defineComponent({
           )
         }
       })
+      // field.push({
+      //   title(column: any) {
+      //     return (
+      //       <NSpace>
+      //         曲目分类
+      //         <NButton
+      //           type="primary"
+      //           size="small"
+      //           text
+      //           onClick={() => {
+      //             dialogs.create({
+      //               title: '请选择曲目分类',
+      //               showIcon: false,
+      //               content: () => {
+      //                 return h(
+      //                   'div',
+      //                   {
+      //                     class: 'flex flex-col justify-center items-center text-14px'
+      //                   },
+      //                   [
+      //                     // icon
+      //                     h(NCascader, {
+      //                       onUpdateValue(v) {
+      //                         state.projectMusicCategoryId = v
+      //                       },
+      //                       valueField: 'id',
+      //                       labelField: 'name',
+      //                       childrenField: 'children',
+      //                       placeholderField: '请选择曲目分类',
+      //                       filterable: true,
+      //                       options: state.musicSheetCategories
+      //                     })
+      //                   ]
+      //                 )
+      //               },
+      //               positiveText: '确定',
+      //               negativeText: '取消',
+      //               onPositiveClick: () => {
+      //                 for (let i = 0; i < state.selectRowData.length; i++) {
+      //                   const item = state.selectRowData[i]
+      //                   item.projectMusicCategoryId = state.projectMusicCategoryId
+      //                 }
+      //               }
+      //             })
+      //           }}
+      //         >
+      //           <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+      //             <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+      //               <path d="M2 26h28v2H2z" fill="currentColor"></path>
+      //               <path
+      //                 d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+      //                 fill="currentColor"
+      //               ></path>
+      //             </svg>
+      //           </NIcon>
+      //         </NButton>
+      //       </NSpace>
+      //     )
+      //   },
+      //   key: 'projectMusicCategoryId',
+      //   width: 200,
+      //   render: (row: any) => {
+      //     // })
+      //     return (
+      //       <NCascader
+      //         valueField="id"
+      //         labelField="name"
+      //         children-field="children"
+      //         placeholder="请选择曲目分类"
+      //         value={row.projectMusicCategoryId}
+      //         options={state.musicSheetCategories}
+      //         onUpdateValue={(value: any) => {
+      //           row.projectMusicCategoryId = value
+      //         }}
+      //         filterable
+      //         clearable
+      //       />
+      //     )
+      //   }
+      // })
       field.push({
         title(column: any) {
           return (
             <NSpace>
-              曲目分类
+              默认谱面
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '请选择曲目分类',
+                    title: '请选择默认谱面',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -422,16 +507,11 @@ export default defineComponent({
                         },
                         [
                           // icon
-                          h(NCascader, {
+                          h(NSelect, {
                             onUpdateValue(v) {
-                              state.projectMusicCategoryId = v
+                              state.scoreType = v
                             },
-                            valueField: 'id',
-                            labelField: 'name',
-                            childrenField: 'children',
-                            placeholderField: '请选择曲目分类',
-                            filterable: true,
-                            options: state.musicSheetCategories
+                            options: getSelectDataFromObj(scoreType)
                           })
                         ]
                       )
@@ -441,7 +521,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.projectMusicCategoryId = state.projectMusicCategoryId
+                        item.scoreType = state.scoreType
                       }
                     }
                   })
@@ -460,22 +540,18 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'projectMusicCategoryId',
+        key: 'scoreType',
         width: 200,
         render: (row: any) => {
           // })
           return (
-            <NCascader
-              valueField="id"
-              labelField="name"
-              children-field="children"
-              placeholder="请选择曲目分类"
-              value={row.projectMusicCategoryId}
-              options={state.musicSheetCategories}
+            <NSelect
+              placeholder="请选择默认谱面"
+              value={row.scoreType}
+              options={getSelectDataFromObj(scoreType)}
               onUpdateValue={(value: any) => {
-                row.projectMusicCategoryId = value
+                row.scoreType = value
               }}
-              filterable
               clearable
             />
           )
@@ -485,14 +561,14 @@ export default defineComponent({
         title(column: any) {
           return (
             <NSpace>
-              默认谱面
+              是否支持转谱
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '请选择默认谱面',
+                    title: '是否支持转谱',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -504,9 +580,18 @@ export default defineComponent({
                           // icon
                           h(NSelect, {
                             onUpdateValue(v) {
-                              state.scoreType = v
+                              state.isConvertibleScore = v
                             },
-                            options: getSelectDataFromObj(scoreType)
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
                           })
                         ]
                       )
@@ -516,7 +601,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.scoreType = state.scoreType
+                        item.isConvertibleScore = state.isConvertibleScore
                       }
                     }
                   })
@@ -535,35 +620,45 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'scoreType',
+        key: 'isConvertibleScore',
         width: 200,
         render: (row: any) => {
           // })
           return (
             <NSelect
-              placeholder="请选择默认谱面"
-              value={row.scoreType}
-              options={getSelectDataFromObj(scoreType)}
+              value={row.isConvertibleScore}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
               onUpdateValue={(value: any) => {
-                row.scoreType = value
+                row.isConvertibleScore = value
               }}
+              filterable
               clearable
             />
           )
         }
       })
+
       field.push({
         title(column: any) {
           return (
             <NSpace>
-              是否支持转谱
+              是否启用
               <NButton
                 type="primary"
                 size="small"
                 text
                 onClick={() => {
                   dialogs.create({
-                    title: '是否支持转谱',
+                    title: '是否启用',
                     showIcon: false,
                     content: () => {
                       return h(
@@ -575,7 +670,7 @@ export default defineComponent({
                           // icon
                           h(NSelect, {
                             onUpdateValue(v) {
-                              state.isConvertibleScore = v
+                              state.status = v
                             },
                             options: [
                               {
@@ -596,7 +691,7 @@ export default defineComponent({
                     onPositiveClick: () => {
                       for (let i = 0; i < state.selectRowData.length; i++) {
                         const item = state.selectRowData[i]
-                        item.isConvertibleScore = state.isConvertibleScore
+                        item.status = state.status
                       }
                     }
                   })
@@ -615,13 +710,13 @@ export default defineComponent({
             </NSpace>
           )
         },
-        key: 'isConvertibleScore',
+        key: 'status',
         width: 200,
         render: (row: any) => {
           // })
           return (
             <NSelect
-              value={row.isConvertibleScore}
+              value={row.status}
               options={[
                 {
                   label: '是',
@@ -633,7 +728,7 @@ export default defineComponent({
                 } as any
               ]}
               onUpdateValue={(value: any) => {
-                row.isConvertibleScore = value
+                row.status = value
               }}
               filterable
               clearable
@@ -641,6 +736,7 @@ export default defineComponent({
           )
         }
       })
+
       field.push({
         title(column: any) {
           return (
@@ -771,6 +867,7 @@ export default defineComponent({
             return row.id === next.id
           })
           if (!find) {
+            next.status = false
             state.selectRowData.push(next)
           }
         }

+ 39 - 13
src/views/music-library/project-music-sheet/module/gyt/music-sheet-gyt.tsx

@@ -65,7 +65,8 @@ export default defineComponent({
         subjectId: null, //声部ID
         subjectIds: null, //曲目声部ID集合
         musicCategoryIds: null, //曲目分类ID
-        status: null, //曲目状态(0:停用,1:启用)
+        clientStatus: null, //曲目状态(0:停用,1:启用)
+        status: null,
         sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
         paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
         userId: null, //所属人
@@ -229,7 +230,7 @@ export default defineComponent({
     }
 
     const onChangeStatus = (row: any) => {
-      const statusStr = row.status ? '停用' : '启用'
+      const statusStr = row.clientStatus ? '停用' : '启用'
       dialog.warning({
         title: '提示',
         content: `是否${statusStr}?`,
@@ -239,7 +240,7 @@ export default defineComponent({
           try {
             await musicSheetApplicationExtendStatus({
               ids: row.applicationExtendId,
-              status: !row.status
+              status: !row.clientStatus
             })
             getList()
             message.success(`${statusStr}成功`)
@@ -383,20 +384,26 @@ export default defineComponent({
         //   }
         // },
         {
-          title: '上传',
+          title: '上传时间',
           minWidth: '150px',
           key: 'composer',
           render(row: any) {
             return (
-              <NDescriptions labelPlacement="left" column={1}>
-                <NDescriptionsItem label="上传人">{row.createByName}</NDescriptionsItem>
-                <NDescriptionsItem label="上传时间">{row.createTime}</NDescriptionsItem>
-              </NDescriptions>
+              row.createTime
+            )
+          }
+        },
+        {
+          title: '业务曲目状态',
+          key: 'clientStatus',
+          render(row: any) {
+            return (
+              <NTag type={row.clientStatus ? 'primary' : 'default'}>{row.clientStatus ? '启用' : '停用'}</NTag>
             )
           }
         },
         {
-          title: '状态',
+          title: '平台曲目状态',
           key: 'status',
           render(row: any) {
             return (
@@ -438,7 +445,7 @@ export default defineComponent({
                   v-auth="musicSheetApplicationExtend/status1751235279221424130"
                   onClick={() => onChangeStatus(row)}
                 >
-                  {row.status ? '停用' : '启用'}
+                  {row.clientStatus ? '停用' : '启用'}
                 </NButton>
                 <NButton
                   type="primary"
@@ -456,7 +463,7 @@ export default defineComponent({
                   type="primary"
                   size="small"
                   text
-                  disabled={!!row.status}
+                  disabled={!!row.clientStatus}
                   onClick={() => onRmove(row)}
                   v-auth="musicSheetApplicationExtend/del1770708605081792513"
                 >
@@ -592,10 +599,29 @@ export default defineComponent({
             {/*    clearable*/}
             {/*  ></NSelect>*/}
             {/*</NFormItem>*/}
-            <NFormItem label="状态" path="status">
+            <NFormItem label="业务曲目状态" path="clientStatus">
+              <NSelect
+                v-model:value={state.searchForm.clientStatus}
+                placeholder="请选择业务曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="平台曲目状态" path="status">
               <NSelect
                 v-model:value={state.searchForm.status}
-                placeholder="请选择状态"
+                placeholder="请选择平台曲目状态"
                 options={
                   [
                     {

+ 27 - 5
src/views/music-library/project-music-sheet/module/gyt/updateMusic.tsx

@@ -30,6 +30,7 @@ export default defineComponent({
       sortNo: null as any,
       availableType: null as any,
       isConvertibleScore: null as any,//是否支持转简谱
+      status: false, // 是否启用
       scoreType: null as any,//默认谱面
     })
     const formsRef = ref()
@@ -53,6 +54,7 @@ export default defineComponent({
       forms.availableType = data[0].availableType
       forms.isConvertibleScore = data[0].isConvertibleScore
       forms.scoreType = data[0].scoreType
+      forms.status = data[0].status
     })
 
     const onSubmit = async () => {
@@ -87,7 +89,7 @@ export default defineComponent({
                 label-placement="left"
                 label-width="auto"
             >
-              <NFormItem
+              {/* <NFormItem
                   label="曲目分类"
                   path="musicSheetCategoryId"
                   rule={[
@@ -110,7 +112,7 @@ export default defineComponent({
                     }}
                     clearable
                 />
-              </NFormItem>
+              </NFormItem> */}
               <NFormItem
                   label="可用途径"
                   path="availableType"
@@ -191,15 +193,35 @@ export default defineComponent({
                 ></NSelect>
               </NFormItem>
               <NFormItem
-                  label="排序值"
-                  path="sortNo"
+                  label="是否启用"
+                  path="status"
                   rule={[
                     {
                       required: true,
-                      message: '请输入排序值'
+                      message: '请选择是否启用'
                     }
                   ]}
               >
+                <NSelect
+                    placeholder="请选择是否启用"
+                    options={[
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any}
+                    v-model:value={forms.status}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="排序值"
+                  path="sortNo"
+              >
                 <NInputNumber
                     v-model:value={forms.sortNo}
                     placeholder="请输入排序值"

+ 168 - 76
src/views/music-library/project-music-sheet/module/klx/addMusic.tsx

@@ -99,6 +99,7 @@ export default defineComponent({
       globalExquisiteFlag: null as any, //精品乐谱
       globalStartSortNum: null as any, // 排序起始值
       isConvertibleScore: null as any, //是否支持转简谱
+      status: false, // 是否启用
       scoreType: null as any //默认谱面
     })
 
@@ -242,10 +243,10 @@ export default defineComponent({
             return
           }
         }
-        if (!item.availableType) {
-          message.error('可用途径不能为空')
-          return
-        }
+        // if (!item.availableType) {
+        //   message.error('可用途径不能为空')
+        //   return
+        // }
         if (typeof item.topFlag !== 'boolean') {
           message.error('是否置顶不能为空')
           return
@@ -262,8 +263,8 @@ export default defineComponent({
           message.error('是否支持转谱不能为空')
           return
         }
-        if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
-          message.error('排序号不能为空')
+        if (item.status == null) {
+          message.error('是否启用不能为空')
           return
         }
         params.push({
@@ -599,76 +600,76 @@ export default defineComponent({
           })
         }
       })
-      field.push({
-        title(column: any) {
-          return (
-            <NSpace>
-              可用途径
-              <NButton
-                type="primary"
-                size="small"
-                text
-                onClick={() => {
-                  dialogs.create({
-                    title: '请选择可用途径',
-                    showIcon: false,
-                    content: () => {
-                      return h(
-                        'div',
-                        {
-                          class: 'flex flex-col justify-center items-center text-14px'
-                        },
-                        [
-                          // icon
-                          h(NSelect, {
-                            onUpdateValue(v) {
-                              state.globalAvailableType = v
-                            },
-                            clearable: true,
-                            options: getSelectDataFromObj(musicSheetAvailableType)
-                          })
-                        ]
-                      )
-                    },
-                    positiveText: '确定',
-                    negativeText: '取消',
-                    onPositiveClick: () => {
-                      for (let i = 0; i < state.selectRowData.length; i++) {
-                        const item = state.selectRowData[i]
-                        item.availableType = state.globalAvailableType
-                      }
-                    }
-                  })
-                }}
-              >
-                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
-                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
-                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
-                    <path
-                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
-                      fill="currentColor"
-                    ></path>
-                  </svg>
-                </NIcon>
-              </NButton>
-            </NSpace>
-          )
-        },
-        key: 'availableType',
-        render: (row: any) => {
-          return (
-            <NSelect
-              placeholder="请选择可用途径"
-              value={row.availableType}
-              options={getSelectDataFromObj(musicSheetAvailableType)}
-              onUpdateValue={(value) => {
-                row['availableType'] = value
-              }}
-              clearable
-            />
-          )
-        }
-      })
+      // field.push({
+      //   title(column: any) {
+      //     return (
+      //       <NSpace>
+      //         可用途径
+      //         <NButton
+      //           type="primary"
+      //           size="small"
+      //           text
+      //           onClick={() => {
+      //             dialogs.create({
+      //               title: '请选择可用途径',
+      //               showIcon: false,
+      //               content: () => {
+      //                 return h(
+      //                   'div',
+      //                   {
+      //                     class: 'flex flex-col justify-center items-center text-14px'
+      //                   },
+      //                   [
+      //                     // icon
+      //                     h(NSelect, {
+      //                       onUpdateValue(v) {
+      //                         state.globalAvailableType = v
+      //                       },
+      //                       clearable: true,
+      //                       options: getSelectDataFromObj(musicSheetAvailableType)
+      //                     })
+      //                   ]
+      //                 )
+      //               },
+      //               positiveText: '确定',
+      //               negativeText: '取消',
+      //               onPositiveClick: () => {
+      //                 for (let i = 0; i < state.selectRowData.length; i++) {
+      //                   const item = state.selectRowData[i]
+      //                   item.availableType = state.globalAvailableType
+      //                 }
+      //               }
+      //             })
+      //           }}
+      //         >
+      //           <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+      //             <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+      //               <path d="M2 26h28v2H2z" fill="currentColor"></path>
+      //               <path
+      //                 d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+      //                 fill="currentColor"
+      //               ></path>
+      //             </svg>
+      //           </NIcon>
+      //         </NButton>
+      //       </NSpace>
+      //     )
+      //   },
+      //   key: 'availableType',
+      //   render: (row: any) => {
+      //     return (
+      //       <NSelect
+      //         placeholder="请选择可用途径"
+      //         value={row.availableType}
+      //         options={getSelectDataFromObj(musicSheetAvailableType)}
+      //         onUpdateValue={(value) => {
+      //           row['availableType'] = value
+      //         }}
+      //         clearable
+      //       />
+      //     )
+      //   }
+      // })
       field.push({
         title(column: any) {
           return (
@@ -1008,6 +1009,97 @@ export default defineComponent({
         }
       })
 
+
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              是否启用
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '是否启用',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NSelect, {
+                            onUpdateValue(v) {
+                              state.status = v
+                            },
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.status = state.status
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'status',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+            <NSelect
+              value={row.status}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
+              onUpdateValue={(value: any) => {
+                row.status = value
+              }}
+              filterable
+              clearable
+            />
+          )
+        }
+      })
+
       field.push({
         title(column: any) {
           return (

+ 37 - 13
src/views/music-library/project-music-sheet/module/klx/music-sheet-klx.tsx

@@ -71,7 +71,8 @@ export default defineComponent({
         // musicSheetType: null, //曲目类型(SINGLE:单曲 CONCERT:合奏)
         subjectId: null, //声部ID
         subjectIds: null, //曲目声部ID集合
-        status: null, //曲目状态(0:停用,1:启用)
+        clientStatus: null, //曲目状态(0:停用,1:启用)
+        status: null,
         sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
         paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
         userId: null, //所属人
@@ -224,7 +225,7 @@ export default defineComponent({
     }
 
     const onChangeStatus = (row: any) => {
-      const statusStr = row.status ? '停用' : '启用'
+      const statusStr = row.clientStatus ? '停用' : '启用'
       dialog.warning({
         title: '提示',
         content: `是否${statusStr}?`,
@@ -234,7 +235,7 @@ export default defineComponent({
           try {
             await musicSheetApplicationExtendStatus({
               ids: row.applicationExtendId,
-              status: !row.status
+              status: !row.clientStatus
             })
             getList()
             message.success(`${statusStr}成功`)
@@ -439,20 +440,24 @@ export default defineComponent({
           key: 'musicPrice'
         },
         {
-          title: '上传',
+          title: '上传时间',
           minWidth: '150px',
           key: 'composer',
           render(row: any) {
+            return row.createTime
+          }
+        },
+        {
+          title: '业务曲目状态',
+          key: 'clientStatus',
+          render(row: any) {
             return (
-              <NDescriptions labelPlacement="left" column={1}>
-                <NDescriptionsItem label="上传人">{row.createByName}</NDescriptionsItem>
-                <NDescriptionsItem label="上传时间">{row.createTime}</NDescriptionsItem>
-              </NDescriptions>
+              <NTag type={row.clientStatus ? 'primary' : 'default'}>{row.clientStatus ? '启用' : '停用'}</NTag>
             )
           }
         },
         {
-          title: '状态',
+          title: '平台曲目状态',
           key: 'status',
           render(row: any) {
             return (
@@ -494,7 +499,7 @@ export default defineComponent({
                   v-auth="musicSheetApplicationExtend/status1751229794627878914"
                   onClick={() => onChangeStatus(row)}
                 >
-                  {row.status ? '停用' : '启用'}
+                  {row.clientStatus ? '停用' : '启用'}
                 </NButton>
                 <NButton
                   type="primary"
@@ -512,7 +517,7 @@ export default defineComponent({
                   type="primary"
                   size="small"
                   text
-                  disabled={!!row.status}
+                  disabled={!!row.clientStatus}
                   onClick={() => onRmove(row)}
                   v-auth="musicSheetApplicationExtend/del1770708473623916546"
                 >
@@ -647,10 +652,29 @@ export default defineComponent({
                 clearable
               ></NSelect>
             </NFormItem>
-            <NFormItem label="状态" path="status">
+            <NFormItem label="业务曲目状态" path="clientStatus">
+              <NSelect
+                v-model:value={state.searchForm.clientStatus}
+                placeholder="请选择业务曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="平台曲目状态" path="status">
               <NSelect
                 v-model:value={state.searchForm.status}
-                placeholder="请选择状态"
+                placeholder="请选择平台曲目状态"
                 options={
                   [
                     {

+ 25 - 3
src/views/music-library/project-music-sheet/module/klx/updateMusic.tsx

@@ -34,6 +34,7 @@ export default defineComponent({
       topFlag: null as any,
       exquisiteFlag: null as any,
       isConvertibleScore: null as any,//是否支持转简谱
+      status: null as any, // 是否启用
       scoreType: null as any,//默认谱面
     })
     const formsRef = ref()
@@ -63,6 +64,7 @@ export default defineComponent({
       forms.exquisiteFlag = data[0].exquisiteFlag
       forms.isConvertibleScore = data[0].isConvertibleScore
       forms.scoreType = data[0].scoreType
+      forms.status = data[0].status
     })
 
     const onSubmit = async () => {
@@ -290,15 +292,35 @@ export default defineComponent({
                 ></NSelect>
               </NFormItem>
               <NFormItem
-                  label="排序值"
-                  path="sortNo"
+                  label="是否启用"
+                  path="status"
                   rule={[
                     {
                       required: true,
-                      message: '请输入排序值'
+                      message: '请选择是否启用'
                     }
                   ]}
               >
+                <NSelect
+                    placeholder="请选择是否启用"
+                    options={[
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any}
+                    v-model:value={forms.status}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="排序值"
+                  path="sortNo"
+              >
                 <NInputNumber
                     v-model:value={forms.sortNo}
                     placeholder="请输入排序值"

+ 898 - 0
src/views/music-library/project-music-sheet/module/klx_jg/addMusic.tsx

@@ -0,0 +1,898 @@
+import { defineComponent, h, onMounted, reactive, ref } from 'vue'
+import SaveForm from '@components/save-form'
+import {
+  DataTableColumns,
+  DataTableRowKey,
+  NButton,
+  NDataTable,
+  NFormItem,
+  NIcon,
+  NImage,
+  NInput,
+  NInputNumber,
+  NSelect,
+  NSpace,
+  NStep,
+  NSteps,
+  useDialog,
+  useMessage
+} from 'naive-ui'
+import Pagination from '@components/pagination'
+import { getMapValueByKey, getSelectDataFromObj } from '@/utils/objectUtil'
+import {
+  appKey,
+  musicSheetAvailableType,
+  musicSheetPaymentType,
+  musicSheetSourceType,
+  musicSheetType,
+  scoreType
+} from '@/utils/constant'
+import {
+  musicSheetApplicationExtendSaveBatch,
+  musicSheetApplicationExtendTagList,
+  musicSheetApplicationOwnerList,
+  musicSheetPage
+} from '@views/music-library/api'
+import deepClone from '@/utils/deep.clone'
+import { getOwnerName } from '@views/music-library/musicUtil'
+import TheTooltip from '@components/TheTooltip'
+import { sysApplicationPage } from '@views/menu-manage/api'
+
+export default defineComponent({
+  name: 'klx-addMusic',
+  props: {
+    appId: {
+      type: String,
+      required: true
+    },
+    subjectList: {
+      type: Array,
+      default: () => []
+    },
+    musicSheetTagList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  emits: ['close', 'getList'],
+  setup(props, { slots, attrs, emit }) {
+    const dialogs = useDialog()
+    const message = useMessage()
+    const state = reactive({
+      loading: false,
+      pagination: {
+        page: 1,
+        rows: 5,
+        pageTotal: 0
+      },
+      stepPagination: {
+        page: 1,
+        rows: 5,
+        pageTotal: 0
+      },
+      searchForm: {
+        keyword: null,
+        // musicSheetType: null,
+        subjectId: null,
+        sourceType: null,
+        composer: null,
+        userId: null,
+        applicationId: null
+      },
+      subjectList: [] as any,
+      showAdd: false,
+      currentStep: 1,
+      dataList: [],
+      selectRowData: [] as any, // 选择的数据列表
+      musicSheetCategories: [] as any,
+      musicSheetTagList: [] as any,
+      useProjectData: [] as any, // 适用项目行数据
+
+      userIdDisable: true,
+      userIdData: [] as any,
+
+      globalStartSortNum: null as any, // 排序起始值
+      status: false as any, // 是否启用
+      isConvertibleScore: null as any, //是否支持转简谱
+      scoreType: null as any //默认谱面
+    })
+
+    onMounted(async () => {
+      state.searchForm.keyword = null
+      // state.searchForm.musicSheetType = null
+      state.searchForm.subjectId = null
+      state.searchForm.sourceType = null
+      state.searchForm.composer = null
+      state.searchForm.userId = null
+      state.searchForm.applicationId = null
+
+      state.loading = true
+      state.subjectList = props.subjectList
+      // state.musicSheetTagList = props.musicSheetTagList
+      // 加载曲目标签
+
+      try {
+        const { data } = await musicSheetApplicationExtendTagList({
+          applicationId: props.appId,
+          enable: true
+        })
+        if (data && data.length > 0) {
+          data.forEach((item: any) => {
+            state.musicSheetTagList.push({
+              ...item,
+              label: item.name,
+              value: item.id
+            })
+          })
+        }
+      } catch (err) {}
+      await initUseAppList()
+      await getList()
+    })
+
+    const initUseAppList = async () => {
+      try {
+        const appKeys = Object.keys(appKey)
+        const { data } = await sysApplicationPage({ page: 1, rows: 999 })
+        const tempList = data.rows || []
+        state.useProjectData = []
+        const filter = tempList.filter((next: any) => {
+          return appKeys.includes(next.appKey)
+        })
+        filter.forEach((item: any) => {
+          state.useProjectData.push({
+            ...item,
+            label: item.appName,
+            value: item.id
+          })
+        })
+      } catch {}
+    }
+
+    const getList = async () => {
+      try {
+        state.loading = true
+        const search = {
+          ...state.searchForm,
+          userId:
+            state.searchForm.sourceType && state.searchForm.sourceType == 'PERSON'
+              ? state.searchForm.userId
+              : null,
+          organizationRoleId:
+            state.searchForm.sourceType && state.searchForm.sourceType == 'ORG'
+              ? state.searchForm.userId
+              : null
+        }
+        const { data } = await musicSheetPage({
+          ...state.pagination,
+          ...search,
+          addAppId: props.appId
+        })
+        state.pagination.pageTotal = Number(data.total)
+        state.dataList = data.rows || []
+      } catch {}
+      state.loading = false
+    }
+
+    const saveForm = ref()
+
+    const onSearch = () => {
+      checkedRowKeysRef.value = []
+      saveForm.value?.submit()
+    }
+    const onBtnReset = () => {
+      saveForm.value?.reset()
+    }
+
+    const onSubmit = () => {
+      state.pagination.page = 1
+      getList()
+    }
+
+    const updateUserIdData = async (sourceType: any) => {
+      if (!state.searchForm.applicationId) {
+        return
+      }
+      state.userIdData = []
+      state.searchForm.userId = null
+      if (sourceType && sourceType !== 'PLATFORM') {
+        const { data } = await musicSheetApplicationOwnerList({
+          page: 1,
+          rows: 9999,
+          sourceType: sourceType,
+          applicationId: state.searchForm.applicationId
+        })
+        const temp = data.rows || []
+        temp.forEach((next: any) => {
+          state.userIdData.push({
+            ...next,
+            label: sourceType === 'PERSON' ? next.userName : next.organizationRole,
+            value: sourceType === 'PERSON' ? next.userId : next.organizationRoleId
+          })
+        })
+      }
+    }
+
+    const onSave = async () => {
+      if (state.selectRowData.length == 0) {
+        message.error('未选择曲目')
+        return
+      }
+      const params = [] as any[]
+      for (let i = 0; i < state.selectRowData.length; i++) {
+        const item = state.selectRowData[i]
+        if (item.scoreType == null) {
+          message.error('默认谱面不能为空')
+          return
+        }
+        if (item.isConvertibleScore == null) {
+          message.error('是否支持转谱不能为空')
+          return
+        }
+        params.push({
+          ...item,
+          musicSheetId: item.id,
+          applicationId: props.appId,
+          id: null
+        })
+      }
+      const res = (await musicSheetApplicationExtendSaveBatch(params)) as any
+      if (res && res.code == '200') {
+        message.success(`添加成功`)
+        emit('getList')
+        emit('close')
+      }
+    }
+
+    const columnsField = [
+      {
+        type: 'selection'
+      },
+      {
+        title: '曲目编号',
+        key: 'id'
+      },
+      {
+        title: '封面图',
+        key: 'titleImg',
+        render(row: any) {
+          return <NImage width={40} height={40} src={row.musicCover} />
+        }
+      },
+      {
+        title: '可用声部',
+        key: 'subjectNames',
+        render: (row: any) => {
+          return <TheTooltip content={row.subjectNames} />
+        }
+      },
+      {
+        title: '曲目名称',
+        key: 'name'
+      },
+      {
+        title: '音乐人',
+        key: 'composer'
+      },
+      // {
+      //   title: '谱面渲染',
+      //   key: 'musicSheetType',
+      //   render: (row: any) => {
+      //     return (
+      //       <div>
+      //         {getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}
+      //       </div>
+      //     )
+      //   }
+      // },
+      {
+        title: '曲目来源',
+        key: 'sourceType',
+        render(row: any) {
+          return getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))
+        }
+      },
+      {
+        title: '所属人',
+        key: 'userName',
+        render: (row: any) => {
+          return <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
+        }
+      }
+    ]
+
+    const columns = (): any => {
+      return columnsField
+    }
+
+    const stepColumns = (): DataTableColumns => {
+      const field = deepClone(columnsField)
+      field.splice(0, 1)
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              默认谱面
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '请选择默认谱面',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NSelect, {
+                            onUpdateValue(v) {
+                              state.scoreType = v
+                            },
+                            options: getSelectDataFromObj(scoreType)
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.scoreType = state.scoreType
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'scoreType',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+            <NSelect
+              placeholder="请选择默认谱面"
+              value={row.scoreType}
+              options={getSelectDataFromObj(scoreType)}
+              onUpdateValue={(value: any) => {
+                row.scoreType = value
+              }}
+              clearable
+            />
+          )
+        }
+      })
+      
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              是否支持转谱
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '是否支持转谱',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NSelect, {
+                            onUpdateValue(v) {
+                              state.isConvertibleScore = v
+                            },
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.isConvertibleScore = state.isConvertibleScore
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'isConvertibleScore',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+            <NSelect
+              value={row.isConvertibleScore}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
+              onUpdateValue={(value: any) => {
+                row.isConvertibleScore = value
+              }}
+              filterable
+              clearable
+            />
+          )
+        }
+      })
+
+
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              是否启用
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '是否启用',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NSelect, {
+                            onUpdateValue(v) {
+                              state.status = v
+                            },
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.status = state.status
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'status',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+            <NSelect
+              value={row.status}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
+              onUpdateValue={(value: any) => {
+                row.status = value
+              }}
+              filterable
+              clearable
+            />
+          )
+        }
+      })
+
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              排序
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '请输入排序起始值',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NInputNumber, {
+                            onUpdateValue(v) {
+                              state.globalStartSortNum = v
+                            },
+                            min: 0,
+                            max: 9999
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.sortNo = state.globalStartSortNum + i
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'sortNo',
+        fixed: 'right',
+        width: 150,
+        render: (row: any) => {
+          return h(NInputNumber, {
+            value: row.sortNo,
+            min: 0,
+            max: 9999,
+            onUpdateValue(value: any) {
+              row.sortNo = value
+            }
+          })
+        }
+      })
+
+      field.push({
+        title: '操作',
+        key: 'operation',
+        fixed: 'right',
+        render(row: any) {
+          return (
+            <NSpace>
+              <NButton
+                type="primary"
+                size="small"
+                text
+                //v-auth="musicSheet/update1602302618558099458"
+                onClick={() => {
+                  dialogs.warning({
+                    title: '提示',
+                    content: `是否删除该数据?`,
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: async () => {
+                      try {
+                        const index = state.selectRowData.findIndex((item: any) => {
+                          if (item.id == row.id) {
+                            return true
+                          }
+                        })
+                        if (index > -1) {
+                          state.selectRowData.splice(index, 1)
+                        }
+                        const index1 = checkedRowKeysRef.value.findIndex((item: any) => {
+                          if (item == row.id) {
+                            return true
+                          }
+                        })
+                        if (index1 > -1) {
+                          checkedRowKeysRef.value.splice(index, 1)
+                        }
+                      } catch {}
+                    }
+                  })
+                }}
+              >
+                移除
+              </NButton>
+            </NSpace>
+          )
+        }
+      })
+      return field
+    }
+
+    const checkedRowKeysRef = ref<DataTableRowKey[]>([])
+    const handleCheck = (rowKeys: DataTableRowKey[]) => {
+      checkedRowKeysRef.value = rowKeys
+      // 添加行更新值
+      state.dataList.forEach((next: any) => {
+        if (checkedRowKeysRef.value.includes(next.id)) {
+          const find = state.selectRowData.find((row: any) => {
+            return row.id === next.id
+          })
+          if (!find) {
+            state.selectRowData.push({
+              ...next,
+              status: false,
+              paymentType: [] as any,
+              musicPriceDisable: false // 默认可以编辑曲目价格
+            })
+          }
+        }
+      })
+
+      // 去掉行更新值
+      state.selectRowData = state.selectRowData.filter((next: any) => {
+        return checkedRowKeysRef.value.includes(next.id)
+      })
+    }
+
+    return () => {
+      return (
+        <div class="system-menu-container">
+          <NSpace vertical size="medium">
+            <NSteps
+              current={state.currentStep}
+              // onUpdateCurrent={()=>{
+              //   state.currentStep = val
+              // }}
+              style={'margin-bottom: 10px;margin-top: 10px'}
+            >
+              <NStep title="选择曲目" description=""></NStep>
+              <NStep title="设置曲目信息" description=""></NStep>
+            </NSteps>
+          </NSpace>
+          {state.currentStep === 1 && (
+            <div class="system-menu-container">
+              <SaveForm
+                ref={saveForm}
+                model={state.searchForm}
+                onSubmit={onSubmit}
+                saveKey="klx-addMusic"
+                onSetModel={(val: any) => (state.searchForm = val)}
+              >
+                <NFormItem label="关键词" path="keyword">
+                  <NInput
+                    v-model:value={state.searchForm.keyword}
+                    placeholder="请输入曲目名称/编号"
+                    clearable
+                  />
+                </NFormItem>
+                {/* <NFormItem label="谱面渲染" path="musicSheetType">
+                  <NSelect
+                    placeholder="请选择谱面渲染"
+                    v-model:value={state.searchForm.musicSheetType}
+                    options={getSelectDataFromObj(musicSheetType)}
+                    clearable
+                  />
+                </NFormItem> */}
+                <NFormItem label="可用声部" path="musicSubject">
+                  <NSelect
+                    placeholder="请选择可用声部"
+                    v-model:value={state.searchForm.subjectId}
+                    options={state.subjectList}
+                    clearable
+                    filterable
+                  />
+                </NFormItem>
+                <NFormItem label="音乐人" path="composer">
+                  <NInput
+                    placeholder="请选择音乐人"
+                    v-model:value={state.searchForm.composer}
+                    clearable
+                  />
+                </NFormItem>
+                <NFormItem label="曲目来源" path="sourceType">
+                  <NSelect
+                    placeholder="请选择曲目来源"
+                    v-model:value={state.searchForm.sourceType}
+                    options={getSelectDataFromObj(musicSheetSourceType)}
+                    onUpdateValue={async (value: any) => {
+                      state.userIdData = []
+                      state.searchForm.userId = null
+                      if (value && value !== 'PLATFORM') {
+                        await updateUserIdData(value)
+                        state.userIdDisable = false
+                      } else {
+                        state.userIdDisable = true
+                      }
+                    }}
+                    clearable
+                  />
+                </NFormItem>
+                <NFormItem label="所属项目" path="applicationId">
+                  <NSelect
+                    placeholder="请选择所属项目"
+                    v-model:value={state.searchForm.applicationId}
+                    options={state.useProjectData}
+                    clearable
+                    onUpdateValue={async (value: any) => {
+                      state.searchForm.applicationId = value
+                      if (value) {
+                        await updateUserIdData(state.searchForm.sourceType)
+                        state.userIdDisable = !(
+                          state.searchForm.sourceType && state.searchForm.sourceType !== 'PLATFORM'
+                        )
+                      } else {
+                        state.searchForm.userId = null
+                        state.userIdDisable = true
+                        state.userIdData = []
+                      }
+                    }}
+                  />
+                </NFormItem>
+                <NFormItem label="所属人" path="author">
+                  <NSelect
+                    filterable
+                    placeholder="请选择所属人"
+                    disabled={
+                      state.userIdDisable ||
+                      (!state.searchForm.applicationId && !state.searchForm.sourceType)
+                    }
+                    v-model:value={state.searchForm.userId}
+                    options={state.userIdData}
+                    clearable
+                  ></NSelect>
+                </NFormItem>
+                <NFormItem>
+                  <NSpace>
+                    <NButton type="primary" onClick={onSearch}>
+                      搜索
+                    </NButton>
+                    <NButton type="default" onClick={onBtnReset}>
+                      重置
+                    </NButton>
+                  </NSpace>
+                </NFormItem>
+              </SaveForm>
+              <p style={{ paddingBottom: '12px' }}>
+                你选择了<span style={'color:red;padding:0 8px'}>{state.selectRowData.length}</span>
+                条曲目
+              </p>
+              <NDataTable
+                loading={state.loading}
+                columns={columns()}
+                data={state.dataList}
+                rowKey={(row: any) => row.id}
+                onUpdateCheckedRowKeys={handleCheck}
+                v-model:checkedRowKeys={checkedRowKeysRef.value}
+              ></NDataTable>
+              <Pagination
+                v-model:page={state.pagination.page}
+                v-model:pageSize={state.pagination.rows}
+                v-model:pageTotal={state.pagination.pageTotal}
+                onList={getList}
+                sync
+                saveKey="klx-addMusic"
+              ></Pagination>
+            </div>
+          )}
+          {state.currentStep === 2 && (
+            <div class="system-menu-container" style={'margin-top: 15px;'}>
+              <NDataTable
+                loading={state.loading}
+                columns={stepColumns()}
+                data={state.selectRowData}
+                rowKey={(row: any) => row.id}
+                maxHeight={500}
+                scrollX={2500}
+              ></NDataTable>
+            </div>
+          )}
+          <NSpace justify="end" style={'margin-top:10px'}>
+            <NButton
+              type="default"
+              onClick={() => {
+                if (state.currentStep > 1) {
+                  state.currentStep = state.currentStep - 1
+                } else {
+                  emit('close')
+                }
+              }}
+            >
+              {state.currentStep === 1 ? '取消' : '上一步'}
+            </NButton>
+            <NButton
+              type="primary"
+              onClick={() => {
+                if (state.currentStep < 2) {
+                  if (state.selectRowData.length == 0) {
+                    message.warning('请选择曲目')
+                    return
+                  }
+                  state.currentStep = state.currentStep + 1
+                } else {
+                  onSave()
+                }
+              }}
+              // loading={btnLoading.value}
+              // disabled={btnLoading.value}
+            >
+              {state.currentStep === 2 ? '确定' : '下一步'}
+            </NButton>
+          </NSpace>
+        </div>
+      )
+    }
+  }
+})

+ 773 - 0
src/views/music-library/project-music-sheet/module/klx_jg/music-sheet-klx_jg.tsx

@@ -0,0 +1,773 @@
+import { defineComponent, onMounted, reactive, ref } from 'vue'
+import SaveForm from '@components/save-form'
+import {
+  DataTableRowKey,
+  NButton,
+  NCascader,
+  NDataTable,
+  NDatePicker,
+  NDescriptions,
+  NDescriptionsItem,
+  NFormItem,
+  NImage,
+  NInput,
+  NModal,
+  NSelect,
+  NSpace,
+  NTag,
+  useDialog,
+  useMessage
+} from 'naive-ui'
+import Pagination from '@components/pagination'
+import TheTooltip from '@components/TheTooltip'
+import AddMusic from './addMusic'
+import { getMapValueByKey, getSelectDataFromObj } from '@/utils/objectUtil'
+import {
+  appKey,
+  musicSheetAudioType,
+  musicSheetAvailableType,
+  musicSheetPaymentType,
+  musicSheetSourceType,
+  musicSheetType
+} from '@/utils/constant'
+import {
+  musicSheetApplicationExtendDel,
+  musicSheetApplicationExtendStatus,
+  musicSheetApplicationOwnerList,
+  musicSheetCategoriesQueryTree,
+  musicSheetPageByApplication
+} from '@views/music-library/api'
+import {
+  musicSheetApplicationExtendSubjectList,
+  sysApplicationPage
+} from '@views/system-manage/api'
+import { filterTimes } from '@/utils/dateUtil'
+import deepClone from '@/utils/deep.clone'
+import { copyText, getOwnerName } from '@views/music-library/musicUtil'
+import UpdateMusic from './updateMusic'
+import MusicPreView from '@views/music-library/music-sheet/modal/musicPreView'
+
+export default defineComponent({
+  name: 'music-sheet-KLX',
+  props: {
+    appKey: {
+      type: String,
+      default: 'KLX'
+    }
+  },
+
+  setup(props) {
+    const dialog = useDialog()
+    const message = useMessage()
+    const state = reactive({
+      loading: false,
+      appId: null as any,
+      pagination: {
+        page: 1,
+        rows: 10,
+        pageTotal: 0
+      },
+      searchForm: {
+        keyword: null,
+        // musicSheetType: null, //曲目类型(SINGLE:单曲 CONCERT:合奏)
+        subjectId: null, //声部ID
+        subjectIds: null, //曲目声部ID集合
+        clientStatus: null, //曲目状态(0:停用,1:启用)
+        status: null,
+        sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
+        paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
+        userId: null, //所属人
+        musicCategoryId: null, //曲目分类ID
+        times: null, // 上传时间
+        audioType: null, //音频类型(HOMEMODE: 自制 COMMON: 普通)
+        exquisiteFlag: null, //精品标志
+        topFlag: null, //是否置顶(0:否;1:是)
+        availableType: null, //可用途径 ORG 机构 PLATFORM 平台
+        appAuditFlag: null, //是否审核版本
+        detailFlag: null, //是否查询详情
+        applicationId: null, //所属人项目ID
+        extendApplicationId: null //所属人项目ID
+      },
+      subjectList: [],
+      dataList: [] as any[],
+      showAddDialog: false,
+      showEditDialog: false,
+      userIdDisable: true,
+      userIdData: [] as any,
+      updateRow: {} as any, // 修改选择的行
+      musicTagList: [] as any, //曲目标签
+      applicationId: null, //应用ID
+      musicPreview: false,
+      musicPreviewScoreType: 'staff', // 预览谱面类型
+      musicScore: null as any,
+      useProjectData: [] as any, // 适用项目行数据
+      musicSheetCategories: [] as any
+    })
+
+    // 获取分类
+    const getMusicSheetCategorieList = async () => {
+      try {
+        const { data } = await musicSheetCategoriesQueryTree({})
+        // state.musicSheetCategories = filterPointCategory(data, 'musicSheetCategoriesList')
+        state.musicSheetCategories = data || []
+        clearEmptyMusicCategory(state.musicSheetCategories)
+      } catch (e) {}
+    }
+
+    const clearEmptyMusicCategory = (data: any) => {
+      for (let i = 0; i < data.length; i++) {
+        if (data[i].musicSheetCategoriesList.length < 1) {
+          data[i].musicSheetCategoriesList = null
+        } else {
+          clearEmptyMusicCategory(data[i].musicSheetCategoriesList)
+        }
+      }
+    }
+
+    onMounted(async () => {
+      state.loading = true
+      // 获取应用APP信息
+      console.log(props.appKey, 'appKey')
+      try {
+        // , appKey: props.appKey,
+        const { data } = await sysApplicationPage({ page: 1, rows: 1, hiddenFlag: true })
+        const tempList = data.rows || []
+        if (!tempList || tempList.length == 0) {
+          state.loading = false
+          message.error('加载项目信息失败')
+          return
+        }
+        tempList.forEach((item: any) => {
+          if(item.appKey === props.appKey) {
+            state.appId = item.id
+            state.applicationId = item.id
+          }
+        })
+        // state.appId = tempList[0].id
+        // state.applicationId = tempList[0].id
+      } catch {}
+
+      // 加载声部
+
+      try {
+        // const { data } = await subjectPage({ page: 1, rows: 999 })
+        // const tempList = data.rows || []
+        // tempList.forEach((item: any) => {
+        //   item.label = item.name
+        //   item.value = item.id + ''
+        // })
+        // state.subjectList = tempList
+        const { data } = await musicSheetApplicationExtendSubjectList({
+          applicationId: state.applicationId
+        })
+        const tempList = data || []
+        tempList.forEach((item: any) => {
+          item.label = item.subjectName
+          item.value = item.subjectId
+        })
+        state.subjectList = tempList
+      } catch {}
+
+      getMusicSheetCategorieList()
+
+      // 加载曲目标签
+      // try {
+        // const { data } = await musicSheetApplicationExtendTagList({ applicationId: state.appId })
+        // if (data && data.length > 0) {
+        //   data.forEach((item: any) => {
+        //     state.musicTagList.push({
+        //       ...item,
+        //       label: item.name,
+        //       value: item.id
+        //     })
+        //   })
+        // }
+        
+      // } catch (err) {}
+
+      // 加载表格数据
+      initUseAppList()
+      getList()
+    })
+
+    const saveForm = ref()
+
+    const onSearch = () => {
+      checkedRowKeysRef.value = []
+      saveForm.value?.submit()
+    }
+    const onBtnReset = () => {
+      saveForm.value?.reset()
+    }
+
+    const onSubmit = () => {
+      state.pagination.page = 1
+      getList()
+    }
+
+    const initUseAppList = async () => {
+      try {
+        const appKeys = Object.keys(appKey)
+        const { data } = await sysApplicationPage({ page: 1, rows: 999 })
+        const tempList = data.rows || []
+        state.useProjectData = []
+        const filter = tempList.filter((next: any) => {
+          return appKeys.includes(next.appKey)
+        })
+        filter.forEach((item: any) => {
+          state.useProjectData.push({
+            ...item,
+            label: item.appName,
+            value: item.id
+          })
+        })
+      } catch {}
+    }
+
+    const checkedRowKeysRef = ref<DataTableRowKey[]>([])
+    const handleCheck = (rowKeys: DataTableRowKey[]) => {
+      checkedRowKeysRef.value = rowKeys
+    }
+
+    const getList = async () => {
+      try {
+        state.loading = true
+        const sourceType = state.searchForm.sourceType
+        let userId = state.searchForm.userId
+        let organizationRoleId = null
+        if (sourceType && sourceType === 'ORG') {
+          organizationRoleId = deepClone(userId)
+          userId = null
+        }
+        const { data } = await musicSheetPageByApplication({
+          ...state.pagination,
+          ...state.searchForm,
+          userId: sourceType && sourceType === 'PERSON' ? state.searchForm.userId : null,
+          organizationRoleId: sourceType && sourceType === 'ORG' ? state.searchForm.userId : null,
+          ...filterTimes(state.searchForm.times, ['startTime', 'endTime']),
+          applicationId: state.applicationId
+        })
+        state.pagination.pageTotal = Number(data.total)
+        state.dataList = data.rows || []
+      } catch {}
+      state.loading = false
+    }
+
+    const onChangeStatus = (row: any) => {
+      const statusStr = row.clientStatus ? '停用' : '启用'
+      dialog.warning({
+        title: '提示',
+        content: `是否${statusStr}?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          try {
+            await musicSheetApplicationExtendStatus({
+              ids: row.applicationExtendId,
+              status: !row.clientStatus
+            })
+            getList()
+            message.success(`${statusStr}成功`)
+          } catch {}
+        }
+      })
+    }
+
+    const onBatchChangeStatus = (status: boolean) => {
+      const length = checkedRowKeysRef.value.length
+      if (length == 0) {
+        message.warning('未选择数据')
+      }
+      const statusStr = !status ? '停用' : '启用'
+      dialog.warning({
+        title: '提示',
+        content: `是否${statusStr}` + length + `条数据?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          try {
+            await musicSheetApplicationExtendStatus({
+              ids: checkedRowKeysRef.value.join(','),
+              status: status
+            })
+            getList()
+            message.success(`${statusStr}成功`)
+          } catch {}
+        }
+      })
+    }
+
+    const getPaymentType = (paymentType: any) => {
+      const paymentTypeName = []
+      if (paymentType && paymentType.length > 0) {
+        for (let i = 0; i < paymentType.length; i++) {
+          const name = getMapValueByKey(
+            paymentType[i],
+            new Map(Object.entries(musicSheetPaymentType))
+          )
+          paymentTypeName.push(name)
+        }
+      }
+      return paymentTypeName.join(',')
+    }
+
+    const updateUserIdData = async (sourceType: any) => {
+      if (!state.searchForm.extendApplicationId) {
+        return
+      }
+      state.userIdData = []
+      state.searchForm.userId = null
+      if (sourceType && sourceType !== 'PLATFORM') {
+        const { data } = await musicSheetApplicationOwnerList({
+          page: 1,
+          rows: 9999,
+          sourceType: sourceType,
+          applicationId: state.searchForm.extendApplicationId
+        })
+        const temp = data.rows || []
+        temp.forEach((next: any) => {
+          state.userIdData.push({
+            ...next,
+            label: sourceType === 'PERSON' ? next.userName : next.organizationRole,
+            value: sourceType === 'PERSON' ? next.userId : next.organizationRoleId
+          })
+        })
+      }
+    }
+
+    const onRemove = (row: any): void => {
+      dialog.warning({
+        title: '提示',
+        content: `删除曲目,是否继续?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          try {
+            await musicSheetApplicationExtendDel(row.applicationExtendId)
+            getList()
+            message.success('删除成功')
+          } catch {}
+        }
+      })
+    }
+
+    const columns = (): any => {
+      return [
+        {
+          type: 'selection'
+        },
+        {
+          title: '曲目名称',
+          key: 'id',
+          render: (row: any) => (
+            <>
+              <NDescriptions labelPlacement="left" column={1}>
+                <NDescriptionsItem label="曲目名称">
+                  <TheTooltip content={row.name} />{' '}
+                </NDescriptionsItem>
+                <NDescriptionsItem label="曲目编号">
+                  <div
+                    onDblclick={() => {
+                      copyText(message, row.id)
+                    }}
+                  >
+                    <TheTooltip content={row.id} />
+                  </div>
+                </NDescriptionsItem>
+              </NDescriptions>
+            </>
+          )
+        },
+        {
+          title: '封面图',
+          key: 'musicCover',
+          render(row: any): JSX.Element {
+            return <NImage width={60} height={60} src={row.musicCover} />
+          }
+        },
+        {
+          title: '曲目信息',
+          key: 'musicSheetCategoriesName',
+          render: (row: any) => (
+            <>
+              <NDescriptions labelPlacement="left" column={1}>
+                <NDescriptionsItem label="曲目来源">
+                  {getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))}
+                </NDescriptionsItem>
+                <NDescriptionsItem label="所属人">
+                  <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
+                </NDescriptionsItem>
+                <NDescriptionsItem label="可用声部">
+                  <TheTooltip content={row.subjectNames} />
+                </NDescriptionsItem>
+              </NDescriptions>
+            </>
+          )
+        },
+        {
+          title: '伴奏类型',
+          key: 'audioType',
+          render: (row: any) => {
+            return (
+              <div>
+                {getMapValueByKey(row.audioType, new Map(Object.entries(musicSheetAudioType)))}
+              </div>
+            )
+          }
+        },
+        {
+          title: '曲目分类',
+          key: 'musicSheetCategoryName'
+        },
+        {
+          title: '上传时间',
+          minWidth: '150px',
+          key: 'createTime',
+          render(row: any) {
+            return (
+              row.createTime
+            )
+          }
+        },
+        {
+          title: '业务曲目状态',
+          key: 'clientStatus',
+          render(row: any) {
+            return (
+              <NTag type={row.clientStatus ? 'primary' : 'default'}>{row.clientStatus ? '启用' : '停用'}</NTag>
+            )
+          }
+        },
+        {
+          title: '平台曲目状态',
+          key: 'status',
+          render(row: any) {
+            return (
+              <NTag type={row.status ? 'primary' : 'default'}>{row.status ? '启用' : '停用'}</NTag>
+            )
+          }
+        },
+        {
+          title: '操作',
+          key: 'operation',
+          fixed: 'right',
+          render(row: any) {
+            return (
+              <NSpace>
+                <NButton
+                  type="primary"
+                  size="small"
+                  text
+                  onClick={() => {
+                    state.musicPreview = true
+                    state.musicScore = row
+                    if ('STAVE' == row.scoreType) {
+                      state.musicPreviewScoreType = 'staff'
+                    } else if ('JIAN' == row.scoreType) {
+                      state.musicPreviewScoreType = 'fixedTone'
+                    } else if ('FIRST' == row.scoreType) {
+                      state.musicPreviewScoreType = 'firstTone'
+                    } else {
+                      return
+                    }
+                  }}
+                >
+                  预览
+                </NButton>
+                <NButton
+                  type="primary"
+                  size="small"
+                  text
+                  v-auth="musicSheetApplicationExtend/status1828741083419410433"
+                  onClick={() => onChangeStatus(row)}
+                >
+                  {row.clientStatus ? '停用' : '启用'}
+                </NButton>
+                <NButton
+                  type="primary"
+                  size="small"
+                  text
+                  v-auth="musicSheetApplicationExtend/update1828741129602891777"
+                  onClick={() => {
+                    state.showEditDialog = true
+                    state.updateRow = row
+                  }}
+                >
+                  修改
+                </NButton>
+                <NButton
+                  type="primary"
+                  size="small"
+                  text
+                  disabled={!!row.clientStatus}
+                  onClick={() => onRemove(row)}
+                  v-auth="musicSheetApplicationExtend/del1828741276168650753"
+                >
+                  删除
+                </NButton>
+              </NSpace>
+            )
+          }
+        }
+      ]
+    }
+
+    return () => {
+      return (
+        <div class="system-menu-container">
+          <SaveForm
+            ref={saveForm}
+            model={state.searchForm}
+            onSubmit={onSubmit}
+            saveKey="music-sheet-klx_jg"
+            onSetModel={(val: any) => (state.searchForm = val)}
+          >
+            <NFormItem label="关键词" path="keyword">
+              <NInput
+                placeholder="请输入曲目名称/编号"
+                v-model:value={state.searchForm.keyword}
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="曲目来源" path="sourceType">
+              <NSelect
+                placeholder="请选择曲目来源"
+                v-model:value={state.searchForm.sourceType}
+                options={getSelectDataFromObj(musicSheetSourceType)}
+                onUpdateValue={async (value: any) => {
+                  state.userIdData = []
+                  state.searchForm.userId = null
+                  if (value && value !== 'PLATFORM') {
+                    await updateUserIdData(value)
+                    state.userIdDisable = !state.searchForm.extendApplicationId
+                  } else {
+                    state.userIdDisable = true
+                  }
+                }}
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="所属项目" path="applicationId">
+              <NSelect
+                placeholder="请选择所属项目"
+                v-model:value={state.searchForm.extendApplicationId}
+                options={state.useProjectData}
+                clearable
+                onUpdateValue={async (value: any) => {
+                  state.searchForm.extendApplicationId = value
+                  if (value) {
+                    await updateUserIdData(state.searchForm.sourceType)
+                    state.userIdDisable = !(
+                      state.searchForm.sourceType && state.searchForm.sourceType !== 'PLATFORM'
+                    )
+                  } else {
+                    state.searchForm.userId = null
+                    state.userIdDisable = true
+                    state.userIdData = []
+                  }
+                }}
+              />
+            </NFormItem>
+            <NFormItem label="所属人" path="userId">
+              <NSelect
+                filterable
+                placeholder="请选择所属人"
+                disabled={state.userIdDisable}
+                v-model:value={state.searchForm.userId}
+                options={state.userIdData}
+                clearable
+              ></NSelect>
+            </NFormItem>
+            {/* <NFormItem label="谱面渲染" path="subjectType">
+              <NSelect
+                placeholder="请选择谱面渲染"
+                v-model:value={state.searchForm.musicSheetType}
+                options={getSelectDataFromObj(musicSheetType)}
+                clearable
+              />
+            </NFormItem> */}
+            <NFormItem label="伴奏类型" path="audioType">
+              <NSelect
+                placeholder="请选择伴奏类型"
+                v-model:value={state.searchForm.audioType}
+                options={getSelectDataFromObj(musicSheetAudioType)}
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="可用声部" path="subjectId">
+              <NSelect
+                placeholder="请选择可用声部"
+                v-model:value={state.searchForm.subjectId}
+                options={state.subjectList}
+                clearable
+                filterable
+              />
+            </NFormItem>
+            <NFormItem label="曲目分类" path="musicTagIds">
+              <NCascader
+                valueField="id"
+                labelField="name"
+                children-field="musicSheetCategoriesList"
+                placeholder="请选择曲目分类"
+                v-model:value={state.searchForm.musicCategoryId}
+                options={state.musicSheetCategories}
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="业务曲目状态" path="clientStatus">
+              <NSelect
+                v-model:value={state.searchForm.clientStatus}
+                placeholder="请选择业务曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="平台曲目状态" path="status">
+              <NSelect
+                v-model:value={state.searchForm.status}
+                placeholder="请选择平台曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="上传时间" path="times">
+              <NDatePicker
+                v-model:value={state.searchForm.times}
+                type="daterange"
+                clearable
+                value-format="yyyy.MM.dd"
+                startPlaceholder="开始时间"
+                endPlaceholder="结束时间"
+              />
+            </NFormItem>
+            <NFormItem>
+              <NSpace>
+                <NButton type="primary" onClick={onSearch}>
+                  搜索
+                </NButton>
+                <NButton type="default" onClick={onBtnReset}>
+                  重置
+                </NButton>
+              </NSpace>
+            </NFormItem>
+          </SaveForm>
+
+          <div class={['section-container']}>
+            <NSpace style={{ paddingBottom: '12px' }}>
+              <NButton
+                type="primary"
+                v-auth="musicSheetApplicationExtend/saveBatch1828740811787894786"
+                onClick={() => {
+                  state.showAddDialog = true
+                }}
+              >
+                添加曲目
+              </NButton>
+              <NButton
+                disabled={checkedRowKeysRef.value.length == 0}
+                v-auth="musicSheetApplicationExtend/status1828741083419410433"
+                onClick={() => {
+                  onBatchChangeStatus(false)
+                }}
+              >
+                批量停用
+              </NButton>
+              <NButton
+                disabled={checkedRowKeysRef.value.length == 0}
+                v-auth="musicSheetApplicationExtend/status1828741083419410433"
+                onClick={() => {
+                  onBatchChangeStatus(true)
+                }}
+              >
+                批量启用
+              </NButton>
+            </NSpace>
+
+            <NDataTable
+              loading={state.loading}
+              columns={columns()}
+              data={state.dataList}
+              rowKey={(row: any) => row.applicationExtendId}
+              v-model:checkedRowKeys={checkedRowKeysRef.value}
+              scrollX={'2000'}
+            ></NDataTable>
+
+            <Pagination
+              v-model:page={state.pagination.page}
+              v-model:pageSize={state.pagination.rows}
+              v-model:pageTotal={state.pagination.pageTotal}
+              onList={getList}
+              sync
+              saveKey="music-sheet-klx_jg"
+            ></Pagination>
+          </div>
+
+          <NModal
+            v-model:show={state.showAddDialog}
+            preset="dialog"
+            showIcon={false}
+            title={'添加曲目'}
+            style={{ width: '1300px' }}
+          >
+            <AddMusic
+              onClose={() => (state.showAddDialog = false)}
+              onGetList={onSubmit}
+              subjectList={state.subjectList}
+              appId={state.appId}
+              musicSheetTagList={state.musicTagList}
+            />
+          </NModal>
+          <NModal
+            v-model:show={state.showEditDialog}
+            preset="dialog"
+            showIcon={false}
+            title={'修改曲目'}
+            style={{ width: '500px' }}
+          >
+            <UpdateMusic
+              onClose={() => (state.showEditDialog = false)}
+              onGetList={() => {
+                state.pagination.page = 1
+                getList()
+              }}
+              rowData={state.updateRow}
+              appId={state.appId}
+            />
+          </NModal>
+          <NModal
+            blockScroll={true}
+            v-model:show={state.musicPreview}
+            preset="dialog"
+            showIcon={false}
+            title={'曲目预览'}
+            style={{ width: 'auto' }}
+          >
+            <MusicPreView item={state.musicScore} scoreType={state.musicPreviewScoreType} />
+          </NModal>
+        </div>
+      )
+    }
+  }
+})

+ 197 - 0
src/views/music-library/project-music-sheet/module/klx_jg/updateMusic.tsx

@@ -0,0 +1,197 @@
+import {defineComponent, onMounted, reactive, ref} from "vue";
+import {NButton, NForm, NFormItem, NInputNumber, NSelect, NSpace, useMessage} from "naive-ui";
+import {musicSheetApplicationExtendCategoryApplicationExtendInfo, musicSheetApplicationExtendUpdate} from "@views/music-library/api";
+import {getSelectDataFromObj} from "@/utils/objectUtil";
+import {musicSheetAvailableType, musicSheetPaymentType, scoreType} from "@/utils/constant";
+import {formatTree} from "@views/music-library/musicUtil";
+
+export default defineComponent({
+  name: 'project-music-cooleshow-edu-updateMusic',
+  props: {
+    appId: {
+      type: String,
+      required: true
+    },
+    rowData: {
+      type: Object,
+      required: true
+    },
+    musicSheetTagList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  emits: ['close', 'getList'],
+  setup(props, {slots, attrs, emit}) {
+    const message = useMessage()
+    const btnLoading = ref(false)
+    const forms = reactive({
+      sortNo: null as any,
+      isConvertibleScore: null as any,//是否支持转简谱
+      status: null,
+      scoreType: null as any,//默认谱面
+    })
+    const formsRef = ref()
+
+    const state = reactive({
+      rowData: null as any,
+      musicSheetTagList: [] as any,
+    })
+
+    onMounted(async () => {
+      state.rowData = props.rowData
+      state.musicSheetTagList = props.musicSheetTagList
+      state.musicSheetTagList.map((item: any) => {
+        item.disabled = !item.enable
+      })
+      const {data} = await musicSheetApplicationExtendCategoryApplicationExtendInfo({musicSheetId: state.rowData.id, applicationId: props.appId}) as any
+      if (!data) {
+        message.error("加载应用失败")
+        return
+      }
+      forms.sortNo = data[0].sortNo
+      forms.isConvertibleScore = data[0].isConvertibleScore
+      forms.scoreType = data[0].scoreType
+      forms.status = data[0].status
+    })
+
+    const onSubmit = async () => {
+      formsRef.value.validate(async (error: any) => {
+        if (error) return false
+        btnLoading.value = true
+        try {
+          const res = await musicSheetApplicationExtendUpdate(
+              {
+                ...forms,
+                musicSheetId: state.rowData.id,
+                applicationId: props.appId
+              }
+          ) as any;
+          if (res && res.code === 200) {
+            emit('close')
+            emit('getList')
+          }
+        } catch (error) {
+        }
+        btnLoading.value = false
+      })
+    }
+
+    return () => {
+      return (
+          <div style="background: #fff; padding-top: 12px">
+            <NForm
+                ref={formsRef}
+                labelPlacement="top"
+                model={forms}
+                label-placement="left"
+                label-width="auto"
+            >
+              <NFormItem
+                  label="默认谱面"
+                  path="scoreType"
+                  rule={[
+                    {
+                      required: true,
+                      message: '请选择默认谱面'
+                    }
+                  ]}
+              >
+                <NSelect
+                    v-model:value={forms.scoreType}
+                    placeholder="请选择默认谱面"
+                    options={getSelectDataFromObj(scoreType)}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="支持转谱"
+                  path="isConvertibleScore"
+                  rule={[
+                    {
+                      required: true,
+                      message: '请选择是否支持转谱',
+                      trigger: ['input', 'blur'],
+                      type: 'boolean'
+                    }
+                  ]}
+              >
+                <NSelect
+                    v-model:value={forms.isConvertibleScore}
+                    options={
+                      [
+                        {
+                          label: '是',
+                          value: true
+                        },
+                        {
+                          label: '否',
+                          value: false
+                        }
+                      ] as any
+                    }
+                    placeholder="请选择是否支持转谱"
+                    onUpdateValue={async (value: any) => {
+                      if (!value) {
+                        //如果不支持,修改默认谱面
+                        // forms.scoreType = 'STAVE'
+                      }
+                    }}
+                    clearable
+                ></NSelect>
+              </NFormItem>
+              <NFormItem
+                  label="是否启用"
+                  path="status"
+                  rule={[
+                    {
+                      required: true,
+                      message: '请选择是否启用'
+                    }
+                  ]}
+              >
+                <NSelect
+                    placeholder="请选择是否启用"
+                    options={[
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any}
+                    v-model:value={forms.status}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="排序值"
+                  path="sortNo"
+              >
+                <NInputNumber
+                    v-model:value={forms.sortNo}
+                    placeholder="请输入排序值"
+                    clearable
+                    min={0}
+                    max={9999}
+                    style={{width: '100%'}}
+                />
+              </NFormItem>
+            </NForm>
+
+            <NSpace justify="end">
+              <NButton onClick={() => emit('close')}>取消</NButton>
+              <NButton type="primary" onClick={onSubmit}
+                       loading={btnLoading.value}
+                       disabled={btnLoading.value}
+              >
+                保存
+              </NButton>
+            </NSpace>
+          </div>
+      )
+    }
+  }
+})

+ 97 - 0
src/views/music-library/project-music-sheet/module/kt/addMusic.tsx

@@ -83,6 +83,7 @@ export default defineComponent({
       startSortNum: null as any, // 排序起始值
       projectMusicCategoryId: null as any, // 曲目分类ID
       isConvertibleScore: null as any, //是否支持转简谱
+      status: false, // 是否启用
       scoreType: null as any, //默认谱面
 
       useProjectData: [] as any, // 适用项目行数据
@@ -199,6 +200,10 @@ export default defineComponent({
           message.error('是否支持转谱不能为空')
           return
         }
+        if (item.status == null) {
+          message.error('是否启用不能为空')
+          return
+        }
         if (!item.sortNo) {
           item.sortNo = 0
         }
@@ -616,6 +621,97 @@ export default defineComponent({
           )
         }
       })
+
+      field.push({
+        title(column: any) {
+          return (
+            <NSpace>
+              是否启用
+              <NButton
+                type="primary"
+                size="small"
+                text
+                onClick={() => {
+                  dialogs.create({
+                    title: '是否启用',
+                    showIcon: false,
+                    content: () => {
+                      return h(
+                        'div',
+                        {
+                          class: 'flex flex-col justify-center items-center text-14px'
+                        },
+                        [
+                          // icon
+                          h(NSelect, {
+                            onUpdateValue(v) {
+                              state.status = v
+                            },
+                            options: [
+                              {
+                                label: '是',
+                                value: true
+                              },
+                              {
+                                label: '否',
+                                value: false
+                              }
+                            ] as any
+                          })
+                        ]
+                      )
+                    },
+                    positiveText: '确定',
+                    negativeText: '取消',
+                    onPositiveClick: () => {
+                      for (let i = 0; i < state.selectRowData.length; i++) {
+                        const item = state.selectRowData[i]
+                        item.status = state.status
+                      }
+                    }
+                  })
+                }}
+              >
+                <NIcon size={15} style="padding-left: 5px;margin-top:4px">
+                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                    <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                    <path
+                      d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z"
+                      fill="currentColor"
+                    ></path>
+                  </svg>
+                </NIcon>
+              </NButton>
+            </NSpace>
+          )
+        },
+        key: 'status',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+            <NSelect
+              value={row.status}
+              options={[
+                {
+                  label: '是',
+                  value: true
+                },
+                {
+                  label: '否',
+                  value: false
+                } as any
+              ]}
+              onUpdateValue={(value: any) => {
+                row.status = value
+              }}
+              filterable
+              clearable
+            />
+          )
+        }
+      })
+
       field.push({
         title(column: any) {
           return (
@@ -748,6 +844,7 @@ export default defineComponent({
             return row.id === next.id
           })
           if (!find) {
+            next.status = false
             state.selectRowData.push(next)
           }
         }

+ 39 - 13
src/views/music-library/project-music-sheet/module/kt/music-sheet-kt.tsx

@@ -65,7 +65,8 @@ export default defineComponent({
         subjectId: null, //声部ID
         subjectIds: null, //曲目声部ID集合
         musicCategoryIds: null, //曲目分类ID
-        status: null, //曲目状态(0:停用,1:启用)
+        clientStatus: null, //曲目状态(0:停用,1:启用)
+        status: null,
         sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
         paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
         userId: null, //所属人
@@ -195,7 +196,7 @@ export default defineComponent({
     }
 
     const onChangeStatus = (row: any) => {
-      const statusStr = row.status ? '停用' : '启用'
+      const statusStr = row.clientStatus ? '停用' : '启用'
       dialog.warning({
         title: '提示',
         content: `是否${statusStr}?`,
@@ -205,7 +206,7 @@ export default defineComponent({
           try {
             await musicSheetApplicationExtendStatus({
               ids: row.applicationExtendId,
-              status: !row.status
+              status: !row.clientStatus
             })
             getList()
             message.success(`${statusStr}成功`)
@@ -369,20 +370,26 @@ export default defineComponent({
           }
         },
         {
-          title: '上传',
+          title: '上传时间',
           minWidth: '150px',
           key: 'composer',
           render(row: any) {
             return (
-              <NDescriptions labelPlacement="left" column={1}>
-                <NDescriptionsItem label="上传人">{row.createByName}</NDescriptionsItem>
-                <NDescriptionsItem label="上传时间">{row.createTime}</NDescriptionsItem>
-              </NDescriptions>
+              row.createTime
+            )
+          }
+        },
+        {
+          title: '业务曲目状态',
+          key: 'clientStatus',
+          render(row: any) {
+            return (
+              <NTag type={row.clientStatus ? 'primary' : 'default'}>{row.clientStatus ? '启用' : '停用'}</NTag>
             )
           }
         },
         {
-          title: '状态',
+          title: '平台曲目状态',
           key: 'status',
           render(row: any) {
             return (
@@ -424,7 +431,7 @@ export default defineComponent({
                   v-auth="musicSheetApplicationExtend/status1751235210464198657"
                   onClick={() => onChangeStatus(row)}
                 >
-                  {row.status ? '停用' : '启用'}
+                  {row.clientStatus ? '停用' : '启用'}
                 </NButton>
                 <NButton
                   type="primary"
@@ -442,7 +449,7 @@ export default defineComponent({
                   type="primary"
                   size="small"
                   text
-                  disabled={!!row.status}
+                  disabled={!!row.clientStatus}
                   onClick={() => onRmove(row)}
                   v-auth="musicSheetApplicationExtend/del1770696070576254977"
                 >
@@ -588,10 +595,29 @@ export default defineComponent({
                   clearable
               />
             </NFormItem>
-            <NFormItem label="状态" path="status">
+            <NFormItem label="业务曲目状态" path="clientStatus">
+              <NSelect
+                v-model:value={state.searchForm.clientStatus}
+                placeholder="请选择业务曲目状态"
+                options={
+                  [
+                    {
+                      label: '启用',
+                      value: true
+                    },
+                    {
+                      label: '停用',
+                      value: false
+                    }
+                  ] as any
+                }
+                clearable
+              />
+            </NFormItem>
+            <NFormItem label="平台曲目状态" path="status">
               <NSelect
                 v-model:value={state.searchForm.status}
-                placeholder="请选择状态"
+                placeholder="请选择平台曲目状态"
                 options={
                   [
                     {

+ 25 - 4
src/views/music-library/project-music-sheet/module/kt/updateMusic.tsx

@@ -30,6 +30,7 @@ export default defineComponent({
       sortNo: null as any,
       paymentType: null as any,
       isConvertibleScore: null as any,//是否支持转简谱
+      status: null as any, // 是否启用
       scoreType: null as any,//默认谱面
     })
     const formsRef = ref()
@@ -53,7 +54,7 @@ export default defineComponent({
       forms.paymentType = data[0].paymentType
       forms.isConvertibleScore = data[0].isConvertibleScore
       forms.scoreType = data[0].scoreType
-
+      forms.status = data[0].status
     })
 
     const onSubmit = async () => {
@@ -192,15 +193,35 @@ export default defineComponent({
                 ></NSelect>
               </NFormItem>
               <NFormItem
-                  label="排序值"
-                  path="sortNo"
+                  label="是否启用"
+                  path="status"
                   rule={[
                     {
                       required: true,
-                      message: '请输入排序值'
+                      message: '请选择是否启用'
                     }
                   ]}
               >
+                <NSelect
+                    placeholder="请选择是否启用"
+                    options={[
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any}
+                    v-model:value={forms.status}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="排序值"
+                  path="sortNo"
+              >
                 <NInputNumber
                     v-model:value={forms.sortNo}
                     placeholder="请输入排序值"

+ 1 - 1
vite.config.ts

@@ -21,7 +21,7 @@ function pathResolve(dir: string) {
 // const proxyUrl = 'https://dev.lexiaoya.cn'
 // const proxyUrl = 'http://127.0.0.1:7293/'
 // const proxyUrl = 'https://resource.colexiu.com/'
-const proxyUrl = 'https://test.resource.colexiu.com/'
+const proxyUrl = 'https://dev.resource.colexiu.com/'
 // https://test.resource.colexiu.com/
 
 export default ({ command, mode }: ConfigEnv): UserConfig => {