From 1428db0430019e145191b4b0661add21c69ecdd6 Mon Sep 17 00:00:00 2001 From: congzc Date: Tue, 13 Jun 2023 18:10:30 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9F=B3=E4=B9=90=E7=94=9F=E6=88=90=E8=A7=86?= =?UTF-8?q?=E9=A2=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/createVideo.js | 12 + src/assets/img/star.png | Bin 0 -> 5345 bytes src/lang/package/en.ts | 2 + src/lang/package/zh-cn.ts | 2 + src/layout/components/Navbar.vue | 18 +- src/layout/components/Sidebar/index.vue | 14 +- src/store/modules/userInfo.js | 7 +- src/types/components.d.ts | 2 + src/views/createVideo/index.vue | 458 +++++++++++++++++++----- 9 files changed, 412 insertions(+), 103 deletions(-) create mode 100644 src/assets/img/star.png diff --git a/src/apis/createVideo.js b/src/apis/createVideo.js index 24c88bc..b62dfbc 100644 --- a/src/apis/createVideo.js +++ b/src/apis/createVideo.js @@ -180,4 +180,16 @@ export function findByIdApi(id) { url: `/api/userPhotoVideo/findById?id=${id}`, method: 'get', }) +} + +/** + * @description 获取音乐列表 + * @params data + * @returns data + */ +export function musicListApi() { + return request({ + url: `api/userPhotoVideo/music`, + method: 'get', + }) } \ No newline at end of file diff --git a/src/assets/img/star.png b/src/assets/img/star.png new file mode 100644 index 0000000000000000000000000000000000000000..3b0137fa141a230198de8fe23bbc12df6c467be7 GIT binary patch literal 5345 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 JQeFFq{{cwU-*Nx| literal 0 HcmV?d00001 diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts index b192b79..d8bfbdf 100644 --- a/src/lang/package/en.ts +++ b/src/lang/package/en.ts @@ -69,6 +69,8 @@ export default { music:'Music', Aipicture:'Ai-generated pictures', AipictureTip:'Please customize your picture', + chooseMusic:'Choose music', + searchMusic:'Search music' }, // 我的视频 diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts index f08c51b..ba5e6df 100644 --- a/src/lang/package/zh-cn.ts +++ b/src/lang/package/zh-cn.ts @@ -69,6 +69,8 @@ export default { music:'音乐', Aipicture:'Ai生成图片', AipictureTip:'请自定义您的图片', + chooseMusic:'选择音乐', + searchMusic:'搜索音乐', }, // 我的视频 diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index fe8e71d..22b58ff 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -16,12 +16,15 @@ -
- +
+
{{ $t("shop.title") }}
+
+
+ +
+ API +
@@ -103,7 +109,13 @@ function routerTo(url: RouteLocationRaw) { .pricing { position: absolute; - bottom: 20px; + bottom: 60px; + width: calc(100% - 40px); + text-align: center; + } + .API { + position: absolute; + bottom: 0px; width: calc(100% - 40px); text-align: center; } diff --git a/src/store/modules/userInfo.js b/src/store/modules/userInfo.js index f186337..2beeb57 100644 --- a/src/store/modules/userInfo.js +++ b/src/store/modules/userInfo.js @@ -9,11 +9,16 @@ export const userInfoModules = defineStore("userInfo", () => { function setEmail(params) { email.value = params } + // 登录获取用户信息 async function getUserInfo() { const res = await getUserInfoApi() userInfo.value = res.data } - return { userInfo, setEmail, getUserInfo }; + // 退出清除用户信息 + function loginOut(params) { + userInfo.value = null + } + return { userInfo, setEmail, getUserInfo, loginOut }; }, { persist: true, diff --git a/src/types/components.d.ts b/src/types/components.d.ts index cbeaaba..f5f10bc 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -53,9 +53,11 @@ declare module '@vue/runtime-core' { IEpCloseBold: typeof import('~icons/ep/close-bold')['default'] IEpCollection: typeof import('~icons/ep/collection')['default'] IEpDelete: typeof import('~icons/ep/delete')['default'] + IEpDocumentAdd: typeof import('~icons/ep/document-add')['default'] IEpDownload: typeof import('~icons/ep/download')['default'] IEpEdit: typeof import('~icons/ep/edit')['default'] IEpGoods: typeof import('~icons/ep/goods')['default'] + IEpHeadset: typeof import('~icons/ep/headset')['default'] IEpLoading: typeof import('~icons/ep/loading')['default'] IEpMenu: typeof import('~icons/ep/menu')['default'] IEpMic: typeof import('~icons/ep/mic')['default'] diff --git a/src/views/createVideo/index.vue b/src/views/createVideo/index.vue index 7436c33..db5bafc 100644 --- a/src/views/createVideo/index.vue +++ b/src/views/createVideo/index.vue @@ -159,10 +159,14 @@
+
+ GPT + +
{{ $t("createVideo.Aipicture") }}
@@ -239,6 +243,10 @@
+
+ GPT + +
@@ -348,7 +356,7 @@

- + {{ $t("createVideo.uploadAudio") }}

@@ -415,133 +423,167 @@
-
+ +

+ + {{ $t("createVideo.chooseMusic") }} +

+ +
- - {{ $t("createVideo.confirm") }} - - - - - +
-

{{ $t("createVideo.languages") }}

- +
+
+ {{ item.name }} + {{ handleTime(item.time) }} +
+
+
+ +
+ + - -
-

{{ $t("createVideo.voices") }}

- + {{ + $t("createVideo.saveVideo") + }} - - -

{{ $t("createVideo.styles") }}

- + - - - {{ - $t("createVideo.generateVideo") - }} + + {{ + $t("createVideo.generateVideo") + }} +
-
+
+ - - {{ $t("createVideo.confirm") }} - - - - - + 🔊 + 🕗

{{ $t("createVideo.languages") }}

+ + :label="item.name" + :value="item.id" + > + + {{ item.name }} +

{{ $t("createVideo.voices") }}

+

{{ $t("createVideo.styles") }}

+ - {{ - $t("createVideo.generateVideo") - }} + + + + {{ + $t("createVideo.saveVideo") + }} + + + + {{ + $t("createVideo.generateVideo") + }}
+
@@ -568,6 +610,7 @@ import { createVideoApi, previewAudioApi, findByIdApi, + musicListApi, } from "@/apis/createVideo"; import { useI18n } from "vue-i18n"; import Recorder from "js-audio-recorder"; //mp3插件 @@ -1025,7 +1068,7 @@ async function saveOrUpdate(index, isSaveVideo) { if (createLoading.value == true) { return; } - tabFrom.value = index; + tabFrom.value = index; // 判断是哪一个tab栏内的生成视频按钮 const saveOrUpdateData = { id: id.value, //从草稿或者重新编辑回到创建视频时有id title: title.value, @@ -1035,6 +1078,7 @@ async function saveOrUpdate(index, isSaveVideo) { speakTypeStr: soundStyle.value, //声音风格 voiceMouldId: sound.value, //选择声音id voiceFrom=1 时必传 voiceMaterialId: afterSaveAudioId.value, //上传音频且保存音频后得到的id voiceFrom=2 时必传 + musicId: musicItemAction.value, // 选中音乐的id,voiceFrom=3 时必传 }; if (index == 1) { createLoading.value = true; @@ -1072,6 +1116,35 @@ async function saveOrUpdate(index, isSaveVideo) { createLoading.value = false; } } + if (index == 3) { + try { + const res1 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据 + + // 这个if判断是不是仅仅保存视频 + if (isSaveVideo == "saveVideo") { + ElMessage.success( + lanChange.value == "zh-cn" ? `已保存为草稿` : `Saved as manuscript` + ); + createLoading.value = false; + router.push("/myCreating"); + return; + } + console.log("ceshi"); + const res2 = await createVideoApi({ id: res1.data.id }); // 生成视频 + if (res2.message == "success") { + ElMessage.success( + lanChange.value == "zh-cn" + ? `视频正在生成中,请耐心等待` + : `The video is being generated, please wait patiently` + ); + } + createLoading.value = false; + router.push("/myCreating"); + } catch (error) { + ElMessage.error(error); + createLoading.value = false; + } + } } //#endregion ---------------------------- @@ -1087,14 +1160,56 @@ async function findById(findId) { afterSaveAudioId.value = res.data.voiceMaterialId; //保存音频后得到的id imgUrl.value = res.data.personPhotoUrl; //图片回显 audioUrl.value = res.data.voiceMaterialUrl; // mp3回显 - language.value = res.data.voiceInfo.languageId; - await chooseType(language.value); + musicItemAction.value = res.data.musicId; //音乐id回显 + language.value = res.data.voiceInfo ? res.data.voiceInfo.languageId : null; + if (language.value) { + await chooseType(language.value); + } sound.value = res.data.voiceMouldId; //声音id chooseStyle(); soundStyle.value = res.data.speakTypeStr; //选择风格 } //#endregion ---------------------------- +//#region 音乐tab +const musicList = ref(null); //展示音乐列表 +const audioMusicUrl = ref(null); //选中音乐Url回显 +const musicItemAction = ref(null); //选中高亮 +// 获取音乐列表 +async function getMusicList() { + try { + const res = await musicListApi(); + musicList.value = res.data; + } catch (error) { + console.log(error); + } +} +// 点击选择音乐 +function chooseMusicUrl(url, id) { + audioMusicUrl.value = url; + musicItemAction.value = id; +} +// 转化秒为分秒 +function handleTime(time) { + let m = Math.floor(time / 60); + let s = time % 60; + if (s < 10) { + s = "0" + s; + } + return m + ":" + s; +} +// 搜索功能 +const searchInput = ref(null); +async function searchMusicList() { + // const res = await + console.log("搜索"); +} +//#endregion ---------------------------- + +//#region + +//#endregion ---------------------------- + //#region //#endregion ---------------------------- @@ -1116,8 +1231,15 @@ onMounted(async () => { } await voiceTotal(); if (route.query.id) { - findById(route.query.id); + await findById(route.query.id); } + await getMusicList(); + + musicList.value.forEach((item) => { + if (item.id == musicItemAction.value) { + audioMusicUrl.value = item.url; + } + }); }); @@ -1342,7 +1464,7 @@ onMounted(async () => { padding: 10px; > div { margin-right: 20px; - padding: 5px 10px; + padding: 10px 15px; transition: all 0.3s; border-radius: 5px; &:hover { @@ -1470,6 +1592,38 @@ onMounted(async () => { background-size: 200% 100% !important; } } + .aiPicTab { + position: relative; + z-index: 2; + .subscript { + position: absolute; + top: -20px; + right: -20px; + width: 40px; + height: 40px; + + z-index: 1; + img { + position: absolute; + top: 0; + left: 0px; + width: 100%; + height: 100%; + z-index: 3; + } + span { + position: absolute; + line-height: 45px; + z-index: 4; + padding-left: 0px; + padding-bottom: 5px; + font-size: 16px; + color: #17ceb9; + font-weight: 900; + transform: rotate(45deg); + } + } + } } } @@ -1479,6 +1633,36 @@ onMounted(async () => { padding: 30px 30px 20px 30px; background-color: #f1f2f6; border-radius: 30px 0 0 0; + position: relative; + z-index: 2; + + .subscript { + position: absolute; + top: 30px; + right: 30px; + width: 40px; + height: 40px; + z-index: 3; + img { + position: absolute; + top: 0; + left: 0px; + width: 100%; + height: 100%; + z-index: 3; + } + span { + position: absolute; + line-height: 45px; + z-index: 4; + padding-left: 0px; + padding-bottom: 5px; + font-size: 16px; + color: #17ceb9; + font-weight: 900; + transform: rotate(45deg); + } + } :deep(.el-tabs--border-card) { font-size: 20px; border: none; @@ -1488,6 +1672,7 @@ onMounted(async () => { height: 100%; padding: 20px 20px 0px 20px; border-radius: 20px; + .card1 { .text { padding: 10px; @@ -1607,10 +1792,89 @@ onMounted(async () => { } } .card3 { + width: 100%; + padding: 10px; + .el-icon { + vertical-align: text-top; + } + .musicList { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + .musicItem { + width: 100%; + height: 30px; + position: relative; + margin-top: 10px; + padding: 0 20px; + border: #000 1px solid; + border-radius: 10px; + overflow: hidden; + transition: all 0.3s; + box-shadow: #00000026 2px 2px 2px 2px; + transition: all 0.3s; + cursor: pointer; + .musicNmae { + display: inline-block; + width: 320px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .musicTime { + display: inline-block; + max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + .musicItemAvtive { + background-color: #000; + color: #fff; + } + } + .AudioBox { + display: flex; + justify-content: space-around; + width: 100%; + padding: 20px; + transition: all 0.3s; + audio { + width: 100%; + } + } + > .el-button { + width: 100%; + height: 50px; + margin-top: 10px; + // background-color: #000; + } + :deep(.el-input__wrapper) { + border: none; + border-bottom: 2px solid #000; + border-radius: 0; + box-shadow: none; + } + + .el-icon.icon-edit { + width: 30px; + height: 30px; + font-size: 30px; + color: #8c939d; + text-align: center; + cursor: pointer; + transition: all 0.3s; + &:hover { + color: #292929; + } + } + } + .card4 { .text { padding: 10px; border: 1px solid #000; - .el-button { float: right; margin-top: 10px; @@ -1623,7 +1887,7 @@ onMounted(async () => { } p { - margin: 10px 0; + margin: 7px 0; } > .el-button { @@ -1631,8 +1895,12 @@ onMounted(async () => { height: 50px; margin-top: 10px; } - } + :deep(.el-input .is-focus) { + // box-shadow: none !important; + // box-shadow: 0 0 0 1px #000 !important; + } + } :deep(.el-tabs__item.is-active) { color: #909393; background-color: #000; @@ -1643,7 +1911,7 @@ onMounted(async () => { } :deep(.el-tabs__item) { - width: 25%; + width: 26%; } :deep(.el-tabs__item:hover) {