Browse Source

约束调整

yuanliang 1 year ago
parent
commit
ab30f25f97

+ 1 - 1
src/utils/constant.ts

@@ -233,7 +233,7 @@ export const heardLevelType = {
 
 // 曲目类型
 export const musicSheetType = {
-  SINGLE: '单曲',
+  SINGLE: '独奏',
   CONCERT: '合奏'
 } as any
 

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

@@ -1,15 +1,15 @@
 import SaveForm from '@/components/save-form'
 import Pagination from '@/components/pagination'
-import {NButton, NCascader, NDataTable, NFormItem, NIcon, NImage, NInput, NModal, NSelect, NSpace, NTag, useDialog, useMessage} from 'naive-ui'
+import {NButton, NDataTable, NFormItem, NIcon, NImage, NInput, NModal, NSelect, NSpace, NTag, useDialog, useMessage} from 'naive-ui'
 import {defineComponent, onMounted, reactive, ref, watch} from 'vue'
-import {musicSheetCategoriesPage, musicSheetCategoriesQueryTree, musicSheetPage, musicSheetRemove, musicSheetStatus, musicTagPage} from '../../api'
+import {musicSheetCategoriesQueryTree, musicSheetPage, musicSheetRemove, musicSheetStatus, musicTagPage} from '../../api'
 import MusicOperation from '../modal/music-operation'
 import {subjectPage} from '@/views/system-manage/api'
 import MusicPreView from '../modal/musicPreView'
 import {filterPointCategory} from '@/views/teaching-manage/unit-test'
 import UseProject from "@views/music-library/music-sheet/modal/use-project";
 import {getMapValueByKey} from "@/utils/filters";
-import {musicSheetUseApp, musicSheetSourceType, musicSheetType} from "@/utils/constant";
+import {musicSheetSourceType, musicSheetType} from "@/utils/constant";
 import {getSelectDataFromObj} from "@/utils/objectUtil";
 import {sysApplicationPage} from "@views/menu-manage/api";
 
@@ -314,7 +314,7 @@ export default defineComponent({
         const tempList = data.rows || []
         tempList.forEach((item: any) => {
           item.label = item.name
-          item.value = item.id
+          item.value = item.id + ''
         })
         state.subjectList = tempList
       } catch {

+ 0 - 262
src/views/music-library/music-sheet/component/tag-list.tsx

@@ -1,262 +0,0 @@
-import SaveForm from '@/components/save-form'
-import Pagination from '@/components/pagination'
-import {
-  NButton,
-  NDataTable,
-  NFormItem,
-  NInput,
-  NModal,
-  NSpace,
-  NTag,
-  useDialog,
-  useMessage
-} from 'naive-ui'
-import { defineComponent, onMounted, reactive, ref } from 'vue'
-import { musicTagPage, musicTagRemove, musicTagState } from '../../api'
-import TagOperation from '../modal/tag-operation'
-
-export default defineComponent({
-  name: 'content-flash',
-  setup() {
-    const dialog = useDialog()
-    const message = useMessage()
-    const state = reactive({
-      loading: false,
-      pagination: {
-        page: 1,
-        rows: 10,
-        pageTotal: 0
-      },
-      searchForm: {
-        keyword: null
-      },
-      dataList: [] as any,
-      visiableTag: false,
-      tagOperation: 'add',
-      tagData: {} as any
-    })
-
-    const columns = () => {
-      return [
-        {
-          title: '编号',
-          key: 'id'
-        },
-        {
-          title: '名称',
-          key: 'name'
-        },
-        // {
-        //   title: '平台乐谱启用/总数',
-        //   key: 'enablePlatformMusicSheetNum',
-        //   render(row: any) {
-        //     return `${row.enablePlatformMusicSheetNum}/${row.musicPlatformSheetNum}`
-        //   }
-        // },
-        // {
-        //   title: '老师乐谱启用/总数',
-        //   key: 'enableTeacherMusicSheetNum',
-        //   render(row: any) {
-        //     return `${row.enableTeacherMusicSheetNum}/${row.musicTeacherSheetNum}`
-        //   }
-        // },
-        {
-          title: '更新人',
-          key: 'updateUser'
-        },
-        {
-          title: '更新时间',
-          key: 'updateTime'
-        },
-        {
-          title: '排序',
-          key: 'sortNumber'
-        },
-        {
-          title: '状态',
-          key: 'state',
-          render(row: any) {
-            return (
-              <NTag type={row.state ? 'primary' : 'default'}>{row.state ? '启用' : '停用'}</NTag>
-            )
-          }
-        },
-        {
-          title: '操作',
-          key: 'operation',
-          render(row: any) {
-            return (
-              <NSpace>
-                <NButton
-                  type="primary"
-                  size="small"
-                  text
-                  onClick={() => onChangeState(row)}
-                  //v-auth="musicTag/state1602302067191672833"
-                >
-                  {row.state ? '停用' : '启用'}
-                </NButton>
-
-                <NButton
-                  type="primary"
-                  size="small"
-                  text
-                  //v-auth="musicTag/update1602301883418243073"
-                  onClick={() => {
-                    state.visiableTag = true
-                    state.tagOperation = 'edit'
-                    state.tagData = row
-                  }}
-                >
-                  修改
-                </NButton>
-                <NButton
-                  type="primary"
-                  size="small"
-                  text
-                  onClick={() => onRmove(row)}
-                  //v-auth="musicTag/remove1602301979954343937"
-                >
-                  删除
-                </NButton>
-              </NSpace>
-            )
-          }
-        }
-      ]
-    }
-
-    const onChangeState = (row: any) => {
-      // musicTag/state
-      const statusStr = row.state ? '停用' : '启用'
-      dialog.warning({
-        title: '警告',
-        content: `是否${statusStr}?`,
-        positiveText: '确定',
-        negativeText: '取消',
-        onPositiveClick: async () => {
-          try {
-            await musicTagState({
-              id: row.id
-            })
-            getList()
-            message.success(`${statusStr}成功`)
-          } catch {}
-        }
-      })
-    }
-
-    const onRmove = (row: any): void => {
-      dialog.warning({
-        title: '警告',
-        content: `删除"${row.name}",是否继续?`,
-        positiveText: '确定',
-        negativeText: '取消',
-        onPositiveClick: async () => {
-          try {
-            await musicTagRemove({ id: row.id })
-            getList()
-            message.success('删除成功')
-          } catch {}
-        }
-      })
-    }
-
-    const getList = async () => {
-      try {
-        state.loading = true
-        const { data } = await musicTagPage({ ...state.pagination, ...state.searchForm })
-        state.loading = false
-        state.pagination.pageTotal = Number(data.total)
-        state.dataList = data.rows || []
-      } catch {
-        state.loading = false
-      }
-    }
-
-    const saveForm = ref()
-    const onSubmit = () => {
-      state.pagination.page = 1
-      getList()
-    }
-
-    const onSearch = () => {
-      saveForm.value?.submit()
-    }
-    const onBtnReset = () => {
-      saveForm.value?.reset()
-    }
-
-    onMounted(() => {
-      getList()
-    })
-    return () => (
-      <div class="system-menu-container">
-        <SaveForm
-          ref={saveForm}
-          model={state.searchForm}
-          onSubmit={onSubmit}
-          saveKey="tag-list"
-          onSetModel={(val: any) => (state.searchForm = val)}
-        >
-          <NFormItem label="名称" path="keyword">
-            <NInput placeholder="请输入名称" v-model:value={state.searchForm.keyword} clearable />
-          </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="musicTag/save1602301806310158338"
-              onClick={() => {
-                state.visiableTag = true
-                state.tagOperation = 'add'
-                state.tagData = {}
-              }}
-            >
-              添加曲目标签
-            </NButton>
-          </NSpace>
-
-          <NDataTable
-            loading={state.loading}
-            columns={columns()}
-            data={state.dataList}
-          ></NDataTable>
-          <Pagination
-            v-model:page={state.pagination.page}
-            v-model:pageSize={state.pagination.rows}
-            v-model:pageTotal={state.pagination.pageTotal}
-            onList={getList}
-            sync
-            saveKey="tag-list"
-          ></Pagination>
-        </div>
-        <NModal
-          v-model:show={state.visiableTag}
-          preset="dialog"
-          showIcon={false}
-          title={state.tagOperation === 'add' ? '新增曲目标签' : '修改曲目标签'}
-          style={{ width: '500px' }}
-        >
-          <TagOperation
-            type={state.tagOperation}
-            data={state.tagData}
-            onClose={() => (state.visiableTag = false)}
-            onGetList={getList}
-          />
-        </NModal>
-      </div>
-    )
-  }
-})

+ 186 - 62
src/views/music-library/music-sheet/modal/music-operation.tsx

@@ -9,6 +9,8 @@ import axios from 'axios'
 import {CheckboxGroup} from "vant";
 import {musicSheetSourceType, musicSheetType} from "@/utils/constant";
 import {getSelectDataFromObj} from "@/utils/objectUtil";
+import {musicalInstrumentPage} from "@views/system-manage/subject-manage/api";
+import {subjectPage} from "@views/system-manage/api";
 
 /**
  * 获取指定元素下一个Note元素
@@ -253,38 +255,47 @@ export default defineComponent({
       playMode: 'MP3', // 播放类型
       xmlFileUrl: null, // XML
       midiUrl: null, // mid
-      metronomeUrl: null, // 伴奏 根据mp3Type 是否是为包含节拍器
       name: null, // 曲目名称
       musicTag: [] as any, // 曲目标签
       composer: null, // 音乐人
       playSpeed: null, // 曲谱速度
-      showFingering: null as any, // 是否显示指法
-      canEvaluate: null as any, // 是否评测
-      subjectIds: null as any, // 可用声部
-      notation: null as any, // 能否转和简谱
-      auditVersion: null as any, // 审核版本
-      audioType: 'HOMEMODE', // 伴奏类型
-      sortNumber: null, // 排序
+      // showFingering: null as any, // 是否显示指法
+      // canEvaluate: null as any, // 是否评测
+      // notation: null as any, // 能否转和简谱
+      // auditVersion: null as any, // 审核版本
+      // sortNumber: null, // 排序
       musicCover: null, // 曲谱封面
       remark: null, // 曲谱描述
-      background: [] as any, // 原音
+      musicSheetSoundList: [] as any, // 原音
       musicSheetCategoriesId: null,
       status: false,
       musicSheetType: null, // 曲目类型
-      sourceType: undefined,
+      sourceType: undefined, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
       userId: null, // 所属人
-      isPlayBeat: 1, // 是否播放节拍器
-      playStyle: undefined, // 播放方式
       appAuditFlag: false, // 是否审核版本
-      midiFileUrl: null, // 伴奏文件
-      musicalInstrumentIds: null,  //可用乐器
+      midiFileUrl: null, // 伴奏文件 MIDI文件(保留字段)
+      subjectIds: '', // 可用声部
+      subjectIdList: [] as any, // 可用声部
+      musicalInstrumentIds: '',  //可用乐器
+      musicalInstrumentIdList: [] as any,  //可用乐器
       musicCategoryId: null,  //曲目分类
+      musicSheetAccompanimentList: [],  //曲目伴奏
+      audioType: 'HOMEMODE', // 伴奏类型
+      isPlayBeat: 1, // 是否播放节拍器
+      isUseSystemBeat: '1', // 是否使用系统节拍器(0:否;1:是)
+      repeatedBeats: '0', // 是否重复节拍时长
+      evaluationStandard: 'AMPLITUDE', // 评分标准 节奏 AMPLITUDE 音准 FREQUENCY 分贝 DECIBELS
     })
     const state = reactive({
+      loading: false,
       tagList: [...props.tagList] as any, // 标签列表
       xmlFirstSpeed: null as any, // 第一个音轨速度
       partListNames: [] as any, // 所有音轨声部列表
-      musicSheetCategories: [...props.musicSheetCategories] as any
+      musicSheetCategories: [...props.musicSheetCategories] as any,
+      musicSheetAccompanimentNames: [] as any,
+      instrumentData: [],
+      instrumentList: [],
+      subjectList: [],
     })
     const gradualData = reactive({
       list: [] as any[],
@@ -305,13 +316,14 @@ export default defineComponent({
           return
         }
         try {
+          //extConfigJson: {"repeatedBeats":0,"gradualTimes":{"75":"02:38:60","77":"02:43:39"}}
           const obj = {
             ...forms,
             musicTag: '-1',
             extConfigJson: JSON.stringify({gradualTimes: forms.graduals})
           }
           if (forms.audioType == 'MIDI') {
-            obj.background = []
+            obj.musicSheetSoundList = []
           }
           btnLoading.value = true
           if (props.type === 'add') {
@@ -332,7 +344,7 @@ export default defineComponent({
       })
     }
 
-    // 上传XML,初始化音轨 音轨速度
+    // 上传XML,初始化音轨 音轨速度 乐器、声部
     const readFileInputEventAsArrayBuffer = (file: any) => {
       const xmlRead = new FileReader()
       xmlRead.onload = (res) => {
@@ -345,17 +357,17 @@ export default defineComponent({
         state.partListNames = getPartListNames(res?.target?.result as any) as any
         // 这里是如果没有当前音轨就重新写
         for (let j = 0; j < state.partListNames.length; j++) {
-          if (!forms.background[j]) {
-            forms.background.push({audioFileUrl: null, track: null})
+          if (!forms.musicSheetSoundList[j]) {
+            forms.musicSheetSoundList.push({audioFileUrl: null, track: null})
           }
-          forms.background[j].track = state.partListNames[j].value
+          forms.musicSheetSoundList[j].track = state.partListNames[j].value
         }
 
         // 循环添加所在音轨的原音
-        for (let index = forms.background.length; index < state.partListNames.length; index++) {
+        for (let index = forms.musicSheetSoundList.length; index < state.partListNames.length; index++) {
           const part = state.partListNames[index].value
           const sysData = {
-            ...forms.background[0],
+            ...forms.musicSheetSoundList[0],
             track: part
           }
           if (!sysData.speed) {
@@ -364,8 +376,8 @@ export default defineComponent({
           createSys(sysData)
         }
 
-        if (forms.background.length == 0) {
-          forms.background.push({audioFileUrl: '', track: ''})
+        if (forms.musicSheetSoundList.length == 0) {
+          forms.musicSheetSoundList.push({audioFileUrl: '', track: ''})
         }
 
 
@@ -373,7 +385,7 @@ export default defineComponent({
       xmlRead.readAsText(file)
     }
 
-    // 获取xml中所有轨道
+    // 获取xml中所有轨道 乐器
     const getPartListNames = (xml: any) => {
       if (!xml) return []
       const xmlParse = new DOMParser().parseFromString(xml, 'text/xml')
@@ -388,13 +400,39 @@ export default defineComponent({
       })
 
       if (partListNames.length > 0) {
-        forms.background = forms.background.slice(0, partListNames.length)
+        forms.musicSheetSoundList = forms.musicSheetSoundList.slice(0, partListNames.length)
       }
 
       state.xmlFirstSpeed = xmlParse.getElementsByTagName('per-minute')?.[0]?.textContent || ''
       if (!forms.playSpeed) {
         forms.playSpeed = state.xmlFirstSpeed
       }
+
+      // 乐器
+      const instrumentCodeList: any = [];
+      const instrumentEle = xmlParse.getElementsByTagName('virtual-instrument');
+      for (let index = 0; index < instrumentEle.length; index++) {
+        const note = instrumentEle[index]
+        const instrumentCode = note.getElementsByTagName('virtual-name')?.[0].textContent || '';
+        if (instrumentCode && !instrumentCodeList.includes(instrumentCode)) {
+          instrumentCodeList.push(instrumentCode);
+        }
+      }
+      const codeIdMap = new Map<string, string>();
+      state.instrumentData.forEach((data: any) => {
+        codeIdMap.set(data.code, data.id + '');
+      })
+      forms.musicalInstrumentIdList = [];
+      instrumentCodeList.forEach((code: string) => {
+        if (codeIdMap.has(code)) {
+          forms.musicalInstrumentIdList.push(codeIdMap.get(code));
+        }
+      })
+
+      // 声部
+      if (forms.musicalInstrumentIdList.length > 0) {
+        showBackSubject(forms.musicalInstrumentIdList);
+      }
       return partListNames
     }
 
@@ -403,7 +441,7 @@ export default defineComponent({
       const _names = state.partListNames.filter((n: any) => n.value?.toLocaleUpperCase?.() != 'COMMON')
       const partListNames = deepClone(_names) || []
       partListNames.forEach((item: any) => {
-        const index = forms.background.findIndex((ground: any) => item.value == ground.track)
+        const index = forms.musicSheetSoundList.findIndex((ground: any) => item.value == ground.track)
         if (index > -1 && track != item.value) {
           item.disabled = true
         } else {
@@ -413,9 +451,40 @@ export default defineComponent({
       return partListNames || []
     }
 
+    // 获取乐器信息
+
+    const initInstrumentList = async () => {
+      if (state.instrumentList && state.instrumentList.length > 0) {
+        return
+      }
+      try {
+        const {data} = await musicalInstrumentPage({page: 1, rows: 999})
+        const tempList = data.rows || []
+        state.instrumentData = tempList
+        tempList.forEach((item: any) => {
+          item.label = item.name
+          item.value = item.id + ''
+        })
+        state.instrumentList = tempList
+      } catch {
+      }
+    }
+
+    // 反显声部
+    const showBackSubject = async (musicalInstrumentIdList: []) => {
+      try {
+        const {data} = await subjectPage({page: 1, rows: 999, musicalInstrumentIdList: musicalInstrumentIdList})
+        const tempList = data.rows || []
+        tempList.forEach((item: any) => {
+          forms.subjectIdList.push(item.id + '')
+        })
+      } catch {
+      }
+    }
+
     // 添加原音
     const createSys = (initData?: any) => {
-      forms.background.push({
+      forms.musicSheetSoundList.push({
         audioFileUrl: null, // 原音
         track: null, // 轨道
         ...initData
@@ -429,12 +498,13 @@ export default defineComponent({
         positiveText: '确定',
         negativeText: '取消',
         onPositiveClick: async () => {
-          forms.background.splice(index, 1)
+          forms.musicSheetSoundList.splice(index, 1)
         }
       })
     }
 
     onMounted(async () => {
+      initInstrumentList();
       if (props.type === 'edit' || props.type === 'preview') {
         const detail = props.data
         try {
@@ -443,22 +513,31 @@ export default defineComponent({
           forms.playMode = data.playMode
           forms.xmlFileUrl = data.xmlFileUrl
           forms.midiUrl = data.midiUrl
-          forms.metronomeUrl = data.metronomeUrl
           forms.name = data.name
           forms.musicTag = data.musicTag?.split(',')
           forms.composer = data.composer
           forms.playSpeed = data.playSpeed
-          forms.showFingering = Number(data.showFingering)
-          forms.canEvaluate = Number(data.canEvaluate)
-          forms.notation = Number(data.notation)
-          forms.auditVersion = Number(data.auditVersion)
-          forms.sortNumber = data.sortNumber
+          // forms.showFingering = Number(data.showFingering)
+          // forms.canEvaluate = Number(data.canEvaluate)
+          // forms.notation = Number(data.notation)
+          // forms.auditVersion = Number(data.auditVersion)
+          // forms.sortNumber = data.sortNumber
           forms.musicCover = data.musicCover
           forms.remark = data.remark
           forms.status = data.status
           forms.musicSheetCategoriesId = data.musicSheetCategoriesId
-          forms.background = data.background || []
+          forms.musicSheetSoundList = data.musicSheetSoundList || []
           forms.musicSheetType = data.musicSheetType || "SINGLE"
+          forms.musicSheetAccompanimentList = data.musicSheetAccompanimentList
+          data.musicSheetAccompanimentList?.forEach((next: any) => {
+            state.musicSheetAccompanimentNames.push(next.audioFileUrl);
+          })
+          forms.evaluationStandard = data.evaluationStandard
+          forms.musicalInstrumentIds = data.musicalInstrumentIds
+          forms.musicalInstrumentIdList = data.musicalInstrumentIds.split(',') || []
+
+          forms.subjectIds = data.subjectIds
+          forms.subjectIdList = data.subjectIds?.split(',') || []
           // 获取渐变 和 是否多声部
           try {
             const extConfigJson = data.extConfigJson ? JSON.parse(data.extConfigJson) : {}
@@ -615,7 +694,7 @@ export default defineComponent({
                       [
                         {
                           label: '小A',
-                          value: '小B'
+                          value: '1'
                         }
                       ] as any
                     }
@@ -662,6 +741,47 @@ export default defineComponent({
                 />
               </NFormItemGi>
             </NGrid>
+            <NGrid cols={2}>
+              <NFormItemGi label="是否重复节拍时长" path="repeatedBeats"
+                           rule={[
+                             {
+                               required: true,
+                               message: '请选择是否重复节拍时长'
+                             }
+                           ]}
+              >
+                <NRadioGroup
+                    v-model:value={forms.repeatedBeats}
+                    // onUpdateValue={(value: string | number | boolean) => {
+                    //   if (value === 'MP3') {
+                    //     forms.repeatedBeats = 'MP3'
+                    //   } else {
+                    //     forms.repeatedBeats = 'MIDI'
+                    //   }
+                    // }}
+                >
+                  <NRadio value="1">是</NRadio>
+                  <NRadio value="0">否</NRadio>
+                </NRadioGroup>
+              </NFormItemGi>
+              <NFormItemGi
+                  label="评分标准"
+                  path="evaluationStandard"
+                  rule={[
+                    {
+                      required: true
+                    }
+                  ]}
+              >
+                <NRadioGroup
+                    v-model:value={forms.evaluationStandard}
+                >
+                  <NRadio value={'AMPLITUDE'}>节奏评分</NRadio>
+                  <NRadio value={'FREQUENCY'}>音准评分</NRadio>
+                  <NRadio value={'DECIBELS'}>分贝评分</NRadio>
+                </NRadioGroup>
+              </NFormItemGi>
+            </NGrid>
             <NAlert showIcon={false} style={{marginBottom: "12px"}}>曲目上传</NAlert>
             <NGrid cols={2}>
               <NFormItemGi label="播放模式" path="playMode"
@@ -709,23 +829,25 @@ export default defineComponent({
               {forms.playMode === 'MP3' && (
                   <NFormItemGi
                       label="上传伴奏"
-                      path="midiFileUrl"
+                      path="musicSheetAccompanimentNames"
                       rule={[
                         {
                           required: true,
-                          message: '请选择上传.mp3/.aac'
+                          message: '请选择上传.mp3'
                         }
                       ]}
                   >
                     <UploadFile
                         size={10}
-                        v-model:fileList={forms.midiFileUrl}
-                        tips="仅支持上传.mp3/.aac格式文件"
+                        v-model:imageList={state.musicSheetAccompanimentNames}
+                        tips="仅支持上传.mp3格式文件"
                         listType="image"
-                        accept=".mp3,.aac"
+                        accept=".mp3"
                         bucketName="cloud-coach"
                         text="点击上传伴奏文件"
-                        onReadFileInputEventAsArrayBuffer={readFileInputEventAsArrayBuffer}
+                        max={10}
+                        // onReadFileInputEventAsArrayBuffer={readFileInputEventAsArrayBuffer}
+                        multiple={true}
                     />
                   </NFormItemGi>
               )}
@@ -777,15 +899,16 @@ export default defineComponent({
             </NGrid>
 
             <NGrid cols={2}>
-              <NFormItemGi label="可用声部" path="musicSubject"
+              <NFormItemGi label="可用声部" path="subjectIdList"
                            rule={[
                              {
-                               required: true
+                               required: true,
+                               message: '请选择可用声部'
                              }
                            ]}
               >
                 <NSelect
-                    v-model:value={forms.subjectIds}
+                    v-model:value={forms.subjectIdList}
                     options={props.subjectList}
                     multiple
                     filterable
@@ -793,7 +916,7 @@ export default defineComponent({
                     placeholder="请选择可用声部"
                 />
               </NFormItemGi>
-              {(forms.playMode === 'MP3' || forms.musicSheetType === 'SINGLE') && (
+              {(forms.musicSheetType === 'SINGLE') && (
                   <NFormItemGi
                       label="页面渲染声轨"
                       path="audioType"
@@ -812,7 +935,7 @@ export default defineComponent({
                     </CheckboxGroup>
                   </NFormItemGi>
               )}
-              {forms.playMode === 'MIDI' && forms.musicSheetType === 'CONCERT' && (
+              {forms.musicSheetType === 'CONCERT' && (
                   <NFormItemGi
                       label="用户可切换声轨"
                       path="audioType"
@@ -835,7 +958,7 @@ export default defineComponent({
             </NGrid>
 
             <NGrid cols={2}>
-              <NFormItemGi label="可用乐器" path="audioType"
+              <NFormItemGi label="可用乐器" path="musicalInstrumentIdList"
                            rule={[
                              {
                                required: true,
@@ -844,15 +967,16 @@ export default defineComponent({
                            ]}
               >
                 <NSelect
-                    options={
-                      [] as any
-                    }
-                    v-model:value={forms.musicalInstrumentIds}
+                    placeholder="请选择可用乐器"
+                    options={state.instrumentList}
+                    v-model:value={forms.musicalInstrumentIdList}
+                    clearable
+                    multiple
                 />
               </NFormItemGi>
             </NGrid>
             <NGrid cols={2}>
-              <NFormItemGi label="是否播放节拍器" path="audioType"
+              <NFormItemGi label="是否播放节拍器" path="isPlayBeat"
                            rule={[
                              {
                                required: true,
@@ -877,10 +1001,10 @@ export default defineComponent({
                                ]}
                   >
                     <NRadioGroup
-                        v-model:value={forms.playStyle}
+                        v-model:value={forms.isUseSystemBeat}
                     >
-                      <NRadio value="MP3">系统节拍器</NRadio>
-                      <NRadio value="MIDI">MP3节拍器</NRadio>
+                      <NRadio value="1">系统节拍器</NRadio>
+                      <NRadio value="0">MP3节拍器</NRadio>
                     </NRadioGroup>
                   </NFormItemGi>
               )}
@@ -888,13 +1012,13 @@ export default defineComponent({
             {/* 只有播放类型为mp3时才会有原音 */}
             {forms.playMode === 'MP3' && (
                 <>
-                  {forms.background.map((item: any, index: number) => (
+                  {forms.musicSheetSoundList.map((item: any, index: number) => (
                       <>
                         {item.track?.toLocaleUpperCase?.() != 'COMMON' && <NGrid class={styles.audioSection}>
                             <NFormItemGi
                                 span={12}
                                 label="原音"
-                                path={`background[${index}].audioFileUrl`}
+                                path={`musicSheetSoundList[${index}].audioFileUrl`}
                                 rule={[
                                   {
                                     required: true,
@@ -917,7 +1041,7 @@ export default defineComponent({
                               <NFormItemGi
                                   span={12}
                                   label="所属轨道"
-                                  path={`background[${index}].track`}
+                                  path={`musicSheetSoundList[${index}].track`}
                                   rule={[
                                     {
                                       required: true,
@@ -936,7 +1060,7 @@ export default defineComponent({
                                 <NButton
                                     type="primary"
                                     text
-                                    disabled={forms.background.length === 1}
+                                    disabled={forms.musicSheetSoundList.length === 1}
                                     onClick={() => removeSys(index)}
                                 >
                                     删除
@@ -950,7 +1074,7 @@ export default defineComponent({
                       type="primary"
                       dashed
                       block
-                      disabled={state.partListNames.length <= forms.background.length}
+                      disabled={state.partListNames.length <= forms.musicSheetSoundList.length}
                       style={{
                         marginBottom: '24px'
                       }}

+ 0 - 125
src/views/music-library/music-sheet/modal/tag-operation.tsx

@@ -1,125 +0,0 @@
-import {
-  NForm,
-  NFormItem,
-  NInput,
-  NSelect,
-  NSpace,
-  NButton,
-  useMessage,
-  NCascader,
-  NInputNumber
-} from 'naive-ui'
-import type { TreeSelectOption } from 'naive-ui'
-import { defineComponent, PropType, reactive, ref } from 'vue'
-import { musicTagSave, musicTagUpdate } from '../../api'
-
-export default defineComponent({
-  name: 'city-operation',
-  props: {
-    type: {
-      type: String,
-      default: 'add'
-    },
-    data: {
-      type: Object as PropType<any>,
-      default: () => {}
-    },
-    catalogList: {
-      type: Array as PropType<Array<TreeSelectOption>>,
-      default: () => []
-    },
-    clientTypeList: {
-      type: Array as PropType<Array<string>>,
-      default: () => []
-    }
-  },
-  emits: ['close', 'getList'],
-  setup(props, { slots, attrs, emit }) {
-    const forms = reactive({
-      name: null,
-      sortNumber: null
-    })
-
-    const btnLoading = ref(false)
-    const formsRef = ref()
-    const message = useMessage()
-
-    // 提交记录
-    const onSubmit = async () => {
-      formsRef.value.validate(async (error: any) => {
-        if (error) return
-        try {
-          btnLoading.value = true
-          if (props.type === 'add') {
-            await musicTagSave({ ...forms })
-            message.success('添加成功')
-          } else if (props.type === 'edit') {
-            await musicTagUpdate({ ...forms, id: props.data.id })
-            message.success('修改成功')
-          }
-          emit('getList')
-          emit('close')
-        } catch {
-          //
-        }
-        setTimeout(() => {
-          btnLoading.value = false
-        }, 100)
-      })
-    }
-
-    // 初始化数据
-    if (props.type === 'edit') {
-      const data = props.data
-      forms.name = data.name
-      forms.sortNumber = data.sortNumber
-    }
-
-    return () => (
-      <div style="background: #fff; padding-top: 12px">
-        <NForm model={forms} ref={formsRef} label-placement="left" label-width="auto">
-          <NFormItem
-            label="名称"
-            path="name"
-            rule={[
-              {
-                required: true,
-                message: '请输入名称'
-              }
-            ]}
-          >
-            <NInput
-              v-model:value={forms.name}
-              placeholder="请输入名称"
-              clearable
-              showCount
-              maxlength={6}
-            />
-          </NFormItem>
-          <NFormItem label="排序" path="sortNumber">
-            <NInputNumber
-              v-model:value={forms.sortNumber}
-              placeholder="请输入排序"
-              min={0}
-              style={{ width: '100%' }}
-            />
-          </NFormItem>
-        </NForm>
-
-        <NSpace justify="end">
-          <NButton type="default" onClick={() => emit('close')}>
-            取消
-          </NButton>
-          <NButton
-            type="primary"
-            onClick={() => onSubmit()}
-            loading={btnLoading.value}
-            disabled={btnLoading.value}
-          >
-            保存
-          </NButton>
-        </NSpace>
-      </div>
-    )
-  }
-})

+ 4 - 3
src/views/system-manage/subject-manage/instrument/instrument-list.tsx

@@ -87,7 +87,7 @@ export default defineComponent({
           key: 'hz'
         },
         {
-          title: '声部分类',
+          title: '声部',
           key: 'subjectName'
         },
         {
@@ -195,7 +195,7 @@ export default defineComponent({
               <NFormItem path="rate" label="评测频率">
                 <NInput
                     v-model:value={state.searchForm.hz}
-                    placeholder="请输入乐器编码"
+                    placeholder="请输入评测频率"
                     clearable
                 />
               </NFormItem>
@@ -203,6 +203,7 @@ export default defineComponent({
                 <NSelect
                     options={getSelectDataFromObj(defaultScore)}
                     v-model:value={state.searchForm.defaultScore}
+                    placeholder="请选择默认谱面"
                     clearable
                 />
               </NFormItem>
@@ -246,7 +247,7 @@ export default defineComponent({
                     state.saveMode = 'add'
                   }}
               >
-                新增乐器
+                添加
               </NButton>
             </NSpace>
 

+ 40 - 7
src/views/system-manage/subject-manage/instrument/modal/instrument-save.tsx

@@ -28,6 +28,7 @@ export default defineComponent({
       defaultScore: null,
       code: null,
       hz: null,
+      isConvertibleScore: true,
     })
     const btnLoading = ref(false)
     const formsRef = ref()
@@ -65,6 +66,7 @@ export default defineComponent({
         forms.defaultScore = data.defaultScore
         forms.code = data.code
         forms.hz = data.hz
+        forms.isConvertibleScore = data.isConvertibleScore
       }
     })
 
@@ -86,25 +88,56 @@ export default defineComponent({
                   placeholder="请输入声部名称"
                   clearable
                   maxlength={10}
+                  showCount
               ></NInput>
             </NFormItem>
             <NFormItem
-                label="默认谱面"
-                path="defaultScore"
+                label="是否支持转简谱"
+                path="isConvertibleScore"
                 rule={[
                   {
                     required: true,
-                    message: '请选择默认谱面'
+                    message: '请选择是否支持转简谱'
                   }
                 ]}
             >
               <NSelect
+                  v-model:value={forms.isConvertibleScore}
+                  options={
+                    [
+                      {
+                        label: '是',
+                        value: true
+                      },
+                      {
+                        label: '否',
+                        value: false
+                      }
+                    ] as any
+                  }
+                  placeholder="请输入声部名称"
                   clearable
-                  v-model:value={forms.defaultScore}
-                  placeholder="请选择默认谱面"
-                  options={getSelectDataFromObj(defaultScore)}
-              />
+              ></NSelect>
             </NFormItem>
+            {(forms.isConvertibleScore && (
+                <NFormItem
+                    label="默认谱面"
+                    path="defaultScore"
+                    rule={[
+                      {
+                        required: true,
+                        message: '请选择默认谱面'
+                      }
+                    ]}
+                >
+                  <NSelect
+                      clearable
+                      v-model:value={forms.defaultScore}
+                      placeholder="请选择默认谱面"
+                      options={getSelectDataFromObj(defaultScore)}
+                  />
+                </NFormItem>
+            ))}
             <NFormItem
                 label="乐器编码"
                 path="code"

+ 1 - 0
src/views/system-manage/subject-manage/subject-categorize/modal/categorize-save.tsx

@@ -85,6 +85,7 @@ export default defineComponent({
                   placeholder="请输入声部名称"
                   clearable
                   maxlength={10}
+                  showCount
               ></NInput>
             </NFormItem>
           </NForm>

+ 2 - 1
src/views/system-manage/subject-manage/subject/modal/subject-save.tsx

@@ -129,6 +129,7 @@ export default defineComponent({
                   placeholder="请输入声部名称"
                   clearable
                   maxlength={10}
+                  showCount
               ></NInput>
             </NFormItem>
             <NFormItem
@@ -163,7 +164,7 @@ export default defineComponent({
                 path="musicalInstrumentIds"
                 rule={[
                   {
-                    required: true,
+                    required: false,
                     message: '请选择关联乐器'
                   }
                 ]}

+ 6 - 6
src/views/system-manage/subject-manage/subject/subject-list.tsx

@@ -228,25 +228,25 @@ export default defineComponent({
                     clearable
                 />
               </NFormItem>
-              <NFormItem path="categorize" label="声部分类">
+              <NFormItem path="categoryId" label="声部分类">
                 <NSelect
-                    v-model={[searchForm.categoryId, 'value']}
                     placeholder="请选择声部分类"
+                    v-model={[searchForm.categoryId, 'value']}
                     filterable
-                    options={state.categorizeList as any}
+                    options={state.categorizeList}
                     clearable
                 />
               </NFormItem>
-              <NFormItem path="categorize" label="关联乐器">
+              <NFormItem path="musicalInstrumentId" label="关联乐器">
                 <NSelect
                     v-model={[searchForm.musicalInstrumentId, 'value']}
                     placeholder="请选择关联乐器"
                     filterable
-                    options={state.instrumentList as any}
+                    options={state.instrumentList}
                     clearable
                 />
               </NFormItem>
-              <NFormItem path="operator" label="操作人">
+              <NFormItem path="operatorKeyword" label="操作人">
                 <NInput
                     placeholder="请输入操作人"
                     v-model:value={searchForm.operatorKeyword}