step3-form-content.vue
5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<script setup lang="ts">
import { ref, computed, createVNode } from 'vue';
import { FieldRule, FormInstance } from '@arco-design/web-vue/es/form';
import { useVModels } from '@vueuse/core';
import { Form, FormItem, Link, Textarea, TypographyText } from '@arco-design/web-vue';
import InputUpload from '@/components/input-upload/index.vue';
import { useSelectionStore } from '@/store';
import { get, set } from 'lodash';
import axios from 'axios';
import AudioPreview from '@/views/demo/components/audio-preview.vue';
import AudioPlayer from '@/components/audio-player/index.vue';
import { createModalVNode } from '@/utils/createVNode';
import useAuthApi from "@/api/auth";
const props = defineProps<{ loading?: boolean; modelValue?: any }>();
const emits = defineEmits(['update:modelValue', 'update:loading']);
const formRef = ref<FormInstance>();
const { loading, modelValue: formValue } = useVModels(props, emits);
const guideSourceUrl = computed({
get: () => get(formValue.value, 'expand.guide_source.url', ''),
set: (val) => set(formValue.value, 'expand.guide_source.url', val),
});
const karaokeSourceUrl = computed({
get: () => get(formValue.value, 'expand.karaoke_source.url', ''),
set: (val) => set(formValue.value, 'expand.karaoke_source.url', val),
});
const onUpdateGuide = (file: { name: string; url: string; size: number }) => {
set(formValue.value, 'expand.guide_source', { name: file.name, url: file.url, size: file.size });
};
const onUpdateKaraoke = (file: { name: string; url: string; size: number }) => {
set(formValue.value, 'expand.karaoke_source', { name: file.name, url: file.url, size: file.size });
};
const { activityAudioAccept } = useSelectionStore();
const formRule = {
'expand.guide_source.url': [{ required: true, message: '请上传导唱文件' }],
'expand.karaoke_source.url': [{ required: false, message: '请上传伴奏文件' }],
'lyric': [{ type: 'string', required: true, message: '请填写歌词内容' }],
'clip_lyric': [{ type: 'string', required: true, message: '请填写推荐歌词内容' }],
} as Record<string, FieldRule[]>;
const onDownload = (url: string, fileName: string) => useAuthApi.downloadFile(url, `${formValue.value.song_name}(${fileName})`);
const onFormatLyric = (key: string) => {
formValue.value[key] = formValue.value[key].replace(/(\n[\s\t]*\r*\n)/g, '\n').replace(/^[\n\r\t]*|[\n\r\t]*$/g, '');
};
const guideFile = ref<File | undefined>();
const getGuideFile = async () => {
if (!guideFile.value) {
guideFile.value = await axios
.get(`${guideSourceUrl.value}?response-content-type=Blob`, { responseType: 'blob', timeout: 60000 })
.then(({ data }) => Promise.resolve(data));
}
return guideFile.value;
};
const onAudioPreview = async () => {
const src = await getGuideFile();
createModalVNode(() => createVNode(AudioPreview, { src, lyric: formValue.value.lyric }), {
title: '预览歌词-整首',
footer: false,
closable: true,
});
};
defineExpose({
onValid: (callback?: () => void) => formRef.value?.validate((errors) => !errors && callback?.()),
});
</script>
<template>
<Form ref="formRef" :model="formValue" :rules="formRule" :auto-label-width="true" size="small">
<FormItem label="音频文件" field="expand.guide_source.url" :show-colon="true">
<InputUpload v-model="guideSourceUrl" :accept="activityAudioAccept" :limit="100" @success="onUpdateGuide"
@choose-file="(file: any) => (guideFile = file)" @update:loading="(value: boolean) => (loading = value)" />
</FormItem>
<FormItem v-if="guideSourceUrl">
<template #label>
<Link icon @click="onDownload(guideSourceUrl, '音频文件')">下载音频</Link>
</template>
<AudioPlayer name="音频文件" :url="guideSourceUrl" />
</FormItem>
<FormItem label="伴奏文件" field="expand.karaoke_source.url" :show-colon="true">
<InputUpload v-model="karaokeSourceUrl" :accept="activityAudioAccept" :limit="100" @success="onUpdateKaraoke"
@update:loading="(value: boolean) => (loading = value)" />
</FormItem>
<FormItem v-if="karaokeSourceUrl">
<template #label>
<Link icon @click="onDownload(karaokeSourceUrl, '伴奏文件')">下载伴奏</Link>
</template>
<AudioPlayer name="伴奏文件" :url="karaokeSourceUrl" />
</FormItem>
<FormItem class="lyric" label="歌词文本" field="lyric" :show-colon="true">
<Textarea v-model="formValue.lyric" :auto-size="{ minRows: 6, maxRows: 6 }" placeholder="请粘贴带时间的lrc歌词文本至输入框"
@blur="() => onFormatLyric('lyric')" />
<!-- <template #extra>
<Link :hoverable="false" :disabled="!guideSourceUrl || !formValue.lyric" @click="onAudioPreview"> 预览歌词</Link>
</template> -->
</FormItem>
<TypographyText type="danger" style="font-size: 13px">
注意:demo上架后,存在于您的私库。需要在App应用内,您的个人主页下,进行1对1分享给对方试听
</TypographyText>
</Form>
</template>
<style scoped lang="less">
.lyric {
:deep(.arco-form-item-extra) {
width: 100%;
text-align: right;
}
}
</style>