diff --git a/api/service/suno/service.go b/api/service/suno/service.go index 6bf11c5e..936b4ee4 100644 --- a/api/service/suno/service.go +++ b/api/service/suno/service.go @@ -112,6 +112,10 @@ type RespVo struct { Message string `json:"message"` Data string `json:"data"` Channel string `json:"channel,omitempty"` + Error struct { + Message string `json:"message"` + Type string `json:"type"` + } `json:"error,omitempty"` } func (s *Service) Create(task types.SunoTask) (RespVo, error) { @@ -154,13 +158,14 @@ func (s *Service) Create(task types.SunoTask) (RespVo, error) { } body, _ := io.ReadAll(r.Body) + logger.Debugf("API response: %s", string(body)) err = json.Unmarshal(body, &res) if err != nil { return RespVo{}, fmt.Errorf("解析API数据失败:%v, %s", err, string(body)) } if res.Code != "success" { - return RespVo{}, fmt.Errorf("API 返回失败:%s", res.Message) + return RespVo{}, fmt.Errorf("API 返回失败:%s", res.Error.Message) } // update the last_use_at for api key apiKey.LastUsedAt = time.Now().Unix() diff --git a/web/src/utils/dialog.js b/web/src/utils/dialog.js index 52a9b941..cba7c8df 100644 --- a/web/src/utils/dialog.js +++ b/web/src/utils/dialog.js @@ -56,3 +56,24 @@ export function showLoading(message = '正在处理...') { export function closeLoading() { closeToast() } + +// 自定义 Toast 消息系统 +export function showToastMessage(message, type = 'info', duration = 3000) { + const toast = document.createElement('div') + toast.className = `fixed top-20 left-1/2 transform -translate-x-1/2 z-50 px-4 py-2 rounded-lg text-white font-medium ${ + type === 'error' ? 'bg-red-500' : type === 'success' ? 'bg-green-500' : 'bg-blue-500' + } animate-fade-in` + toast.textContent = message + document.body.appendChild(toast) + + if (duration > 0) { + setTimeout(() => { + toast.classList.add('animate-fade-out') + setTimeout(() => { + if (document.body.contains(toast)) { + document.body.removeChild(toast) + } + }, 300) + }, duration) + } +} diff --git a/web/src/views/mobile/components/CustomSelect.vue b/web/src/views/mobile/components/CustomSelect.vue new file mode 100644 index 00000000..b52fc5f6 --- /dev/null +++ b/web/src/views/mobile/components/CustomSelect.vue @@ -0,0 +1,116 @@ + + + {{ label }} + + {{ selectedLabel || placeholder || '请选择' }} + + + + + + + + {{ title || '请选择' }} + + + + + + + + + + {{ slotProps.option.label }} + + {{ slotProps.option.desc }} + + + + + + + + + + + + + + + + + diff --git a/web/src/views/mobile/components/CustomSelectOption.vue b/web/src/views/mobile/components/CustomSelectOption.vue new file mode 100644 index 00000000..8a16ec8e --- /dev/null +++ b/web/src/views/mobile/components/CustomSelectOption.vue @@ -0,0 +1,50 @@ + + + + + + {{ option.label }} + {{ option.desc }} + + + + + + + + + + + diff --git a/web/src/views/mobile/pages/SunoCreate.vue b/web/src/views/mobile/pages/SunoCreate.vue index 9999d141..286574e4 100644 --- a/web/src/views/mobile/pages/SunoCreate.vue +++ b/web/src/views/mobile/pages/SunoCreate.vue @@ -1,235 +1,475 @@ - + - - + + + + + + 音乐创作 + + - + - - - - - - - - - + + + 创作模式 + + + + {{ custom ? '自定义模式:可设置歌词、风格等详细参数' : '简单模式:通过描述快速生成' }} + - - - + + + + {{ option.label }} + ({{ option.value }}) + + + + - - - - - - + + + + 纯音乐 + 生成不包含人声的音乐 + + + - + - - + 歌词 + - - 生成歌词 - + + {{ data.lyrics.length }}/2000 + + + {{ isGenerating ? '生成中...' : '生成歌词' }} + + - - + 音乐风格 + + + {{ data.tags.length }}/120 + - - + {{ tag.label }} - + - - + 歌曲名称 + + + {{ data.title.length }}/100 + - - + 歌曲描述 + + + {{ data.prompt.length }}/1000 + - - - - 移除 - - - - + + + 续写歌曲 + + 移除 + + + + + 歌曲名称: + {{ refSong.title }} + + + 续写开始时间(秒) + + + - - - + 上传音乐文件(可选) + + - - - 上传音乐文件 - 支持 .wav, .mp3 格式 - - + @change="handleFileSelect" + class="hidden" + /> + + + 上传音乐文件 + 支持 .wav, .mp3 格式 + + + + + + {{ uploadFiles[0].name }} + - - - {{ btnText }} - + + + + {{ loading ? '创作中...' : btnText }} + - - - - - - - {{ item.major_model_version }} - - 用户上传 - 完整歌曲 - - - - 播放 - - + 我的作品 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ item.title || '未命名歌曲' }} + + + {{ item.tags || item.prompt }} + + + + + + + + + 失败 + + + + 生成中 + + + + + + + {{ item.major_model_version }} + + + 用户上传 + + + 完整歌曲 + + + 续写 + + + + + + + + + - 下载 - - 删除 - - + + 播放 + + + + + + + + {{ item.downloading ? '下载中...' : '下载' }} + + + + + 删除 + + + + + + + 生成进度 + {{ item.progress }}% + + + + + + + + + + + {{ item.err_msg || '未知错误' }} + + + - + + + + + + + + + + + + 没有更多了 + + - - - - - - - - - 正在播放 - + + + + 正在播放 + + + + + + + + + 您的浏览器不支持音频播放 + - - + + + + -
+ {{ slotProps.option.desc }} +
{{ option.desc }}
+ {{ custom ? '自定义模式:可设置歌词、风格等详细参数' : '简单模式:通过描述快速生成' }} +
生成不包含人声的音乐
+ {{ item.tags || item.prompt }} +
{{ item.err_msg || '未知错误' }}