diff --git a/src/apis/createVideo.js b/src/apis/createVideo.js index 8ef4022..c562522 100644 --- a/src/apis/createVideo.js +++ b/src/apis/createVideo.js @@ -12,6 +12,18 @@ export function personPhotoList(pageNum, pageSize, sendType) { }) } +/** + * @description 获取人脸列表 + * @params pageNum, pageSize + * @returns data + */ +export function personPhotoUserListList(pageNum, pageSize, sendType) { + return request({ + url: `api/personPhoto/userList?pageNum=${pageNum}&pageSize=${pageSize}&sendType=${sendType}`, + method: 'get' + }) +} + /** * @description 上传图片 * @params data @@ -37,6 +49,18 @@ export function saveImgApi(data) { }) } +/** + * @description 删除图片 + * @params id + * @returns data + */ +export function delImgApi(id) { + return request({ + url: `api/personPhoto/del?id=${id}`, + method: 'get', + }) +} + /** * @description 上传视频 * @params data @@ -105,10 +129,17 @@ export function chooseTypeApi(id) { * @params id * @returns data */ -export function previewAudioApi(genTxt, voiceId, voiceStyle) { +// export function previewAudioApi(genTxt, voiceId, voiceStyle) { +// return request({ +// url: `api/voiceMould/preview?genTxt=${genTxt}&voiceId=${voiceId}&voiceStyle=${voiceStyle}`, +// method: 'GET', +// }) +// } +export function previewAudioApi(gen_txt, voice_id, voice_style) { return request({ - url: `api/voiceMould/preview?genTxt=${genTxt}&voiceId=${voiceId}&voiceStyle=${voiceStyle}`, - method: 'GET', + url: `api/voiceMould/preview`, + method: 'POST', + data: { gen_txt, voice_id, voice_style } }) } diff --git a/src/assets/img/false1.png b/src/assets/img/false1.png new file mode 100644 index 0000000..b9d3e55 Binary files /dev/null and b/src/assets/img/false1.png differ diff --git a/src/assets/img/false2.png b/src/assets/img/false2.png new file mode 100644 index 0000000..72b5850 Binary files /dev/null and b/src/assets/img/false2.png differ diff --git a/src/assets/img/false3.png b/src/assets/img/false3.png new file mode 100644 index 0000000..0f01c8d Binary files /dev/null and b/src/assets/img/false3.png differ diff --git a/src/assets/img/trueImg.png b/src/assets/img/trueImg.png new file mode 100644 index 0000000..86937aa Binary files /dev/null and b/src/assets/img/trueImg.png differ diff --git a/src/lang/package/en.ts b/src/lang/package/en.ts index 33ed014..95d5714 100644 --- a/src/lang/package/en.ts +++ b/src/lang/package/en.ts @@ -81,6 +81,7 @@ export default { draftText: "Draft", generatingText: "The video is generating, please wait a moment", generationFailedText: "The video generate is failed, Reason:", + edit:'edit' }, // 个人账户 diff --git a/src/lang/package/zh-cn.ts b/src/lang/package/zh-cn.ts index ef3eaf5..892b898 100644 --- a/src/lang/package/zh-cn.ts +++ b/src/lang/package/zh-cn.ts @@ -81,6 +81,7 @@ export default { draftText: "草稿", generatingText: "视频正在生成中,请稍等哦", generationFailedText: "视频生成失败。原因:", + edit:'编辑' }, // 个人账户 diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue index 39d01a9..5a8a6c1 100644 --- a/src/layout/components/AppMain.vue +++ b/src/layout/components/AppMain.vue @@ -23,7 +23,7 @@ const tagsViewStore = useTagsViewStore(); /* 50= navbar 50 */ min-height: calc(100vh - 80px); - overflow: hidden; + // overflow: hidden; // background-color: var(--el-bg-color-page); background-color: #000; } diff --git a/src/types/auto-imports.d.ts b/src/types/auto-imports.d.ts index eb6c842..e5c7bdb 100644 --- a/src/types/auto-imports.d.ts +++ b/src/types/auto-imports.d.ts @@ -5,7 +5,6 @@ declare global { const ElForm: typeof import('element-plus/es')['ElForm'] const ElMessage: typeof import('element-plus/es')['ElMessage'] const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] - const ElTree: typeof import('element-plus/es')['ElTree'] const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const computed: typeof import('vue')['computed'] @@ -275,7 +274,6 @@ declare module 'vue' { readonly ElForm: UnwrapRef readonly ElMessage: UnwrapRef readonly ElMessageBox: UnwrapRef - readonly ElTree: UnwrapRef readonly asyncComputed: UnwrapRef readonly autoResetRef: UnwrapRef readonly computed: UnwrapRef diff --git a/src/types/components.d.ts b/src/types/components.d.ts index a91ade0..0fd84b0 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -49,11 +49,13 @@ declare module '@vue/runtime-core' { IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default'] IEpCaretTop: typeof import('~icons/ep/caret-top')['default'] IEpClose: typeof import('~icons/ep/close')['default'] + IEpCloseBold: typeof import('~icons/ep/close-bold')['default'] IEpCollection: typeof import('~icons/ep/collection')['default'] IEpDelete: typeof import('~icons/ep/delete')['default'] IEpDownload: typeof import('~icons/ep/download')['default'] IEpEdit: typeof import('~icons/ep/edit')['default'] IEpGoods: typeof import('~icons/ep/goods')['default'] + IEpLoading: typeof import('~icons/ep/loading')['default'] IEpMenu: typeof import('~icons/ep/menu')['default'] IEpMic: typeof import('~icons/ep/mic')['default'] IEpPlus: typeof import('~icons/ep/plus')['default'] diff --git a/src/views/createVideo/index copy.vue b/src/views/createVideo/index copy.vue index 0fb95c0..4cfe35f 100644 --- a/src/views/createVideo/index copy.vue +++ b/src/views/createVideo/index copy.vue @@ -7,7 +7,11 @@
-
+
@@ -83,11 +95,7 @@
-
+
+
@@ -114,13 +122,6 @@
- - - {{ $t("createVideo.confirm") }} - + {{ $t("createVideo.generateVideo") }} + + + + {{ + $t("createVideo.saveVideo") + }}
@@ -208,7 +222,7 @@

- 上传音频 + {{ $t("createVideo.uploadAudio") }}

+ @@ -230,7 +244,7 @@

- 录制音频 + {{ $t("createVideo.recordedAudio") }}

- 开始录音 + {{ $t("createVideo.startRecorded") }}
@@ -258,12 +272,25 @@ 上传音频 -->
+ {{ $t("createVideo.generateVideo") }} + + + + {{ + $t("createVideo.saveVideo") + }}
@@ -355,9 +382,13 @@ import { createVideoApi, previewAudioApi, } from "@/apis/createVideo"; +import { useI18n } from "vue-i18n"; import Recorder from "js-audio-recorder"; //mp3插件 import imageCompression from "browser-image-compression"; //压缩图片插件 +const { locale } = useI18n(); +const lanChange = ref(locale); + //#region 头像区的逻辑 // 获取AI头像 const AiFaceList = ref([]); @@ -399,18 +430,27 @@ function setImgUrl(url, id) { //#region 预览图片 const compressionImgLoad = ref(false); async function lookImg(e) { - // 压缩配置 - compressionImgLoad.value = true; - const options = { - maxSizeMB: 2, // 最大压缩大小为 1MB - useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 - }; - const compressedFile = await imageCompression(e.target.files[0], options); - imgUrl.value = URL.createObjectURL(compressedFile); - imgData.value = compressedFile; - showUploadBtn.value = false; - submitImgBtn.value = true; - compressionImgLoad.value = false; + if (e.target.files[0]) { + faceItemActive.value = null; + imgUrl.value = null; + imgData.value = null; + showUploadBtn.value = true; + submitImgBtn.value = false; + compressionImgLoad.value = true; + // 压缩配置 + const options = { + maxSizeMB: 2, // 最大压缩大小为 1MB + useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 + }; + const compressedFile = await imageCompression(e.target.files[0], options); + imgUrl.value = URL.createObjectURL(compressedFile); + imgData.value = compressedFile; + showUploadBtn.value = false; + submitImgBtn.value = true; + compressionImgLoad.value = false; + } else { + return; + } } //#endregion ------------------ @@ -422,6 +462,11 @@ const imgUrl = ref(""); //图片回显路径 const imgData = ref(""); // 上传图片文件 const showUploadBtn = ref(false); //上传图片+号的显示隐藏 const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 +// 点击AI头像区的+号 +function clickAddBtn() { + faceItemActive.value = null; + showUploadBtn.value = true; +} // 上传图片 async function changeFile() { imgUrl.value = URL.createObjectURL(imgData.value); @@ -429,13 +474,21 @@ async function changeFile() { const timestamp = Date.now(); formData.append("file", imgData.value, timestamp + ".png"); try { + // 上传图片 const res = await awsImgUpload(formData); - if (res.code == 200) { - ElMessage.success("上传成功!"); + // 保存图片 + const res2 = await saveImgApi({ material: res.data.url }); + // 重新获取列表 + getAiFaceList(1, 100, 1); + if (res2.code == 200) { + ElMessage.success( + lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully` + ); } else { - ElMessage.error("上传失败!"); + ElMessage.error( + lanChange.value == "zh-cn" ? `上传失败` : `Upload failure` + ); } - const res2 = await saveImgApi({ material: res.data.url }); } catch (error) { ElMessage.error(error); } @@ -503,11 +556,19 @@ async function chooseStyle() { const previewAudioUrl = ref(null); async function getPreviewAudio() { if (!textareaContent.value) { - ElMessage.error("您还没有输入文案"); + ElMessage.error( + lanChange.value == "zh-cn" + ? `您还没有输入文案` + : `You have not entered the copy yet` + ); return; } if (!sound.value) { - ElMessage.error("您还没有选择声音"); + ElMessage.error( + lanChange.value == "zh-cn" + ? `您还没有选择声音` + : `You have not selected the sound` + ); return; } @@ -565,7 +626,7 @@ const playRecording = () => { } }; // 上传音频 -async function uploadAudio() { +async function uploadAudio(isSaveVideo) { createLoading.value = true; let formData = new FormData(); const timestamp = Date.now(); @@ -576,12 +637,14 @@ async function uploadAudio() { if (res) { // ElMessage.success("上传成功!"); } else { - ElMessage.error("音频上传失败!"); + ElMessage.error( + lanChange.value == "zh-cn" ? `上传音频失败!` : `Failed to upload audio!` + ); return; } // 查询进度 intervalId = setInterval(() => { - uploadProgress(res.data.videoId); + uploadProgress(res.data.videoId, isSaveVideo); }, 1000); // ElMessage.success("上传成功!"); } catch (error) { @@ -604,7 +667,7 @@ const handleFileChange = async () => { }; // 获取视频上传进度 const afterSaveAudioId = ref(null); -async function uploadProgress(videoId) { +async function uploadProgress(videoId, isSaveVideo) { const res = await uploadProgressApi(videoId); if (res.data == "complete") { clearInterval(intervalId); @@ -625,9 +688,20 @@ async function uploadProgress(videoId) { }; try { const res3 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据 + if (isSaveVideo == "saveVideo") { + ElMessage.success( + lanChange.value == "zh-cn" ? `已保存为草稿` : `Saved as draft` + ); + createLoading.value = false; + return; + } const res4 = await createVideoApi({ id: res3.data.id }); // 生成视频 if (res4.message == "success") { - ElMessage.success("视频正在生成,请耐心等待"); + ElMessage.success( + lanChange.value == "zh-cn" + ? `视频正在生成中,请耐心等待` + : `The video is being generated, please wait patiently` + ); } createLoading.value = false; } catch (error) { @@ -644,7 +718,7 @@ const tabFrom = ref(1); const createLoading = ref(false); // 上传音频后,得到videoId // 保存数据 -async function saveOrUpdate(index) { +async function saveOrUpdate(index, isSaveVideo) { if (createLoading.value == true) { return; } @@ -661,9 +735,20 @@ async function saveOrUpdate(index) { createLoading.value = true; try { const res2 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据 + if (isSaveVideo == "saveVideo") { + ElMessage.success( + lanChange.value == "zh-cn" ? `已保存为草稿` : `Saved as draft` + ); + createLoading.value = false; + return; + } const res3 = await createVideoApi({ id: res2.data.id }); // 生成视频 if (res3.message == "success") { - ElMessage.success("视频正在生成,请耐心等待"); + ElMessage.success( + lanChange.value == "zh-cn" + ? `视频正在生成中,请耐心等待` + : `The video is being generated, please wait patiently` + ); } createLoading.value = false; } catch (error) { @@ -673,7 +758,7 @@ async function saveOrUpdate(index) { } if (index == 2) { try { - const res1 = await uploadAudio(); // 上传音频 + const res1 = await uploadAudio(isSaveVideo); // 上传音频 } catch (error) { ElMessage.error(error); createLoading.value = false; @@ -768,13 +853,34 @@ onMounted(() => { width: 100%; height: 100%; border: 1px solid #000; - + .imgBox { + position: relative; + width: 100%; + height: 100%; + border-radius: 50%; + overflow: hidden; + border: 1px solid #ccc; + img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 120%; + } + } .trueImg { + position: relative; top: 60px; width: 100px; height: 100px; - background-color: green; border-radius: 50%; + .icon { + position: absolute; + top: 0%; + right: -5%; + border: 2px solid #00ff95; + color: #00ff95; + } } .el-upload { position: absolute; @@ -791,7 +897,7 @@ onMounted(() => { font-size: 50px; line-height: 100px; text-align: center; - background-color: pink; + background-color: #ccc; border-radius: 50%; } @@ -800,7 +906,7 @@ onMounted(() => { // background-color: #795562; display: flex; justify-content: space-evenly; - width: 500px; + width: 700px; height: 100px; > div { @@ -809,6 +915,13 @@ onMounted(() => { height: 100px; background-color: #ccc; border-radius: 50%; + .icon { + position: absolute; + top: 0%; + right: -5%; + border: 2px solid red; + color: red; + } } } } @@ -821,6 +934,7 @@ onMounted(() => { width: 100%; height: 100%; opacity: 0; + cursor: pointer; } .icon { diff --git a/src/views/createVideo/index.vue b/src/views/createVideo/index.vue index bd47601..3c879be 100644 --- a/src/views/createVideo/index.vue +++ b/src/views/createVideo/index.vue @@ -3,8 +3,8 @@
- -
+ +
- -
- - -
- -
+ +
+
+ +
@@ -50,10 +43,84 @@
-
×
-
×
-
×
+
+
+ +
+
×
+
+
+
+ +
+
×
+
+
+
+ +
+
×
+
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ + + +
+
+
+
+ +
+
×
+
+
+
+ +
+
×
+
+
+
+ +
+
×
+
+
+
+
+ +
+ + +
+ +
+
+ +
+
@@ -75,7 +142,8 @@ {{ $t("createVideo.personalWarehouse") }}
-
+ +
+ @@ -95,6 +163,33 @@ s
+ +
+ +
+ + +
+ + +
+
+ +
+
+ ✖︎ +
+
+
@@ -353,7 +448,9 @@ import { getCurrentInstance } from "vue"; import { personPhotoList, + personPhotoUserListList, awsImgUpload, + delImgApi, videoUpload, saveImgApi, uploadProgressApi, @@ -374,7 +471,9 @@ const lanChange = ref(locale); //#region 头像区的逻辑 // 获取AI头像 const AiFaceList = ref([]); +const userAiFaceList = ref([]); const feceItemLoading = ref(false); +const feceItemLoading2 = ref(false); function getAiFaceList(pageNum, pageSize, sendType) { feceItemLoading.value = true; personPhotoList(pageNum, pageSize, sendType) @@ -387,6 +486,18 @@ function getAiFaceList(pageNum, pageSize, sendType) { console.log(err, "err"); }); } +function getAiFaceUserList(pageNum, pageSize, sendType) { + feceItemLoading2.value = true; + personPhotoUserListList(pageNum, pageSize, sendType) + .then((res) => { + userAiFaceList.value = res.data.list; + feceItemLoading2.value = false; + }) + .catch((err) => { + feceItemLoading2.value = false; + console.log(err, "err"); + }); +} // 选择显示的face列表 const showFace = ref("0"); function ChangeShowFaceList(index) { @@ -395,7 +506,7 @@ function ChangeShowFaceList(index) { getAiFaceList(1, 100, 1); } if (index == 1) { - getAiFaceList(1, 100, 3); + getAiFaceUserList(1, 100, 3); } showFace.value = index; } @@ -403,10 +514,32 @@ const faceItemActive = ref(); //高亮处理和当前选择图片的ID // 点击aifece function setImgUrl(url, id) { faceItemActive.value = id; - showUploadBtn.value = false; + showUploadBtn.value = 1; submitImgBtn.value = false; imgUrl.value = url; } +async function deleteFaceImg(id) { + const msg = + lanChange.value == "zh-cn" + ? `确定要删除这张图片吗? ` + : `Are you sure to delete this image ? `; + const notice = lanChange.value == "zh-cn" ? "提示" : "Notice"; + const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm"; + const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel"; + ElMessageBox.confirm(msg, notice, { + confirmButtonText: confirm, + cancelButtonText: cancel, + }).then(async () => { + try { + const res = await delImgApi(id); + imgUrl.value = null; + faceItemActive.value = null; + getAiFaceUserList(1, 100, 3); + } catch (error) { + ElMessage.error(errpr); + } + }); +} //#endregion ------------------------------ //#region 预览图片 @@ -416,7 +549,7 @@ async function lookImg(e) { faceItemActive.value = null; imgUrl.value = null; imgData.value = null; - showUploadBtn.value = true; + showUploadBtn.value = 3; submitImgBtn.value = false; compressionImgLoad.value = true; // 压缩配置 @@ -427,7 +560,7 @@ async function lookImg(e) { const compressedFile = await imageCompression(e.target.files[0], options); imgUrl.value = URL.createObjectURL(compressedFile); imgData.value = compressedFile; - showUploadBtn.value = false; + showUploadBtn.value = 4; submitImgBtn.value = true; compressionImgLoad.value = false; } else { @@ -442,15 +575,17 @@ const title = ref(""); //#region 上传图片 const imgUrl = ref(""); //图片回显路径 const imgData = ref(""); // 上传图片文件 -const showUploadBtn = ref(false); //上传图片+号的显示隐藏 +const showUploadBtn = ref(1); //上传图片+号的显示隐藏 const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 // 点击AI头像区的+号 function clickAddBtn() { faceItemActive.value = null; - showUploadBtn.value = true; + showUploadBtn.value = 2; } // 上传图片 async function changeFile() { + compressionImgLoad.value = true; + showUploadBtn.value = 3; imgUrl.value = URL.createObjectURL(imgData.value); let formData = new FormData(); const timestamp = Date.now(); @@ -461,7 +596,9 @@ async function changeFile() { // 保存图片 const res2 = await saveImgApi({ material: res.data.url }); // 重新获取列表 - getAiFaceList(1, 100, 1); + compressionImgLoad.value = false; + showUploadBtn.value = 4; + getAiFaceUserList(1, 100, 3); if (res2.code == 200) { ElMessage.success( lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully` @@ -661,6 +798,7 @@ async function uploadProgress(videoId, isSaveVideo) { } // 定义参数 const saveOrUpdateData = { + title: title.value, personPhotoId: faceItemActive.value, //任务照片id, voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 paperwork: textareaContent.value, //文案 @@ -706,6 +844,7 @@ async function saveOrUpdate(index, isSaveVideo) { } tabFrom.value = index; const saveOrUpdateData = { + title: title.value, personPhotoId: faceItemActive.value, //任务照片id, voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 paperwork: textareaContent.value, //文案 @@ -765,6 +904,7 @@ const t = globalProperties.$t(string); onMounted(() => { getAiFaceList(1, 100, 1); + getAiFaceUserList(1, 100, 3); voiceTotal(); chooseType(); }); @@ -835,13 +975,34 @@ onMounted(() => { width: 100%; height: 100%; border: 1px solid #000; - + .imgBox { + position: relative; + width: 100%; + height: 100%; + border-radius: 50%; + overflow: hidden; + border: 1px solid #ccc; + img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 120%; + } + } .trueImg { + position: relative; top: 60px; width: 100px; height: 100px; - background-color: green; border-radius: 50%; + .icon { + position: absolute; + top: 0%; + right: -5%; + border: 2px solid #00ff95; + color: #00ff95; + } } .el-upload { position: absolute; @@ -858,7 +1019,7 @@ onMounted(() => { font-size: 50px; line-height: 100px; text-align: center; - background-color: pink; + background-color: #ccc; border-radius: 50%; } @@ -867,7 +1028,7 @@ onMounted(() => { // background-color: #795562; display: flex; justify-content: space-evenly; - width: 500px; + width: 700px; height: 100px; > div { @@ -876,6 +1037,13 @@ onMounted(() => { height: 100px; background-color: #ccc; border-radius: 50%; + .icon { + position: absolute; + top: 0%; + right: -5%; + border: 2px solid red; + color: red; + } } } } @@ -888,6 +1056,7 @@ onMounted(() => { width: 100%; height: 100%; opacity: 0; + cursor: pointer; } .icon { @@ -973,6 +1142,20 @@ onMounted(() => { width: 100%; } } + .deleteIcon { + position: absolute; + top: 0; + right: 15px; + z-index: 999; + width: 25px; + height: 25px; + border: 2px solid #6d76ef; + border-radius: 50%; + color: #6d76ef; + font-size: 20px; + line-height: 23px; + cursor: pointer; + } .uploadImg { line-height: 145px; font-size: 50px; diff --git a/src/views/myCreating/index.vue b/src/views/myCreating/index.vue index 34a865f..d5dfddd 100644 --- a/src/views/myCreating/index.vue +++ b/src/views/myCreating/index.vue @@ -68,12 +68,17 @@ />
...
-
+ +
{{ $t("myCreating.download") }}
+
+ + +
+