From fcdd9fd33c51fc66223a4fc5dfd2bef04a6da752 Mon Sep 17 00:00:00 2001 From: A1300399510 <A1300399510> Date: Wed, 17 Jul 2024 16:32:57 +0800 Subject: [PATCH] no message --- .gitignore | 30 + .vscode/extensions.json | 3 + README.md | 29 + index.html | 13 + jsconfig.json | 8 + package.json | 24 + public/favicon.ico | Bin 0 -> 4286 bytes src/App.vue | 1165 ++++++++++++++++++++ src/assets/base.css | 0 src/assets/img/dot.svg | 1 + src/assets/img/icon12.svg | 1 + src/assets/img/loop-c.png | Bin 0 -> 6926 bytes src/assets/img/loop.png | Bin 0 -> 5689 bytes src/assets/img/play-icon.png | Bin 0 -> 7456 bytes src/assets/img/question-icon.svg | 1 + src/assets/img/single-c.png | Bin 0 -> 6428 bytes src/assets/img/single.png | Bin 0 -> 5349 bytes src/assets/img/suspend.png | Bin 0 -> 6428 bytes src/assets/main.css | 70 ++ src/components/HelloWorld.vue | 44 + src/components/TheWelcome.vue | 88 ++ src/components/WelcomeItem.vue | 86 ++ src/components/icons/IconCommunity.vue | 7 + src/components/icons/IconDocumentation.vue | 7 + src/components/icons/IconEcosystem.vue | 7 + src/components/icons/IconSupport.vue | 7 + src/components/icons/IconTooling.vue | 19 + src/main.js | 20 + src/router/index.js | 23 + src/utils/api.js | 32 + src/utils/http.js | 78 ++ src/views/AboutView.vue | 15 + src/views/HomeView.vue | 9 + vite.config.js | 16 + 34 files changed, 1803 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 index.html create mode 100644 jsconfig.json create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 src/App.vue create mode 100644 src/assets/base.css create mode 100644 src/assets/img/dot.svg create mode 100644 src/assets/img/icon12.svg create mode 100644 src/assets/img/loop-c.png create mode 100644 src/assets/img/loop.png create mode 100644 src/assets/img/play-icon.png create mode 100644 src/assets/img/question-icon.svg create mode 100644 src/assets/img/single-c.png create mode 100644 src/assets/img/single.png create mode 100644 src/assets/img/suspend.png create mode 100644 src/assets/main.css create mode 100644 src/components/HelloWorld.vue create mode 100644 src/components/TheWelcome.vue create mode 100644 src/components/WelcomeItem.vue create mode 100644 src/components/icons/IconCommunity.vue create mode 100644 src/components/icons/IconDocumentation.vue create mode 100644 src/components/icons/IconEcosystem.vue create mode 100644 src/components/icons/IconSupport.vue create mode 100644 src/components/icons/IconTooling.vue create mode 100644 src/main.js create mode 100644 src/router/index.js create mode 100644 src/utils/api.js create mode 100644 src/utils/http.js create mode 100644 src/views/AboutView.vue create mode 100644 src/views/HomeView.vue create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ee54e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a7cea0b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..a5cbacd --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# suno + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Customize configuration + +See [Vite Configuration Reference](https://vitejs.dev/config/). + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Compile and Minify for Production + +```sh +npm run build +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..99f583a --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <link rel="icon" href="/favicon.ico"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Vite App</title> + </head> + <body> + <div id="app"></div> + <script type="module" src="/src/main.js"></script> + </body> +</html> diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..5a1f2d2 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + }, + "exclude": ["node_modules", "dist"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4585735 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "suno", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite --host", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.3.1", + "axios": "^1.7.2", + "element-plus": "^2.7.7", + "qs": "^6.12.3", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.5", + "less": "^4.2.0", + "vite": "^5.3.1" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 GIT binary patch literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kev<ISBgE$F{SFy+(=9Z)f)De0Se}ZDZW}Z3B zElCeVrw;K0Fdl_Cg=gZOFXXc3pL)Q05CAuT+XucQ<8g~3dteP~|7s7c6QYP;fy;mF zMN;>tV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?<QnEgvj4i?s}Yk=qA2z`-^*<eK3c)MS4JOdbsTQEOa0) z0NWqlna2rzs>5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7<X*Er!BfRbvU93$DH%#v6dRt^6HBxz1xBNHx=$&_Gv<&J}Ljk zJN<Fzx(`Oe@KgQ0F$<14=XV#WK`o#6Ku>z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{T<?%b6i9IjI)Ls)S{-*mq<@~R{?$}ZKjf;^k75i_}(2MXt}^SEBVg7AI@28 zo_uPg2V)_e-`2Ois=PYoe%9u*n9({PFR)OnHJPi{dNx>Kx<YG`4QQ>D#iCLfl2<BD h7L=-;Q>vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S literal 0 HcmV?d00001 diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..881fe3c --- /dev/null +++ b/src/App.vue @@ -0,0 +1,1165 @@ +<script setup> +import { RouterLink, RouterView } from "vue-router" +import { onMounted, ref } from "vue" + +import { getQrcode, getList, monitorState, Generate, monitorMusic, getDetails } from "./utils/api" +import { ElMessage } from "element-plus" + +onMounted(() => { + // getLoginQrcode() + getListData() +}) + +let list = ref([]) +let listIndex = ref(null) // 列表选中的 Index + +const getListData = () => { + getList().then(res => { + if (res.code == 401) { + getLoginQrcode() + return + } + + if (res.code != 200) return + const data = res.data || [] + + data.forEach(element => { + console.log("element", element.metadataid) + }) + + list.value = data || [] + }) +} + +let wxloginVisible = ref(false) // 登录弹窗显示状态 +let wxloginQrcodeLose = ref(false) // 登录二维码失效状态 +let islogin = ref(false) // 登录状态 +let token = "" +let qrcode = ref("") + +// 获取二维码 +const getLoginQrcode = () => { + getQrcode().then(res => { + if (res.code != 200) return + + const data = res.data || {} + token = data.token || "" + qrcode.value = data.qrcode || "" + wxloginVisible.value = true + + monitorLogin() + }) +} + +// 监听扫码状态 +let monitorTimer = null +const monitorLogin = () => { + monitorTimer = setInterval(() => { + monitorState({ token: token }).then(res => { + console.log(res) + // code 200 为登录成功 400 是等待 201 是失效 + if (res.code == 400) return + + clearInterval(monitorTimer) + + if (res.code == 201) { + wxloginQrcodeLose.value = true + } + + if (res.code == 200) { + ElMessage({ + showClose: true, + message: res.message, + type: "success", + }) + wxloginVisible.value = false + getListData() + localStorage.setItem("token", res.data?.token) + } + }) + }, 3000) +} + +const handleClose = () => { + console.log("挂壁了") + wxloginVisible.value = false + wxloginQrcodeLose.value = false + clearInterval(monitorTimer) +} + +let textarea = ref("") +let value2 = ref(false) +let modelValue = ref("chirp-v3-5") +let options = ref([ + { + label: "V2 (老款模型,最长生成1分钟左右)", + value: "chirp-v2-xxl-alpha", + }, + { + label: "V3 (广泛、多才多艺,最多生成2分钟)", + value: "chirp-v3-0", + }, + { + label: "V3.5 (最新模型,更好的歌曲结构,最长生成4分钟)", + value: "chirp-v3-5", + }, +]) + +let type = ref("inspiration") // inspiration 灵感 custom 自定义 + +const cutType = key => { + type.value = key +} + +let obj = ref({ + "gpt_description_prompt": "", // 描述 + "mv": "chirp-v3-5", + "make_instrumental": false, + "tags": null, // 标签 + "prompt": "", // 提示 + "history": null, + "concat_history": null, + "type": "gen", + "duration": null, // 持续时间 + "refund_credits": null, // 优惠 + "stream": true, // 流派 + "infill": null, // 填充物 + "has_vocal": true, // 是否有声音 + "error_type": null, + "error_message": null, + "tags": "", +}) + +// 点击创建音乐 +const creativeMusic = () => { + console.log("提交了") + + // return + + Generate({ ...obj.value }).then(res => { + if (res.code != 200) { + ElMessage({ + showClose: true, + message: res.message, + type: "error", + }) + return + } + const data = res.data || {} + + monitorMusicState(data.metadataid) + ElMessage({ + showClose: true, + message: res.message, + type: "success", + }) + }) +} + +// let styleVisible = ref(true) // 风格弹窗状态 +// bass, drum, guitar, rock, pop, electro, electronic, metal, heavy metal, heavy metal, heavy metal, heavy metal +let stylelist = ["bass", "drum", "guitar", "rock", "pop", "electro", "electronic", "metal", "heavy metal", "Subscribe", "heavy metal", "beat", "synth", "hard rock", "rap", "catchy", "powerful", "indie pop"] + +const addStyle = item => { + obj.value.tags = obj.value.tags.trim() + if (obj.value.tags) obj.value.tags += "," + + obj.value.tags += item +} + +const handleMusicList = index => { + let targetlist = list.value || [] + let target = targetlist[index] + listIndex.value = index + if (target.status !== "complete") { + monitorMusicState(target.metadataid) + } else { + getMusicDetails(target.id) + } +} + +let monitorMusicTimer = null +// 监听音乐的生成状态 +const monitorMusicState = metadataid => { + clearTimeout(monitorMusicTimer) + monitorMusicTimer = setTimeout(() => { + monitorMusic({ metadataid }).then(res => { + if (res.code != 200) return + const data = res.data || {} + const dataList = data.list || [] + + let obj = {} + let isnoneed = 0 // isnoneed > 0 需要继续监听的意思 submitted streaming 代表生产中 + dataList.forEach((element, index) => { + if (element.status != "complete") isnoneed++ + obj[element.sid] = index + }) + + console.log("isnoneed", isnoneed) + + if (isnoneed > 0) { + monitorMusicState(metadataid) + } + + let targetlist = list.value || [] + targetlist.forEach((element, index) => { + if (obj[element.sid] >= 0) { + targetlist[index] = dataList[obj[element.sid]] + delete obj[element.sid] + } + }) + + for (const key in obj) { + targetlist.unshift(dataList[obj[key]]) + } + list.value = targetlist + }) + }, 1000) +} + +let songInfo = ref({}) // 歌详情 + +const getMusicDetails = id => { + getDetails({ id }).then(res => { + if (res.code != 200) return + + songInfo.value = res.data + + previewState.value = true + }) +} + +const audio = ref(null) +const isPlaying = ref(false) + +let previewState = ref(false) +const closeInfo = () => { + previewState.value = false +} + +const playAudio = index => { + if (index == undefined) { + index = listIndex.value || 0 + } + let targetlist = list.value || [] + let target = targetlist[index] || {} + audio.value.src = target.audio_url || "" + audio.value.play() + listIndex.value = index +} + +const togglePlayPause = () => { + if (isPlaying.value) { + pauseAudio() + } else { + playAudio() + } +} + +const updatePlayStatus = () => { + isPlaying.value = !audio.value.paused +} + +const pauseAudio = () => { + audio.value.pause() +} + +const nextAudio = () => { + if (listIndex.value == null) return + let targetlist = list.value || [] + let index = listIndex.value + index = (index + 1) % targetlist.length + let target = targetlist[index] + audio.value.src = target.audio_url + audio.value.play() + listIndex.value = index + console.log(audio.value) +} + +const prevAudio = () => { + if (listIndex.value == null) return + + let targetlist = list.value || [] + let index = listIndex.value + index = (index - 1 + targetlist.length) % targetlist.length + + let target = targetlist[index] + audio.value.src = target.audio_url + audio.value.play() + + listIndex.value = index +} + +const currentTime = ref(0) +const duration = ref(0) + +const updateCurrentTime = () => { + currentTime.value = audio.value.currentTime +} + +const updateDuration = () => { + duration.value = audio.value.duration +} + +const seekAudio = value => { + audio.value.currentTime = value +} + +const formatTime = time => { + const minutes = Math.floor(time / 60) + const seconds = Math.floor(time % 60) + return `${minutes}:${seconds < 10 ? "0" : ""}${seconds}` +} +</script> + +<template> + <div> + <div class="flexflex" style="height: calc(100vh - 69px); overflow: auto;"> + <div class="left-box"> + <div class="tab-box"> + <div class="tab-item" :class="{ 'sel': type == 'inspiration' }" @click="cutType('inspiration')">灵感模式</div> + <div class="tab-item" :class="{ 'sel': type == 'custom' }" @click="cutType('custom')">自定义模式</div> + </div> + <template v-if="type == 'inspiration'"> + <div class="description"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 歌曲描述 + <el-popover placement="right" :width="300" trigger="click" content='描述你想要的音乐风格和主题(例如"关于假日")。使用流派和氛围,而不是特定的艺术家和歌曲。' :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + <div class="title-right"></div> + </div> + <el-input v-model="obj.gpt_description_prompt" class="description-input" style="width: 100%;" :rows="4" type="textarea" placeholder="请输入您的歌曲描述,例如:一首关于青春的冷酷的电子歌曲" /> + </div> + <div class="toggle-switch title-box flexacenter"> + <div class="title-left flexacenter"> + <el-switch v-model="obj.has_vocal" class="ml-2" style="--el-switch-on-color: #fbd38d; --el-switch-off-color: #ffffff3d;" :active-value="false" :inactive-value="true" /> + 纯音乐 + <el-popover placement="right" :width="150" trigger="click" content="没有歌词的音乐。" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + <div class="section model"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 音乐模型 + <el-popover placement="right" :width="150" trigger="click" content="官方suno音乐模型" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + + <el-select v-model="modelValue" placeholder="选择模型" size="large" style="width: 100%;" popper-class="model-select" :teleported="false"> + <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> + </el-select> + </div> + <div class="creation-btn flexcenter" @click="creativeMusic()">创作</div> + </template> + <template v-else> + <div class="toggle-switch title-box flexacenter"> + <div class="title-left flexacenter"> + <el-switch v-model="obj.has_vocal" style="--el-switch-on-color: #fbd38d; --el-switch-off-color: #ffffff3d;" :active-value="false" :inactive-value="true" /> + 纯音乐 + <el-popover placement="right" :width="150" trigger="click" content="没有歌词的音乐。" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + + <div class="lyric"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 歌词 + <el-popover placement="right" :width="300" trigger="click" content="随机生成歌词,自己写,或者从Al那里得到一些帮助。使用两首诗(8行)获得最佳效果。" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + <div class="title-right flexacenter"> + <!-- <el-popover popper-class="type-popover" placement="right" :width="280" trigger="click" :teleported="false"> + <div class="lyric-type flexflex"> + <div class="lyric-type-item flexcenter" v-for="item in 7" :key="item">主歌</div> + </div> + <template #reference> + <div class="meta-tags flexcenter">添加元标签</div> + </template> + </el-popover> --> + </div> + </div> + + <div class="lyric-content"> + <el-input v-model="obj.gpt_description_prompt" class="lyric-input" maxlength="2000" style="width: 100%;" :rows="4" type="textarea" placeholder="请输入你的歌词" /> + <!-- <div class="random-btn flexcenter">随机生成歌词</div> --> + </div> + </div> + <div class="style"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 音乐风格 + <el-popover placement="right" :width="300" trigger="click" content="描述你想要的音乐风格 例如:流行、摇滚、史诗。Suno的模型无法识别具体的艺人名称,但能理解音乐类型和氛围。" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + <div class="style-content"> + <el-input v-model="obj.tags" class="style-input" maxlength="2000" style="width: 100%;" :rows="4" type="textarea" placeholder="输入音乐风格" autosize /> + <!-- <div class="random-btn flexcenter">选择音乐风格</div> --> + <div class="style-list"> + <div class="style-item" v-for="item in stylelist" :key="item" @click="addStyle(item)">{{ item }}</div> + </div> + </div> + </div> + <div class="name"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 歌曲名称 + <el-popover placement="right" :width="300" trigger="click" content="为你的歌曲命名" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + + <el-input class="name-input" v-model="obj.title" style="width: 300px;" maxlength="40" placeholder="请输入歌曲名称" /> + </div> + <div class="section model"> + <div class="title-box flexacenter"> + <div class="title-left flexacenter"> + 音乐模型 + <el-popover placement="right" :width="150" trigger="click" content="官方suno音乐模型" :teleported="false"> + <template #reference> + <img class="question-icon" src="./assets/img/question-icon.svg" /> + </template> + </el-popover> + </div> + </div> + + <el-select v-model="modelValue" placeholder="选择模型" size="large" style="width: 100%;" popper-class="model-select" :teleported="false"> + <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> + </el-select> + </div> + <div class="creation-btn flexcenter" @click="creativeMusic()">创作</div> + </template> + </div> + <div class="middle-box flex1"> + <template v-if="list.length == 0"> + <div class="nodata">暂无数据</div> + </template> + <template v-else> + <div class="list"> + <div class="item flexflex" :class="{ 'sel': listIndex == index }" v-for="(item, index) in list" :key="index" @click="handleMusicList(index)"> + <!-- <div class="progress-bar" :style="{ 'width': item.progress + '%' }"></div> --> + <div class="progress-bar" v-if="item.status != 'complete'">生成中...</div> + <div class="img-box" @click="playAudio(index)"> + <img class="img" :src="item.image_url" /> + <div class="play flexcenter"> + <img class="play-btn" src="./assets/img/play-icon.png" /> + </div> + </div> + <div class="content flexflex flex1"> + <div class="name">{{ item.title }}</div> + <div class="desc">{{ item.tags || item?.metadata?.tags }}</div> + </div> + + <el-popover popper-class="dot-popover" placement="bottom" :width="220" trigger="click" :teleported="false"> + <div class="dot-list"> + <a class="dot-item" v-if="item.audio_url" :href="item.audio_url" :download="item.title + '.mp3'">下载MP3</a> + <!-- <div class="dot-item" v-if="item.audio_url">下载MP3</div> --> + <!-- <div class="dot-item">下载wav</div> --> + <a class="dot-item" v-if="item.video_url" :href="item.video_url" :download="item.title + '.mp4'">下载视频</a> + <!-- <div class="dot-item" v-if="item.video_url">下载视频</div> --> + </div> + <template #reference> + <div class="dot flexcenter"> + <img class="dot-icon" src="./assets/img/dot.svg" /> + </div> + </template> + </el-popover> + </div> + </div> + </template> + </div> + <div class="right-box" v-if="previewState"> + <template v-if="JSON.stringify(songInfo) === '{}'"> + <div class="nosong">选择要预览的歌曲。</div> + </template> + <template v-else> + <div class="close flexcenter" @click="closeInfo()"> + <img class="close-icon" src="./assets/img/icon12.svg" /> + </div> + <img class="song-picture" :src="songInfo.image_large_url" /> + <div class="song-info"> + <div class="name">{{ songInfo.title }}</div> + <div class="desc">{{ songInfo?.metadata?.tags }}</div> + <div class="desc" v-html="songInfo?.metadata?.prompt"></div> + </div> + </template> + </div> + </div> + + <div class="base-bottom flexacenter"> + <div class="base-side"></div> + <div class="base-middle flexacenter"> + <div class="btn flexacenter"> + <div class="btn-item btn-left flexcenter" @click="prevAudio()"> + <el-icon color="#fff" :size="18"><DArrowLeft /></el-icon> + </div> + <div class="btn-item btn-centre flexcenter" @click="togglePlayPause()"> + <img v-if="isPlaying" class="suspend" src="./assets/img/suspend.png" /> + <img v-else class="suspend" src="./assets/img/play-icon.png" /> + </div> + <div class="btn-item btn-right flexcenter" @click="nextAudio()"> + <el-icon color="#fff" :size="18"><DArrowRight /></el-icon> + </div> + </div> + <div class="audio-box flexacenter"> + <div class="time">{{ formatTime(currentTime) }}</div> + <el-slider class="progress-box" :show-tooltip="false" v-model="currentTime" :max="duration" @change="seekAudio" /> + <div class="time">{{ formatTime(duration) }}</div> + </div> + <!-- <img class="cyclical-icon" src="./assets/img/loop.png" /> + <img class="cyclical-icon" src="./assets/img/single.png" /> --> + </div> + <div class="base-side"></div> + </div> + + <el-dialog class="wxlogin" v-model="wxloginVisible" width="480" :before-close="handleClose" align-center="true" :show-close="false"> + <div class="wxlogin-box"> + <div class="close-box"> + <img class="close-icon" src="" /> + </div> + <div class="wxlogin-title">微信登录</div> + <div class="qrcode-box flexcenter"> + <img class="qrcode-img" :src="qrcode" /> + <div class="lose-box flexcenter" v-if="wxloginQrcodeLose" @click="getLoginQrcode()"> + 二维码失效,点击重新获取 + </div> + </div> + <div class="hint">扫码关注【SunoAI音乐创作工具】即可登录</div> + <!-- <div class="remark flexacenter"> + 注册/登录表示您已同意 + <a>《用户协议》</a> + 及 + <a>《隐私政策》</a> + </div> --> + </div> + </el-dialog> + <!-- 风格 --> + <!-- <el-dialog class="style-dialog" v-model="styleVisible" width="480" :before-close="handleClose" align-center="true" :show-close="false"> + <div class="style-box"> + <div class="title">音乐流派</div> + <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> + <el-tab-pane label="User" name="first">User</el-tab-pane> + <el-tab-pane label="Config" name="second">Config</el-tab-pane> + <el-tab-pane label="Role" name="third">Role</el-tab-pane> + <el-tab-pane label="Task" name="fourth">Task</el-tab-pane> + </el-tabs> + </div> + </el-dialog> --> + + <audio ref="audio" @timeupdate="updateCurrentTime" @loadedmetadata="updateDuration" @ended="nextAudio" @play="updatePlayStatus" @pause="updatePlayStatus"></audio> + </div> +</template> + +<style scoped lang="less"> +audio { + display: none; +} +body { + background-color: #000; +} + +.left-box { + width: 320px; + // height: calc(100vh - 69px); + // overflow: auto; + padding: 10px; + background-color: #000; + border-right: 1px solid #252323; + height: calc(100vh - 69px); + .tab-box { + display: flex; + align-items: center; + padding: 4px; + border: 1px solid #adadad; + border-radius: 23px; + color: #adadad; + margin-bottom: 18px; + + .tab-item { + flex: 1; + height: 34px; + cursor: pointer; + text-align: center; + line-height: 34px; + &.sel { + color: #000; + border-radius: 20px; + background-color: #fbd38d; + } + } + } + + .description { + margin-bottom: 10px; + .title { + margin-bottom: 10px; + } + + .description-input { + /deep/ .el-textarea__inner { + box-shadow: 0 0 0 1px #252323 inset !important; + background: transparent; + } + min-height: 31px; + height: 94px; + width: 100%; + color: #ffffffeb; + line-height: 1.5; + border-radius: 4px; + } + } + + .toggle-switch { + color: #fff; + font-size: 14px; + .el-switch { + margin-right: 10px; + } + margin-bottom: 10px; + } + + .title-box { + margin-bottom: 10px; + justify-content: space-between; + + .title-left { + font-size: 14px; + color: #fff; + .question-icon { + width: 14px; + height: 14px; + margin-left: 3px; + cursor: pointer; + } + + /deep/ .el-popper { + font-size: 12px; + color: #fff; + } + } + .title-right { + .meta-tags { + width: 80px; + height: 28px; + color: rgb(204 204 204); + background-color: rgb(26 26 26); + font-size: 12px; + border-radius: 4px; + cursor: pointer; + } + } + } + + .model { + .title { + margin-bottom: 10px; + } + /deep/ .el-select__wrapper { + box-shadow: 0 0 0 1px #252323 inset !important; + background: transparent; + + .el-select__selected-item { + color: #fff; + } + } + + /deep/ .el-popper { + .el-select-dropdown.model-select { + .el-select-dropdown__item { + color: #606266; + &.is-selected { + color: #fff; + } + &.is-hovering { + background: #232426 !important; + } + } + } + } + } + + .creation-btn { + color: #1a202c; + font-size: 16px; + font-weight: 700; + padding: 0 16px; + background-color: #fbd38d; + height: 44px; + border-radius: 4px; + margin-top: 24px; + cursor: pointer; + } + + .lyric { + .title-box { + .el-popper.type-popover { + .lyric-type { + justify-content: space-between; + flex-wrap: wrap; + gap: 10px; + padding: 10px; + .lyric-type-item { + width: 72px; + height: 24px; + color: rgb(170 170 170); + cursor: pointer; + border-radius: 9999px; + border: 1px solid #aaa; + &:hover { + border-color: #ddd; + } + } + } + } + } + + .lyric-content { + /deep/ .lyric-input { + .el-textarea__inner { + background: transparent; + box-shadow: none; + } + } + padding-bottom: 5px; + box-shadow: 0 0 0 1px #252323 inset !important; + margin-bottom: 10px; + } + } + + .style { + .style-content { + /deep/ .style-input { + .el-textarea__inner { + background: transparent; + box-shadow: none; + min-height: 100px !important; + } + } + padding-bottom: 5px; + box-shadow: 0 0 0 1px #252323 inset !important; + margin-bottom: 10px; + + .style-list { + width: 100%; + display: flex; + overflow: auto; + white-space: pre; + + .style-item { + color: rgb(250 247 245); + font-size: 13px; + padding: 8px 12px; + background: #363030bf; + margin-left: 4px; + border-radius: 9999px; + cursor: pointer; + } + } + } + } + + .random-btn { + background: rgba(255, 255, 255, 0.16); + width: 120px; + margin-left: 5px; + cursor: pointer; + padding: 0 12px; + min-width: 32px; + height: 32px; + border-radius: 6px; + color: #fff; + font-size: 12px; + } + + .name { + margin-bottom: 10px; + + .name-input { + /deep/ .el-input__wrapper { + background: none; + box-shadow: 0 0 0 1px #252323 inset !important; + } + } + } +} + +/deep/ .el-popper { + background: rgb(25, 25, 26) !important; + border: none !important; + box-shadow: 0 0 0 1px #252323 inset !important; + + &.is-light .el-popper__arrow:before { + border-color: #252323 !important; + background: rgb(25, 25, 26) !important; + } +} + +.right-box { + width: 294px; + height: calc(100vh - 69px); + overflow: auto; + position: relative; + .nosong { + color: #a0aec0; + font-size: 14px; + text-align: center; + padding-top: 40px; + } + + .close { + position: absolute; + top: 10px; + right: 10px; + background-color: #fff3; + width: 40px; + height: 40px; + border-radius: 5px; + cursor: pointer; + } + + .song-picture { + width: 100%; + } + .song-info { + font-size: 14px; + padding: 10px; + color: #fff; + + .name { + line-height: 24px; + font-size: 14px; + } + .desc { + white-space: pre-line; + line-height: 24px; + margin-bottom: 40px; + } + } +} + +.middle-box { + border-right: 1px solid #252323; + height: calc(100vh - 69px); + overflow: auto; + .nodata { + color: #a0aec0; + font-size: 14px; + text-align: center; + padding-top: 40px; + } + + .list { + .item { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 20px; + padding-right: 20px; + cursor: pointer; + align-items: center; + &.sel, + &:hover { + background: radial-gradient(3010.06% 152.11% at 27.33% 38.98%, rgba(61, 58, 58, 0.43) 0%, rgba(25, 24, 24, 0.57) 100%) !important; + } + + .img-box { + position: relative; + width: 60px; + height: 60px; + margin-right: 10px; + border-radius: 6px; + + .img { + width: 60px; + height: 60px; + border-radius: 6px; + } + &:hover { + .play { + display: flex; + } + } + .play { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.6); + .play-btn { + width: 22px; + } + } + } + + position: relative; + + .progress-bar { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; + color: #fff; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(270deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8)); + background-size: 300% 100%; + animation: gradientAnimation 5s linear infinite; + } + + @keyframes gradientAnimation { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } + } + + .content { + font-size: 14px; + line-height: 21px; + flex-direction: column; + justify-content: center; + .name { + font-weight: 700; + color: #fff; + } + .desc { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + line-clamp: 2; + word-break: break-all; + word-wrap: break-word; + white-space: normal; + color: rgb(203 213 224); + } + } + + .dot { + padding: 0 12px; + min-width: 32px; + height: 32px; + cursor: pointer; + border-radius: 6px; + + .dot-icon { + widows: 16px; + height: 16px; + } + } + /deep/ .dot-popover { + padding: 0; + + .dot-list { + padding: 5px 0; + .dot-item { + padding-left: 10px; + padding-right: 10px; + line-height: 30px; + cursor: pointer; + height: 30px; + font-size: 14px; + color: #fff; + display: block; + text-decoration: none; + &:hover { + background: radial-gradient(3010.06% 152.11% at 27.33% 38.98%, rgba(61, 58, 58, 0.43) 0%, rgba(25, 24, 24, 0.57) 100%); + } + } + } + } + } + } +} + +.base-bottom { + background-color: rgb(22 22 22); + border-top: 1px solid #222222; + padding-left: 24px; + padding-right: 24px; + height: 68px; + .base-side { + width: 450px; + } + + .base-middle { + .btn { + margin-right: 24px; + .btn-item { + width: 32px; + height: 32px; + border-radius: 50% !important; + background: rgba(255, 255, 255, 0.08); + cursor: pointer; + transition: all 0.3s; + &:hover { + .el-icon { + font-size: 30px; + } + } + + &.btn-centre { + margin-left: 6px; + margin-right: 6px; + background-color: #fbd38d; + img { + width: 20px; + } + } + } + } + + .audio-box { + .time { + color: rgb(160 174 192); + font-size: 12px; + } + + .progress-box { + width: 390px; + margin-left: 16px; + margin-right: 16px; + /deep/ .el-slider__runway { + height: 4px; + .el-slider__bar { + background: #fbd38d; + height: 4px; + } + } + /deep/ .el-slider__button { + border: none; + height: 14px; + width: 14px; + } + } + } + .cyclical-icon { + height: 14px; + margin-right: 5px; + margin: 0 12px; + cursor: pointer; + } + } +} + +/deep/ .el-dialog { + border-radius: 10px; + color: #fff !important; + border: 1px solid rgba(255, 255, 255, 0.08) !important; + background: rgb(25, 25, 26) !important; + padding: 16px; + .el-dialog__header { + display: none; + } + + &.wxlogin { + .el-dialog__body { + .wxlogin-box { + display: flex; + flex-direction: column; + align-items: center; + position: relative; + + .close-box { + width: 0; + height: 0; + position: absolute; + top: 15px; + right: 15px; + } + + .wxlogin-title { + color: #969595; + padding: 0 20px; + height: 40px; + margin-bottom: 10px; + line-height: 40px; + font-size: 18px; + } + + .qrcode-box { + width: 300px; + height: 300px; + position: relative; + .qrcode-img { + width: 100%; + height: 100%; + } + .lose-box { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.6); + color: #fff; + } + } + + .hint { + margin-top: 20px; + margin-bottom: 20px; + color: rgb(204 204 204); + text-align: center; + } + + .remark { + text-align: center; + font-size: 12px; + color: rgb(180 185 191); + a { + color: rgb(88 101 242); + text-decoration: underline; + } + } + } + } + } + &.style-dialog { + .el-dialog__body { + .style-box { + .title { + font-size: 18px; + color: #fff; + } + } + } + } +} +</style> diff --git a/src/assets/base.css b/src/assets/base.css new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/img/dot.svg b/src/assets/img/dot.svg new file mode 100644 index 0000000..936dc81 --- /dev/null +++ b/src/assets/img/dot.svg @@ -0,0 +1 @@ +<svg data-v-98294f16="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="#fff" d="M176 416a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224"></path></svg> \ No newline at end of file diff --git a/src/assets/img/icon12.svg b/src/assets/img/icon12.svg new file mode 100644 index 0000000..79d6b89 --- /dev/null +++ b/src/assets/img/icon12.svg @@ -0,0 +1 @@ +<svg stroke="#fff" fill="#fff" stroke-width="0" viewBox="0 0 352 512" data-theme="dark" focusable="false" class="chakra-icon css-13otjrl" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"></path></svg> \ No newline at end of file diff --git a/src/assets/img/loop-c.png b/src/assets/img/loop-c.png new file mode 100644 index 0000000000000000000000000000000000000000..1da24f22eb22558173ffaea7aa9f89ad461285bf GIT binary patch literal 6926 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 literal 0 HcmV?d00001 diff --git a/src/assets/img/loop.png b/src/assets/img/loop.png new file mode 100644 index 0000000000000000000000000000000000000000..64a347deef4c9b8d1ac7a42407275c1b93e64bde GIT binary patch literal 5689 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 aY_R5F!^O^zPfszpV1R%##5P=aApIXbIa6N% literal 0 HcmV?d00001 diff --git a/src/assets/img/play-icon.png b/src/assets/img/play-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af87ea75de1049895a0823964902d8e0f16ce9e9 GIT binary patch literal 7456 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 literal 0 HcmV?d00001 diff --git a/src/assets/img/question-icon.svg b/src/assets/img/question-icon.svg new file mode 100644 index 0000000..ef010d4 --- /dev/null +++ b/src/assets/img/question-icon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="#fff" d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896m23.744 191.488c-52.096 0-92.928 14.784-123.2 44.352-30.976 29.568-45.76 70.4-45.76 122.496h80.256c0-29.568 5.632-52.8 17.6-68.992 13.376-19.712 35.2-28.864 66.176-28.864 23.936 0 42.944 6.336 56.32 19.712 12.672 13.376 19.712 31.68 19.712 54.912 0 17.6-6.336 34.496-19.008 49.984l-8.448 9.856c-45.76 40.832-73.216 70.4-82.368 89.408-9.856 19.008-14.08 42.24-14.08 68.992v9.856h80.96v-9.856c0-16.896 3.52-31.68 10.56-45.76 6.336-12.672 15.488-24.64 28.16-35.2 33.792-29.568 54.208-48.576 60.544-55.616 16.896-22.528 26.048-51.392 26.048-86.592 0-42.944-14.08-76.736-42.24-101.376-28.16-25.344-65.472-37.312-111.232-37.312zm-12.672 406.208a54.272 54.272 0 0 0-38.72 14.784 49.408 49.408 0 0 0-15.488 38.016c0 15.488 4.928 28.16 15.488 38.016A54.848 54.848 0 0 0 523.072 768c15.488 0 28.16-4.928 38.72-14.784a51.52 51.52 0 0 0 16.192-38.72 51.968 51.968 0 0 0-15.488-38.016 55.936 55.936 0 0 0-39.424-14.784z"></path></svg> \ No newline at end of file diff --git a/src/assets/img/single-c.png b/src/assets/img/single-c.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa0fec78b114936954cfff63f4fe91d7f81bfa7 GIT binary patch literal 6428 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°p(w7zsdJga1S8+f*3Dv zRx$gr5}JhVU=t=OLbR3A!6QhtDB#jkv#l<Z?;nh#&GByi38jL(3ny6ZPTEZz8P6Mz zv%z)L56>Y3V$7fx^F1cHb1}R(=zm2-%ZPV7z}&B+Y1hC(d`O^VNSEca=m({yq&T3~ z43!Vnof5cc(#R)YX5coku^B5DFqpsY(eKP<Nns9&hAdAO0*3wqdA$eI?vmFn23b8q zc)qXyvy(S8pGSB}4bXi6zo`w6>dYxbQn*fM<?qaGfj!8MzTS3-0lc(bbIiA)ByKse zC^`@%RK}rDtKJ`ASxX@Ju6pPUQ%)E>_IwNLWoI5f3^4%#;g$mLk)u4EK2DDzThE6` z3x%UG+y(%|`xqXG-?KsX40`l)Xfl!^`~%BFe(*0tc4B^BTL~v)NOTnxpdY*RqO%&t z;3Gy_m_gQ$3_?LsTtE#9bT*C>1?4;-D~yQHX^VrUVmAQ#VbA$Cv>;k~FXz*csh<}p z>gdsQ;Gh6zfIbM<v7rx%M$8%)%M(Wdbs1*An>%kbzB2$B%=%-Iuu+tTm((Wd{TEh7 z?B%J;(JDKSO<<7dPqz0dcU8IvWEGPlI=viGP?BG+WXTp$;(FMJoIp5BX%Y<`y1Dir zZEU8yMx3~Q!DrDz7>ht+=p9j#d&X$1?+Z`Ox=hpa_wT2I$w;|aSaC2o87U48&<a4n uAjx775Zv%)87S75`9GNC|2cehPmh^bk4Exo?ag-wk*1ms{FACp*#7_$uNZ^? literal 0 HcmV?d00001 diff --git a/src/assets/img/single.png b/src/assets/img/single.png new file mode 100644 index 0000000000000000000000000000000000000000..1c8207e257ae1eab8d2322579e2851153b71af8b GIT binary patch literal 5349 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 N0BwpvRvCLF{vSY^=g<HE literal 0 HcmV?d00001 diff --git a/src/assets/img/suspend.png b/src/assets/img/suspend.png new file mode 100644 index 0000000000000000000000000000000000000000..f339f4f1ad746e42ff47e7234517d8564e11e207 GIT binary patch literal 6428 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 WX5mq0rAhzp0MJGl!&?12g#QEXmbe)J literal 0 HcmV?d00001 diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..eead539 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,70 @@ +/* @import './base.css'; + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + font-weight: normal; +} + +a, +.green { + text-decoration: none; + color: hsla(160, 100%, 37%, 1); + transition: 0.4s; + padding: 3px; +} + +@media (hover: hover) { + a:hover { + background-color: hsla(160, 100%, 37%, 0.2); + } +} + +@media (min-width: 1024px) { + body { + display: flex; + place-items: center; + } + + #app { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + } +} */ + + +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +.flexflex { + display: flex; +} + +.flexcenter { + display: flex; + justify-content: center; + align-items: center; +} + +.flexjcenter { + display: flex; + justify-content: center; +} + +.flexacenter { + display: flex; + align-items: center; +} + +.flex1 { + flex: 1; +} + +body { + background-color: #000; +} \ No newline at end of file diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue new file mode 100644 index 0000000..5fb372c --- /dev/null +++ b/src/components/HelloWorld.vue @@ -0,0 +1,44 @@ +<script setup> +defineProps({ + msg: { + type: String, + required: true + } +}) +</script> + +<template> + <div class="greetings"> + <h1 class="green">{{ msg }}</h1> + <h3> + You’ve successfully created a project with + <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> + + <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. + </h3> + </div> +</template> + +<style scoped> +h1 { + font-weight: 500; + font-size: 2.6rem; + position: relative; + top: -10px; +} + +h3 { + font-size: 1.2rem; +} + +.greetings h1, +.greetings h3 { + text-align: center; +} + +@media (min-width: 1024px) { + .greetings h1, + .greetings h3 { + text-align: left; + } +} +</style> diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue new file mode 100644 index 0000000..dab9536 --- /dev/null +++ b/src/components/TheWelcome.vue @@ -0,0 +1,88 @@ +<script setup> +import WelcomeItem from './WelcomeItem.vue' +import DocumentationIcon from './icons/IconDocumentation.vue' +import ToolingIcon from './icons/IconTooling.vue' +import EcosystemIcon from './icons/IconEcosystem.vue' +import CommunityIcon from './icons/IconCommunity.vue' +import SupportIcon from './icons/IconSupport.vue' +</script> + +<template> + <WelcomeItem> + <template #icon> + <DocumentationIcon /> + </template> + <template #heading>Documentation</template> + + Vue’s + <a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a> + provides you with all information you need to get started. + </WelcomeItem> + + <WelcomeItem> + <template #icon> + <ToolingIcon /> + </template> + <template #heading>Tooling</template> + + This project is served and bundled with + <a href="https://vitejs.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The + recommended IDE setup is + <a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> + + <a href="https://github.com/johnsoncodehk/volar" target="_blank" rel="noopener">Volar</a>. If + you need to test your components and web pages, check out + <a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> and + <a href="https://on.cypress.io/component" target="_blank" rel="noopener" + >Cypress Component Testing</a + >. + + <br /> + + More instructions are available in <code>README.md</code>. + </WelcomeItem> + + <WelcomeItem> + <template #icon> + <EcosystemIcon /> + </template> + <template #heading>Ecosystem</template> + + Get official tools and libraries for your project: + <a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>, + <a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>, + <a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and + <a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If + you need more resources, we suggest paying + <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a> + a visit. + </WelcomeItem> + + <WelcomeItem> + <template #icon> + <CommunityIcon /> + </template> + <template #heading>Community</template> + + Got stuck? Ask your question on + <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>, our official + Discord server, or + <a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener" + >StackOverflow</a + >. You should also subscribe to + <a href="https://news.vuejs.org" target="_blank" rel="noopener">our mailing list</a> and follow + the official + <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">@vuejs</a> + twitter account for latest news in the Vue world. + </WelcomeItem> + + <WelcomeItem> + <template #icon> + <SupportIcon /> + </template> + <template #heading>Support Vue</template> + + As an independent project, Vue relies on community backing for its sustainability. You can help + us by + <a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>. + </WelcomeItem> +</template> diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue new file mode 100644 index 0000000..ac366d0 --- /dev/null +++ b/src/components/WelcomeItem.vue @@ -0,0 +1,86 @@ +<template> + <div class="item"> + <i> + <slot name="icon"></slot> + </i> + <div class="details"> + <h3> + <slot name="heading"></slot> + </h3> + <slot></slot> + </div> + </div> +</template> + +<style scoped> +.item { + margin-top: 2rem; + display: flex; + position: relative; +} + +.details { + flex: 1; + margin-left: 1rem; +} + +i { + display: flex; + place-items: center; + place-content: center; + width: 32px; + height: 32px; + color: var(--color-text); +} + +h3 { + font-size: 1.2rem; + font-weight: 500; + margin-bottom: 0.4rem; + color: var(--color-heading); +} + +@media (min-width: 1024px) { + .item { + margin-top: 0; + padding: 0.4rem 0 1rem calc(var(--section-gap) / 2); + } + + i { + top: calc(50% - 25px); + left: -26px; + position: absolute; + border: 1px solid var(--color-border); + background: var(--color-background); + border-radius: 8px; + width: 50px; + height: 50px; + } + + .item:before { + content: ' '; + border-left: 1px solid var(--color-border); + position: absolute; + left: 0; + bottom: calc(50% + 25px); + height: calc(50% - 25px); + } + + .item:after { + content: ' '; + border-left: 1px solid var(--color-border); + position: absolute; + left: 0; + top: calc(50% + 25px); + height: calc(50% - 25px); + } + + .item:first-of-type:before { + display: none; + } + + .item:last-of-type:after { + display: none; + } +} +</style> diff --git a/src/components/icons/IconCommunity.vue b/src/components/icons/IconCommunity.vue new file mode 100644 index 0000000..2dc8b05 --- /dev/null +++ b/src/components/icons/IconCommunity.vue @@ -0,0 +1,7 @@ +<template> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"> + <path + d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z" + /> + </svg> +</template> diff --git a/src/components/icons/IconDocumentation.vue b/src/components/icons/IconDocumentation.vue new file mode 100644 index 0000000..6d4791c --- /dev/null +++ b/src/components/icons/IconDocumentation.vue @@ -0,0 +1,7 @@ +<template> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor"> + <path + d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z" + /> + </svg> +</template> diff --git a/src/components/icons/IconEcosystem.vue b/src/components/icons/IconEcosystem.vue new file mode 100644 index 0000000..c3a4f07 --- /dev/null +++ b/src/components/icons/IconEcosystem.vue @@ -0,0 +1,7 @@ +<template> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor"> + <path + d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z" + /> + </svg> +</template> diff --git a/src/components/icons/IconSupport.vue b/src/components/icons/IconSupport.vue new file mode 100644 index 0000000..7452834 --- /dev/null +++ b/src/components/icons/IconSupport.vue @@ -0,0 +1,7 @@ +<template> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"> + <path + d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z" + /> + </svg> +</template> diff --git a/src/components/icons/IconTooling.vue b/src/components/icons/IconTooling.vue new file mode 100644 index 0000000..660598d --- /dev/null +++ b/src/components/icons/IconTooling.vue @@ -0,0 +1,19 @@ +<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license--> +<template> + <svg + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + aria-hidden="true" + role="img" + class="iconify iconify--mdi" + width="24" + height="24" + preserveAspectRatio="xMidYMid meet" + viewBox="0 0 24 24" + > + <path + d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z" + fill="currentColor" + ></path> + </svg> +</template> diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..65521f6 --- /dev/null +++ b/src/main.js @@ -0,0 +1,20 @@ +import "./assets/main.css" + +import { createApp } from "vue" +import ElementPlus from "element-plus" +import "element-plus/dist/index.css" +// 如果您正在使用CDN引入,请删除下面一行。 +import * as ElementPlusIconsVue from "@element-plus/icons-vue" + +import App from "./App.vue" +import router from "./router" + +const app = createApp(App) +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} +app.use(ElementPlus) + +app.use(router) + +app.mount("#app") diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..a49ae50 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,23 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'home', + component: HomeView + }, + { + path: '/about', + name: 'about', + // route level code-splitting + // this generates a separate chunk (About.[hash].js) for this route + // which is lazy-loaded when the route is visited. + component: () => import('../views/AboutView.vue') + } + ] +}) + +export default router diff --git a/src/utils/api.js b/src/utils/api.js new file mode 100644 index 0000000..750b3ac --- /dev/null +++ b/src/utils/api.js @@ -0,0 +1,32 @@ +import Http from "@/utils/http" + +// 获取二维码 +export const getQrcode = params => { + return Http.post("/api/login/qrcode", params) +} + +// 监听扫码登录 状态 +export const monitorState = params => { + return Http.post("/api/login/monitor", params) +} + +// 获取列表 +export const getList = params => { + return Http.post("/api/lists", params) +} + +// 点击创建音乐 +export const Generate = params => { + return Http.post("/api/music/generate", params) +} + +// 监听音乐生成状态 +export const monitorMusic = params => { + return Http.post("/api/music/monitor", params) +} +// 获取音乐详情 +export const getDetails = params => { + return Http.post("/api/details", params) +} + + diff --git a/src/utils/http.js b/src/utils/http.js new file mode 100644 index 0000000..ef8d946 --- /dev/null +++ b/src/utils/http.js @@ -0,0 +1,78 @@ +import axios from 'axios'; +import QS from 'qs'; +import { ElMessage } from "element-plus"; + + +axios.defaults.baseURL = 'https://suno.ansnid.com' +axios.defaults.emulateJSON = true +axios.defaults.withCredentials = true + +axios.interceptors.request.use( //响应拦截 + async config => { + // 开发时登录用的,可以直接替换小程序的 authorization + const token = localStorage.getItem('token') || '' + config['headers']['token'] = process.env.NODE_ENV !== "production" && token + config['headers']['Content-Type'] = "application/json;charset=utf-8" + return config; + }, + error => { + return Promise.error(error); + }) +// 响应拦截器 +axios.interceptors.response.use(response => { + if (response.status === 200) return Promise.resolve(response); //进行中 + else return Promise.reject(response); //失败 +}, error => { // 服务器状态码不是200的情况 + if (error.response.status) { + switch (error.response.status) { + // 401: 未登录 + case 401: + // goTologin() // 跳转登录页面 + break + default: + } + return Promise.reject(error.response); + } +}); + +/** + * get方法,对应get请求 + * @param {String} url [请求的url地址] + * @param {Object} params [请求时携带的参数] + */ +const get = (url, params) => { + return new Promise((resolve, reject) => { + axios.get(url, { params }).then(res => resolve(res.data)).catch(err => reject(err.data)) + }); +} +/** + * post方法,对应post请求 + * @param {String} url [请求的url地址] + * @param {Object} params [请求时携带的参数] + */ +const post = (url, params) => { + return new Promise((resolve, reject) => { + //是将对象 序列化成URL的形式,以&进行拼接 + // axios.post(url, QS.stringify(params)).then(res => { + axios.post(url, params).then(res => { + let data = res.data + if (data.code == 401 && !process.server) goLogin() + resolve(data) + }).catch(err => { + if (err.data.code == 401) { + goLogin() + resolve(err.data); + } else reject(err.data) + }) + }); +} + +// 打开登录 +const goLogin = () => { + if (typeof ajax_login === "function") ajax_login() +} + +export default { + get, + post, +} \ No newline at end of file diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue new file mode 100644 index 0000000..756ad2a --- /dev/null +++ b/src/views/AboutView.vue @@ -0,0 +1,15 @@ +<template> + <div class="about"> + <h1>This is an about page</h1> + </div> +</template> + +<style> +@media (min-width: 1024px) { + .about { + min-height: 100vh; + display: flex; + align-items: center; + } +} +</style> diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue new file mode 100644 index 0000000..6bb706f --- /dev/null +++ b/src/views/HomeView.vue @@ -0,0 +1,9 @@ +<script setup> +import TheWelcome from '../components/TheWelcome.vue' +</script> + +<template> + <main> + <TheWelcome /> + </main> +</template> diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..5c45e1d --- /dev/null +++ b/vite.config.js @@ -0,0 +1,16 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + } +})