|
@@ -160,8 +160,8 @@ export function getGradualLengthByXml(xml: string) {
|
|
const measureNotes = Array.from(measure.querySelectorAll('note'))
|
|
const measureNotes = Array.from(measure.querySelectorAll('note'))
|
|
|
|
|
|
const noteInMeasureIndex = Array.from(measure.childNodes)
|
|
const noteInMeasureIndex = Array.from(measure.childNodes)
|
|
- .filter((item: any) => item.nodeName === 'note')
|
|
|
|
- .findIndex((item) => item === note)
|
|
|
|
|
|
+ .filter((item: any) => item.nodeName === 'note')
|
|
|
|
+ .findIndex((item) => item === note)
|
|
|
|
|
|
let allDuration = 0
|
|
let allDuration = 0
|
|
let leftDuration = 0
|
|
let leftDuration = 0
|
|
@@ -215,9 +215,9 @@ export function getGradualLengthByXml(xml: string) {
|
|
return textContent && ks.includes(textContent)
|
|
return textContent && ks.includes(textContent)
|
|
})
|
|
})
|
|
if (
|
|
if (
|
|
- ele.type === 'metronome' ||
|
|
|
|
- (ele.type === 'words' && (textContent.startsWith('a tempo') || isKeyWork)) ||
|
|
|
|
- isLastNoteAndNotClosed
|
|
|
|
|
|
+ ele.type === 'metronome' ||
|
|
|
|
+ (ele.type === 'words' && (textContent.startsWith('a tempo') || isKeyWork)) ||
|
|
|
|
+ isLastNoteAndNotClosed
|
|
) {
|
|
) {
|
|
const indexOf = gradualNotes.findIndex((item) => item.length === 1)
|
|
const indexOf = gradualNotes.findIndex((item) => item.length === 1)
|
|
if (indexOf > -1 && ele.index > gradualNotes[indexOf]?.[0].start) {
|
|
if (indexOf > -1 && ele.index > gradualNotes[indexOf]?.[0].start) {
|
|
@@ -256,7 +256,8 @@ export default defineComponent({
|
|
},
|
|
},
|
|
data: {
|
|
data: {
|
|
type: Object as PropType<any>,
|
|
type: Object as PropType<any>,
|
|
- default: () => {}
|
|
|
|
|
|
+ default: () => {
|
|
|
|
+ }
|
|
},
|
|
},
|
|
tagList: {
|
|
tagList: {
|
|
type: Array as PropType<Array<SelectOption>>,
|
|
type: Array as PropType<Array<SelectOption>>,
|
|
@@ -265,7 +266,7 @@ export default defineComponent({
|
|
subjectList: {
|
|
subjectList: {
|
|
type: Array as PropType<Array<SelectOption>>,
|
|
type: Array as PropType<Array<SelectOption>>,
|
|
default: () => []
|
|
default: () => []
|
|
- }
|
|
|
|
|
|
+ },
|
|
// musicSheetCategories: {
|
|
// musicSheetCategories: {
|
|
// type: Array as PropType<Array<SelectOption>>,
|
|
// type: Array as PropType<Array<SelectOption>>,
|
|
// default: () => []
|
|
// default: () => []
|
|
@@ -273,7 +274,7 @@ export default defineComponent({
|
|
},
|
|
},
|
|
emits: ['close', 'getList'],
|
|
emits: ['close', 'getList'],
|
|
|
|
|
|
- setup(props, { slots, attrs, emit }) {
|
|
|
|
|
|
+ setup(props, {slots, attrs, emit}) {
|
|
const forms = reactive({
|
|
const forms = reactive({
|
|
graduals: {} as any, // 渐变速度
|
|
graduals: {} as any, // 渐变速度
|
|
playMode: 'MP3', // 播放类型
|
|
playMode: 'MP3', // 播放类型
|
|
@@ -299,9 +300,9 @@ export default defineComponent({
|
|
appAuditFlag: 0, // 是否审核版本
|
|
appAuditFlag: 0, // 是否审核版本
|
|
midiFileUrl: null, // 伴奏文件 MIDI文件(保留字段)
|
|
midiFileUrl: null, // 伴奏文件 MIDI文件(保留字段)
|
|
subjectIds: [] as any, // 可用声部
|
|
subjectIds: [] as any, // 可用声部
|
|
- musicalInstrumentIdList: [] as any, //可用乐器
|
|
|
|
- musicCategoryId: null, //曲目分类
|
|
|
|
- musicSheetAccompanimentList: [] as any, //曲目伴奏
|
|
|
|
|
|
+ musicalInstrumentIdList: [] as any, //可用乐器
|
|
|
|
+ musicCategoryId: null, //曲目分类
|
|
|
|
+ musicSheetAccompanimentList: [] as any, //曲目伴奏
|
|
audioType: 'HOMEMODE', // 伴奏类型
|
|
audioType: 'HOMEMODE', // 伴奏类型
|
|
isPlayBeat: true, // 是否播放节拍器
|
|
isPlayBeat: true, // 是否播放节拍器
|
|
isUseSystemBeat: true, // 是否使用系统节拍器(0:否;1:是)
|
|
isUseSystemBeat: true, // 是否使用系统节拍器(0:否;1:是)
|
|
@@ -315,7 +316,7 @@ export default defineComponent({
|
|
})
|
|
})
|
|
const state = reactive({
|
|
const state = reactive({
|
|
loading: false,
|
|
loading: false,
|
|
- previewMode: false, //是否是预览模式
|
|
|
|
|
|
+ previewMode: false,//是否是预览模式
|
|
tagList: [...props.tagList] as any, // 标签列表
|
|
tagList: [...props.tagList] as any, // 标签列表
|
|
xmlFirstSpeed: null as any, // 第一个音轨速度
|
|
xmlFirstSpeed: null as any, // 第一个音轨速度
|
|
partListNames: [] as any, // 所有音轨声部列表
|
|
partListNames: [] as any, // 所有音轨声部列表
|
|
@@ -405,6 +406,7 @@ export default defineComponent({
|
|
)
|
|
)
|
|
} catch (error) {}
|
|
} catch (error) {}
|
|
state.partListNames = getPartListNames(res?.target?.result as any) as any
|
|
state.partListNames = getPartListNames(res?.target?.result as any) as any
|
|
|
|
+ parseInstrumentAndSubject(res?.target?.result as any)
|
|
// 这里是如果没有当前音轨就重新写
|
|
// 这里是如果没有当前音轨就重新写
|
|
for (let j = 0; j < state.partListNames.length; j++) {
|
|
for (let j = 0; j < state.partListNames.length; j++) {
|
|
if (!forms.musicSheetSoundList[j]) {
|
|
if (!forms.musicSheetSoundList[j]) {
|
|
@@ -437,6 +439,36 @@ export default defineComponent({
|
|
xmlRead.readAsText(file)
|
|
xmlRead.readAsText(file)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const parseInstrumentAndSubject = (xml: any) => {
|
|
|
|
+ if (!xml) return
|
|
|
|
+ const xmlParse = new DOMParser().parseFromString(xml, 'text/xml')
|
|
|
|
+ // 乐器
|
|
|
|
+ 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);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
// 获取xml中所有轨道 乐器
|
|
// 获取xml中所有轨道 乐器
|
|
const getPartListNames = (xml: any) => {
|
|
const getPartListNames = (xml: any) => {
|
|
if (!xml) return []
|
|
if (!xml) return []
|
|
@@ -500,14 +532,17 @@ export default defineComponent({
|
|
)
|
|
)
|
|
const partListNames = deepClone(_names) || []
|
|
const partListNames = deepClone(_names) || []
|
|
partListNames.forEach((item: any) => {
|
|
partListNames.forEach((item: any) => {
|
|
- const index = forms.musicSheetSoundList.findIndex(
|
|
|
|
- (ground: any) => item.value == ground.track
|
|
|
|
- )
|
|
|
|
- if (index > -1 && track != item.value) {
|
|
|
|
- item.disabled = true
|
|
|
|
- } else {
|
|
|
|
|
|
+ const index = forms.musicSheetSoundList.findIndex((ground: any) => item.value == ground.track)
|
|
|
|
+ if (index > -1 && track == item.value) {
|
|
item.disabled = false
|
|
item.disabled = false
|
|
|
|
+ } else {
|
|
|
|
+ item.disabled = true
|
|
}
|
|
}
|
|
|
|
+ // if (index > -1 && track != item.value) {
|
|
|
|
+ // item.disabled = true
|
|
|
|
+ // } else {
|
|
|
|
+ // item.disabled = false
|
|
|
|
+ // }
|
|
})
|
|
})
|
|
return partListNames || []
|
|
return partListNames || []
|
|
}
|
|
}
|
|
@@ -685,12 +720,8 @@ export default defineComponent({
|
|
forms.subjectIds = data.subjectIds?.split(',') || []
|
|
forms.subjectIds = data.subjectIds?.split(',') || []
|
|
forms.sourceType = data.sourceType
|
|
forms.sourceType = data.sourceType
|
|
forms.musicSheetExtend = data.musicSheetExtend
|
|
forms.musicSheetExtend = data.musicSheetExtend
|
|
|
|
+ forms.repeatedBeats = data.isPlayBeat
|
|
|
|
|
|
- // 初始化音轨和原音
|
|
|
|
- forms.musicSheetSoundList = data.musicSheetSoundList || []
|
|
|
|
- forms.musicSheetSoundList.forEach((next: any) => {
|
|
|
|
- forms.multiTracksSelection.push(next.track)
|
|
|
|
- })
|
|
|
|
|
|
|
|
// 获取渐变 和 是否多声部
|
|
// 获取渐变 和 是否多声部
|
|
try {
|
|
try {
|
|
@@ -703,14 +734,13 @@ export default defineComponent({
|
|
gradualData.list = getGradualLengthByXml(res?.data as any).filter(
|
|
gradualData.list = getGradualLengthByXml(res?.data as any).filter(
|
|
(item: any) => item.length === 2
|
|
(item: any) => item.length === 2
|
|
)
|
|
)
|
|
- // state.partListNames = getPartListNames(res?.data as any) as any
|
|
|
|
- //
|
|
|
|
- // state.partListNames.forEach((item: any) => {
|
|
|
|
- // const tracks = forms.musicSheetSoundList.map((item: any) => item.track);
|
|
|
|
- // if (tracks.indexOf(item.label) <= -1) {
|
|
|
|
- // forms.musicSheetSoundList.push({audioFileUrl: '', track: item.label})
|
|
|
|
- // }
|
|
|
|
- // })
|
|
|
|
|
|
+ state.partListNames = getPartListNames(res?.data as any) as any
|
|
|
|
+
|
|
|
|
+ // 初始化音轨和原音
|
|
|
|
+ forms.musicSheetSoundList = data.musicSheetSoundList || []
|
|
|
|
+ forms.musicSheetSoundList.forEach((next: any) => {
|
|
|
|
+ forms.multiTracksSelection.push(next.track)
|
|
|
|
+ })
|
|
}
|
|
}
|
|
})
|
|
})
|
|
} catch (error) {}
|
|
} catch (error) {}
|
|
@@ -742,14 +772,15 @@ export default defineComponent({
|
|
</NAlert>
|
|
</NAlert>
|
|
<NGrid cols={2}>
|
|
<NGrid cols={2}>
|
|
<NFormItemGi
|
|
<NFormItemGi
|
|
- label="曲目名称"
|
|
|
|
- path="name"
|
|
|
|
- rule={[
|
|
|
|
- {
|
|
|
|
- required: true,
|
|
|
|
- message: '请输入曲目名称'
|
|
|
|
- }
|
|
|
|
- ]}
|
|
|
|
|
|
+ label="曲目名称"
|
|
|
|
+ path="name"
|
|
|
|
+ rule={[
|
|
|
|
+ {
|
|
|
|
+ required: true,
|
|
|
|
+ message: '请输入曲目名称',
|
|
|
|
+ trigger: ['input', 'blur']
|
|
|
|
+ }
|
|
|
|
+ ]}
|
|
>
|
|
>
|
|
<NInput
|
|
<NInput
|
|
v-model:value={forms.name}
|
|
v-model:value={forms.name}
|
|
@@ -759,14 +790,15 @@ export default defineComponent({
|
|
/>
|
|
/>
|
|
</NFormItemGi>
|
|
</NFormItemGi>
|
|
<NFormItemGi
|
|
<NFormItemGi
|
|
- label="音乐人"
|
|
|
|
- path="composer"
|
|
|
|
- rule={[
|
|
|
|
- {
|
|
|
|
- required: true,
|
|
|
|
- message: '请输入音乐人'
|
|
|
|
- }
|
|
|
|
- ]}
|
|
|
|
|
|
+ label="音乐人"
|
|
|
|
+ path="composer"
|
|
|
|
+ rule={[
|
|
|
|
+ {
|
|
|
|
+ required: true,
|
|
|
|
+ message: '请输入音乐人',
|
|
|
|
+ trigger: ['input', 'blur']
|
|
|
|
+ }
|
|
|
|
+ ]}
|
|
>
|
|
>
|
|
<NInput
|
|
<NInput
|
|
v-model:value={forms.composer}
|
|
v-model:value={forms.composer}
|
|
@@ -957,15 +989,14 @@ export default defineComponent({
|
|
v-model:value={forms.appAuditFlag}
|
|
v-model:value={forms.appAuditFlag}
|
|
/>
|
|
/>
|
|
</NFormItemGi>
|
|
</NFormItemGi>
|
|
- <NFormItemGi
|
|
|
|
- label="曲目分类"
|
|
|
|
- path="musicCategoryId"
|
|
|
|
- rule={[
|
|
|
|
- {
|
|
|
|
- required: true,
|
|
|
|
- message: '请选择曲目分类'
|
|
|
|
- }
|
|
|
|
- ]}
|
|
|
|
|
|
+ <NFormItemGi label="曲目分类" path="musicCategoryId"
|
|
|
|
+ rule={[
|
|
|
|
+ {
|
|
|
|
+ required: true,
|
|
|
|
+ message: '请选择曲目分类',
|
|
|
|
+ trigger: ['input', 'blur']
|
|
|
|
+ }
|
|
|
|
+ ]}
|
|
>
|
|
>
|
|
<NCascader
|
|
<NCascader
|
|
valueField="id"
|
|
valueField="id"
|
|
@@ -979,15 +1010,13 @@ export default defineComponent({
|
|
</NFormItemGi>
|
|
</NFormItemGi>
|
|
</NGrid>
|
|
</NGrid>
|
|
<NGrid cols={2}>
|
|
<NGrid cols={2}>
|
|
- <NFormItemGi
|
|
|
|
- label="重复节拍时长"
|
|
|
|
- path="repeatedBeats"
|
|
|
|
- rule={[
|
|
|
|
- {
|
|
|
|
- required: true,
|
|
|
|
- message: '请选择是否重复节拍时长'
|
|
|
|
- }
|
|
|
|
- ]}
|
|
|
|
|
|
+ <NFormItemGi label="重复节拍时长" path="repeatedBeats"
|
|
|
|
+ rule={[
|
|
|
|
+ {
|
|
|
|
+ required: false,
|
|
|
|
+ message: '请选择是否重复节拍时长'
|
|
|
|
+ }
|
|
|
|
+ ]}
|
|
>
|
|
>
|
|
<NRadioGroup v-model:value={forms.repeatedBeats}>
|
|
<NRadioGroup v-model:value={forms.repeatedBeats}>
|
|
<NRadio value={true}>是</NRadio>
|
|
<NRadio value={true}>是</NRadio>
|