| @@ -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 上传图片 | * @description 上传图片 | ||||
| * @params data | * @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 上传视频 | * @description 上传视频 | ||||
| * @params data | * @params data | ||||
| @@ -105,10 +129,17 @@ export function chooseTypeApi(id) { | |||||
| * @params id | * @params id | ||||
| * @returns data | * @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({ | 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 } | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -81,6 +81,7 @@ export default { | |||||
| draftText: "Draft", | draftText: "Draft", | ||||
| generatingText: "The video is generating, please wait a moment", | generatingText: "The video is generating, please wait a moment", | ||||
| generationFailedText: "The video generate is failed, Reason:", | generationFailedText: "The video generate is failed, Reason:", | ||||
| edit:'edit' | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -81,6 +81,7 @@ export default { | |||||
| draftText: "草稿", | draftText: "草稿", | ||||
| generatingText: "视频正在生成中,请稍等哦", | generatingText: "视频正在生成中,请稍等哦", | ||||
| generationFailedText: "视频生成失败。原因:", | generationFailedText: "视频生成失败。原因:", | ||||
| edit:'编辑' | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -23,7 +23,7 @@ const tagsViewStore = useTagsViewStore(); | |||||
| /* 50= navbar 50 */ | /* 50= navbar 50 */ | ||||
| min-height: calc(100vh - 80px); | min-height: calc(100vh - 80px); | ||||
| overflow: hidden; | |||||
| // overflow: hidden; | |||||
| // background-color: var(--el-bg-color-page); | // background-color: var(--el-bg-color-page); | ||||
| background-color: #000; | background-color: #000; | ||||
| } | } | ||||
| @@ -5,7 +5,6 @@ declare global { | |||||
| const ElForm: typeof import('element-plus/es')['ElForm'] | const ElForm: typeof import('element-plus/es')['ElForm'] | ||||
| const ElMessage: typeof import('element-plus/es')['ElMessage'] | const ElMessage: typeof import('element-plus/es')['ElMessage'] | ||||
| const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | ||||
| const ElTree: typeof import('element-plus/es')['ElTree'] | |||||
| const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | ||||
| const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | ||||
| const computed: typeof import('vue')['computed'] | const computed: typeof import('vue')['computed'] | ||||
| @@ -275,7 +274,6 @@ declare module 'vue' { | |||||
| readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> | readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> | ||||
| readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | ||||
| readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | ||||
| readonly ElTree: UnwrapRef<typeof import('element-plus/es')['ElTree']> | |||||
| readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | ||||
| readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | ||||
| readonly computed: UnwrapRef<typeof import('vue')['computed']> | readonly computed: UnwrapRef<typeof import('vue')['computed']> | ||||
| @@ -49,11 +49,13 @@ declare module '@vue/runtime-core' { | |||||
| IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default'] | IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default'] | ||||
| IEpCaretTop: typeof import('~icons/ep/caret-top')['default'] | IEpCaretTop: typeof import('~icons/ep/caret-top')['default'] | ||||
| IEpClose: typeof import('~icons/ep/close')['default'] | IEpClose: typeof import('~icons/ep/close')['default'] | ||||
| IEpCloseBold: typeof import('~icons/ep/close-bold')['default'] | |||||
| IEpCollection: typeof import('~icons/ep/collection')['default'] | IEpCollection: typeof import('~icons/ep/collection')['default'] | ||||
| IEpDelete: typeof import('~icons/ep/delete')['default'] | IEpDelete: typeof import('~icons/ep/delete')['default'] | ||||
| IEpDownload: typeof import('~icons/ep/download')['default'] | IEpDownload: typeof import('~icons/ep/download')['default'] | ||||
| IEpEdit: typeof import('~icons/ep/edit')['default'] | IEpEdit: typeof import('~icons/ep/edit')['default'] | ||||
| IEpGoods: typeof import('~icons/ep/goods')['default'] | IEpGoods: typeof import('~icons/ep/goods')['default'] | ||||
| IEpLoading: typeof import('~icons/ep/loading')['default'] | |||||
| IEpMenu: typeof import('~icons/ep/menu')['default'] | IEpMenu: typeof import('~icons/ep/menu')['default'] | ||||
| IEpMic: typeof import('~icons/ep/mic')['default'] | IEpMic: typeof import('~icons/ep/mic')['default'] | ||||
| IEpPlus: typeof import('~icons/ep/plus')['default'] | IEpPlus: typeof import('~icons/ep/plus')['default'] | ||||
| @@ -7,7 +7,11 @@ | |||||
| <div class="left-top" v-show="!showUploadBtn"> | <div class="left-top" v-show="!showUploadBtn"> | ||||
| <el-row class="justify-between"> | <el-row class="justify-between"> | ||||
| <!-- title框 --> | <!-- title框 --> | ||||
| <div class="flex justify-between" style="width: 300px"> | |||||
| <div | |||||
| v-show="!submitImgBtn" | |||||
| class="flex justify-between" | |||||
| style="width: 300px" | |||||
| > | |||||
| <el-input | <el-input | ||||
| v-model="title" | v-model="title" | ||||
| :placeholder="$t('createVideo.typeTitle')" | :placeholder="$t('createVideo.typeTitle')" | ||||
| @@ -18,12 +22,7 @@ | |||||
| <div class="btnBox" v-show="submitImgBtn"> | <div class="btnBox" v-show="submitImgBtn"> | ||||
| <button class="uploadBtn"> | <button class="uploadBtn"> | ||||
| {{ $t("createVideo.reselect") }} | {{ $t("createVideo.reselect") }} | ||||
| <input | |||||
| accept="image/*" | |||||
| type="file" | |||||
| @click="e.target.value = null" | |||||
| @change="lookImg" | |||||
| /> | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | |||||
| </button> | </button> | ||||
| <button class="uploadBtn" @click="changeFile"> | <button class="uploadBtn" @click="changeFile"> | ||||
| {{ $t("createVideo.sureUpload") }} | {{ $t("createVideo.sureUpload") }} | ||||
| @@ -44,21 +43,34 @@ | |||||
| :isLoading="compressionImgLoad" | :isLoading="compressionImgLoad" | ||||
| ></my-loading> | ></my-loading> | ||||
| <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | ||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/trueImg.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">✔</div> | <div class="icon">✔</div> | ||||
| </div> | </div> | ||||
| <div v-if="!compressionImgLoad" class="upload inmiddle"> | <div v-if="!compressionImgLoad" class="upload inmiddle"> | ||||
| + | + | ||||
| <input | |||||
| accept="image/*" | |||||
| type="file" | |||||
| @click="e.target.value = null" | |||||
| @change="lookImg" | |||||
| /> | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | |||||
| </div> | </div> | ||||
| <div v-if="!compressionImgLoad" class="falseImg inmiddle"> | <div v-if="!compressionImgLoad" class="falseImg inmiddle"> | ||||
| <div><div class="icon">×</div></div> | |||||
| <div><div class="icon">×</div></div> | |||||
| <div><div class="icon">×</div></div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false1.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false2.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false3.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -83,11 +95,7 @@ | |||||
| </div> | </div> | ||||
| <div class="faceList"> | <div class="faceList"> | ||||
| <!-- 上传图片组件 --> | <!-- 上传图片组件 --> | ||||
| <div | |||||
| v-if="showFace == 1" | |||||
| class="faceItem" | |||||
| @click="showUploadBtn = true" | |||||
| > | |||||
| <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | |||||
| <span class="uploadImg">+ </span> | <span class="uploadImg">+ </span> | ||||
| </div> | </div> | ||||
| <my-loading :isLoading="feceItemLoading"></my-loading> | <my-loading :isLoading="feceItemLoading"></my-loading> | ||||
| @@ -114,13 +122,6 @@ | |||||
| <el-tab-pane :label="$t('createVideo.typeScript')"> | <el-tab-pane :label="$t('createVideo.typeScript')"> | ||||
| <div class="card1"> | <div class="card1"> | ||||
| <div class="text"> | <div class="text"> | ||||
| <el-input | |||||
| v-model="title" | |||||
| :placeholder="$t('createVideo.typeTitle')" | |||||
| /> | |||||
| <el-button type="primary"> | |||||
| {{ $t("createVideo.confirm") }} | |||||
| </el-button> | |||||
| <!-- 文本域 --> | <!-- 文本域 --> | ||||
| <el-input | <el-input | ||||
| id="textInputId" | id="textInputId" | ||||
| @@ -142,7 +143,7 @@ | |||||
| <el-select | <el-select | ||||
| @change="chooseType" | @change="chooseType" | ||||
| v-model="language" | v-model="language" | ||||
| placeholder="Select" | |||||
| :placeholder="$t('createVideo.select')" | |||||
| style="width: 100%" | style="width: 100%" | ||||
| > | > | ||||
| <el-option | <el-option | ||||
| @@ -169,7 +170,7 @@ | |||||
| @change="chooseStyle" | @change="chooseStyle" | ||||
| :disabled="language ? false : true" | :disabled="language ? false : true" | ||||
| v-model="sound" | v-model="sound" | ||||
| :placeholder="language ? 'Select' : 'Please select language'" | |||||
| :placeholder="$t('createVideo.select')" | |||||
| style="width: 100%" | style="width: 100%" | ||||
| > | > | ||||
| <el-option | <el-option | ||||
| @@ -184,7 +185,7 @@ | |||||
| <el-select | <el-select | ||||
| :disabled="soundStyleOptions ? false : true" | :disabled="soundStyleOptions ? false : true" | ||||
| v-model="soundStyle" | v-model="soundStyle" | ||||
| :placeholder="soundStyleOptions ? 'Select' : '暂无数据'" | |||||
| :placeholder="$t('createVideo.select')" | |||||
| style="width: 100%" | style="width: 100%" | ||||
| > | > | ||||
| <el-option | <el-option | ||||
| @@ -194,12 +195,25 @@ | |||||
| :value="item" | :value="item" | ||||
| /> | /> | ||||
| </el-select> | </el-select> | ||||
| <!-- 生成视频 --> | |||||
| <el-button @click="saveOrUpdate(1)" color="#000" type="primary"> | <el-button @click="saveOrUpdate(1)" color="#000" type="primary"> | ||||
| <my-loading :isLoading="createLoading"></my-loading> | <my-loading :isLoading="createLoading"></my-loading> | ||||
| <span v-if="!createLoading">{{ | <span v-if="!createLoading">{{ | ||||
| $t("createVideo.generateVideo") | $t("createVideo.generateVideo") | ||||
| }}</span></el-button | }}</span></el-button | ||||
| > | > | ||||
| <!-- 保存视频 --> | |||||
| <el-button | |||||
| @click="saveOrUpdate(1, 'saveVideo')" | |||||
| color="#000" | |||||
| type="primary" | |||||
| style="margin-left: 0" | |||||
| > | |||||
| <my-loading :isLoading="createLoading"></my-loading> | |||||
| <span v-if="!createLoading">{{ | |||||
| $t("createVideo.saveVideo") | |||||
| }}</span></el-button | |||||
| > | |||||
| </div> | </div> | ||||
| </el-tab-pane> | </el-tab-pane> | ||||
| <!-- ------------------------ 2 --> | <!-- ------------------------ 2 --> | ||||
| @@ -208,7 +222,7 @@ | |||||
| <!-- 上传视频 --> | <!-- 上传视频 --> | ||||
| <p> | <p> | ||||
| <el-icon class="icon-VideoCamera"><i-ep-VideoCamera /></el-icon> | <el-icon class="icon-VideoCamera"><i-ep-VideoCamera /></el-icon> | ||||
| 上传音频 | |||||
| {{ $t("createVideo.uploadAudio") }} | |||||
| </p> | </p> | ||||
| <div class="uploadVideo"> | <div class="uploadVideo"> | ||||
| + | + | ||||
| @@ -230,7 +244,7 @@ | |||||
| <!-- 录制MP3上传语音 --> | <!-- 录制MP3上传语音 --> | ||||
| <p> | <p> | ||||
| <el-icon class="icon-Mic"><i-ep-Mic /></el-icon> | <el-icon class="icon-Mic"><i-ep-Mic /></el-icon> | ||||
| 录制音频 | |||||
| {{ $t("createVideo.recordedAudio") }} | |||||
| </p> | </p> | ||||
| <div | <div | ||||
| class="uploadAudio" | class="uploadAudio" | ||||
| @@ -242,14 +256,14 @@ | |||||
| :disabled="!isRecording" | :disabled="!isRecording" | ||||
| @click="startRecording" | @click="startRecording" | ||||
| > | > | ||||
| 开始录音 | |||||
| {{ $t("createVideo.startRecorded") }} | |||||
| </button> | </button> | ||||
| <button | <button | ||||
| class="pointer" | class="pointer" | ||||
| @click="stopRecording" | @click="stopRecording" | ||||
| :disabled="isRecording" | :disabled="isRecording" | ||||
| > | > | ||||
| 停止录音 | |||||
| {{ $t("createVideo.stopRecorded") }} | |||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| <!-- <button @click="playRecording">播放录音</button> --> | <!-- <button @click="playRecording">播放录音</button> --> | ||||
| @@ -258,12 +272,25 @@ | |||||
| 上传音频 | 上传音频 | ||||
| </button> --> | </button> --> | ||||
| </div> | </div> | ||||
| <!-- 生成视频 --> | |||||
| <el-button @click="saveOrUpdate(2)" color="#000" type="primary"> | <el-button @click="saveOrUpdate(2)" color="#000" type="primary"> | ||||
| <my-loading :isLoading="createLoading"></my-loading> | <my-loading :isLoading="createLoading"></my-loading> | ||||
| <span v-if="!createLoading">{{ | <span v-if="!createLoading">{{ | ||||
| $t("createVideo.generateVideo") | $t("createVideo.generateVideo") | ||||
| }}</span> | }}</span> | ||||
| </el-button> | </el-button> | ||||
| <!-- 保存视频 --> | |||||
| <el-button | |||||
| @click="saveOrUpdate(2, 'saveVideo')" | |||||
| color="#000" | |||||
| type="primary" | |||||
| style="margin-left: 0" | |||||
| > | |||||
| <my-loading :isLoading="createLoading"></my-loading> | |||||
| <span v-if="!createLoading">{{ | |||||
| $t("createVideo.saveVideo") | |||||
| }}</span></el-button | |||||
| > | |||||
| </div> | </div> | ||||
| </el-tab-pane> | </el-tab-pane> | ||||
| <!-- ----------------------- 3 --> | <!-- ----------------------- 3 --> | ||||
| @@ -355,9 +382,13 @@ import { | |||||
| createVideoApi, | createVideoApi, | ||||
| previewAudioApi, | previewAudioApi, | ||||
| } from "@/apis/createVideo"; | } from "@/apis/createVideo"; | ||||
| import { useI18n } from "vue-i18n"; | |||||
| import Recorder from "js-audio-recorder"; //mp3插件 | import Recorder from "js-audio-recorder"; //mp3插件 | ||||
| import imageCompression from "browser-image-compression"; //压缩图片插件 | import imageCompression from "browser-image-compression"; //压缩图片插件 | ||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| //#region 头像区的逻辑 | //#region 头像区的逻辑 | ||||
| // 获取AI头像 | // 获取AI头像 | ||||
| const AiFaceList = ref([]); | const AiFaceList = ref([]); | ||||
| @@ -399,18 +430,27 @@ function setImgUrl(url, id) { | |||||
| //#region 预览图片 | //#region 预览图片 | ||||
| const compressionImgLoad = ref(false); | const compressionImgLoad = ref(false); | ||||
| async function lookImg(e) { | 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 ------------------ | //#endregion ------------------ | ||||
| @@ -422,6 +462,11 @@ const imgUrl = ref(""); //图片回显路径 | |||||
| const imgData = ref(""); // 上传图片文件 | const imgData = ref(""); // 上传图片文件 | ||||
| const showUploadBtn = ref(false); //上传图片+号的显示隐藏 | const showUploadBtn = ref(false); //上传图片+号的显示隐藏 | ||||
| const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 | const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 | ||||
| // 点击AI头像区的+号 | |||||
| function clickAddBtn() { | |||||
| faceItemActive.value = null; | |||||
| showUploadBtn.value = true; | |||||
| } | |||||
| // 上传图片 | // 上传图片 | ||||
| async function changeFile() { | async function changeFile() { | ||||
| imgUrl.value = URL.createObjectURL(imgData.value); | imgUrl.value = URL.createObjectURL(imgData.value); | ||||
| @@ -429,13 +474,21 @@ async function changeFile() { | |||||
| const timestamp = Date.now(); | const timestamp = Date.now(); | ||||
| formData.append("file", imgData.value, timestamp + ".png"); | formData.append("file", imgData.value, timestamp + ".png"); | ||||
| try { | try { | ||||
| // 上传图片 | |||||
| const res = await awsImgUpload(formData); | 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 { | } else { | ||||
| ElMessage.error("上传失败!"); | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" ? `上传失败` : `Upload failure` | |||||
| ); | |||||
| } | } | ||||
| const res2 = await saveImgApi({ material: res.data.url }); | |||||
| } catch (error) { | } catch (error) { | ||||
| ElMessage.error(error); | ElMessage.error(error); | ||||
| } | } | ||||
| @@ -503,11 +556,19 @@ async function chooseStyle() { | |||||
| const previewAudioUrl = ref(null); | const previewAudioUrl = ref(null); | ||||
| async function getPreviewAudio() { | async function getPreviewAudio() { | ||||
| if (!textareaContent.value) { | if (!textareaContent.value) { | ||||
| ElMessage.error("您还没有输入文案"); | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `您还没有输入文案` | |||||
| : `You have not entered the copy yet` | |||||
| ); | |||||
| return; | return; | ||||
| } | } | ||||
| if (!sound.value) { | if (!sound.value) { | ||||
| ElMessage.error("您还没有选择声音"); | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `您还没有选择声音` | |||||
| : `You have not selected the sound` | |||||
| ); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -565,7 +626,7 @@ const playRecording = () => { | |||||
| } | } | ||||
| }; | }; | ||||
| // 上传音频 | // 上传音频 | ||||
| async function uploadAudio() { | |||||
| async function uploadAudio(isSaveVideo) { | |||||
| createLoading.value = true; | createLoading.value = true; | ||||
| let formData = new FormData(); | let formData = new FormData(); | ||||
| const timestamp = Date.now(); | const timestamp = Date.now(); | ||||
| @@ -576,12 +637,14 @@ async function uploadAudio() { | |||||
| if (res) { | if (res) { | ||||
| // ElMessage.success("上传成功!"); | // ElMessage.success("上传成功!"); | ||||
| } else { | } else { | ||||
| ElMessage.error("音频上传失败!"); | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" ? `上传音频失败!` : `Failed to upload audio!` | |||||
| ); | |||||
| return; | return; | ||||
| } | } | ||||
| // 查询进度 | // 查询进度 | ||||
| intervalId = setInterval(() => { | intervalId = setInterval(() => { | ||||
| uploadProgress(res.data.videoId); | |||||
| uploadProgress(res.data.videoId, isSaveVideo); | |||||
| }, 1000); | }, 1000); | ||||
| // ElMessage.success("上传成功!"); | // ElMessage.success("上传成功!"); | ||||
| } catch (error) { | } catch (error) { | ||||
| @@ -604,7 +667,7 @@ const handleFileChange = async () => { | |||||
| }; | }; | ||||
| // 获取视频上传进度 | // 获取视频上传进度 | ||||
| const afterSaveAudioId = ref(null); | const afterSaveAudioId = ref(null); | ||||
| async function uploadProgress(videoId) { | |||||
| async function uploadProgress(videoId, isSaveVideo) { | |||||
| const res = await uploadProgressApi(videoId); | const res = await uploadProgressApi(videoId); | ||||
| if (res.data == "complete") { | if (res.data == "complete") { | ||||
| clearInterval(intervalId); | clearInterval(intervalId); | ||||
| @@ -625,9 +688,20 @@ async function uploadProgress(videoId) { | |||||
| }; | }; | ||||
| try { | try { | ||||
| const res3 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据 | 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 }); // 生成视频 | const res4 = await createVideoApi({ id: res3.data.id }); // 生成视频 | ||||
| if (res4.message == "success") { | if (res4.message == "success") { | ||||
| ElMessage.success("视频正在生成,请耐心等待"); | |||||
| ElMessage.success( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `视频正在生成中,请耐心等待` | |||||
| : `The video is being generated, please wait patiently` | |||||
| ); | |||||
| } | } | ||||
| createLoading.value = false; | createLoading.value = false; | ||||
| } catch (error) { | } catch (error) { | ||||
| @@ -644,7 +718,7 @@ const tabFrom = ref(1); | |||||
| const createLoading = ref(false); | const createLoading = ref(false); | ||||
| // 上传音频后,得到videoId | // 上传音频后,得到videoId | ||||
| // 保存数据 | // 保存数据 | ||||
| async function saveOrUpdate(index) { | |||||
| async function saveOrUpdate(index, isSaveVideo) { | |||||
| if (createLoading.value == true) { | if (createLoading.value == true) { | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -661,9 +735,20 @@ async function saveOrUpdate(index) { | |||||
| createLoading.value = true; | createLoading.value = true; | ||||
| try { | try { | ||||
| const res2 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据 | 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 }); // 生成视频 | const res3 = await createVideoApi({ id: res2.data.id }); // 生成视频 | ||||
| if (res3.message == "success") { | if (res3.message == "success") { | ||||
| ElMessage.success("视频正在生成,请耐心等待"); | |||||
| ElMessage.success( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `视频正在生成中,请耐心等待` | |||||
| : `The video is being generated, please wait patiently` | |||||
| ); | |||||
| } | } | ||||
| createLoading.value = false; | createLoading.value = false; | ||||
| } catch (error) { | } catch (error) { | ||||
| @@ -673,7 +758,7 @@ async function saveOrUpdate(index) { | |||||
| } | } | ||||
| if (index == 2) { | if (index == 2) { | ||||
| try { | try { | ||||
| const res1 = await uploadAudio(); // 上传音频 | |||||
| const res1 = await uploadAudio(isSaveVideo); // 上传音频 | |||||
| } catch (error) { | } catch (error) { | ||||
| ElMessage.error(error); | ElMessage.error(error); | ||||
| createLoading.value = false; | createLoading.value = false; | ||||
| @@ -768,13 +853,34 @@ onMounted(() => { | |||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| border: 1px solid #000; | 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 { | .trueImg { | ||||
| position: relative; | |||||
| top: 60px; | top: 60px; | ||||
| width: 100px; | width: 100px; | ||||
| height: 100px; | height: 100px; | ||||
| background-color: green; | |||||
| border-radius: 50%; | border-radius: 50%; | ||||
| .icon { | |||||
| position: absolute; | |||||
| top: 0%; | |||||
| right: -5%; | |||||
| border: 2px solid #00ff95; | |||||
| color: #00ff95; | |||||
| } | |||||
| } | } | ||||
| .el-upload { | .el-upload { | ||||
| position: absolute; | position: absolute; | ||||
| @@ -791,7 +897,7 @@ onMounted(() => { | |||||
| font-size: 50px; | font-size: 50px; | ||||
| line-height: 100px; | line-height: 100px; | ||||
| text-align: center; | text-align: center; | ||||
| background-color: pink; | |||||
| background-color: #ccc; | |||||
| border-radius: 50%; | border-radius: 50%; | ||||
| } | } | ||||
| @@ -800,7 +906,7 @@ onMounted(() => { | |||||
| // background-color: #795562; | // background-color: #795562; | ||||
| display: flex; | display: flex; | ||||
| justify-content: space-evenly; | justify-content: space-evenly; | ||||
| width: 500px; | |||||
| width: 700px; | |||||
| height: 100px; | height: 100px; | ||||
| > div { | > div { | ||||
| @@ -809,6 +915,13 @@ onMounted(() => { | |||||
| height: 100px; | height: 100px; | ||||
| background-color: #ccc; | background-color: #ccc; | ||||
| border-radius: 50%; | border-radius: 50%; | ||||
| .icon { | |||||
| position: absolute; | |||||
| top: 0%; | |||||
| right: -5%; | |||||
| border: 2px solid red; | |||||
| color: red; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -821,6 +934,7 @@ onMounted(() => { | |||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| opacity: 0; | opacity: 0; | ||||
| cursor: pointer; | |||||
| } | } | ||||
| .icon { | .icon { | ||||
| @@ -3,8 +3,8 @@ | |||||
| <!-- 左侧栏 --> | <!-- 左侧栏 --> | ||||
| <div class="left"> | <div class="left"> | ||||
| <!-- 顶部 --> | <!-- 顶部 --> | ||||
| <!-- 有图片时 --> | |||||
| <div class="left-top" v-show="!showUploadBtn"> | |||||
| <!-- 选中AiFace --> | |||||
| <div class="left-top" v-show="showUploadBtn == 1"> | |||||
| <el-row class="justify-between"> | <el-row class="justify-between"> | ||||
| <!-- title框 --> | <!-- title框 --> | ||||
| <div | <div | ||||
| @@ -18,24 +18,14 @@ | |||||
| /> | /> | ||||
| <el-icon class="icon-edit"><i-ep-edit /></el-icon> | <el-icon class="icon-edit"><i-ep-edit /></el-icon> | ||||
| </div> | </div> | ||||
| <!-- 上传按钮 --> | |||||
| <div class="btnBox" v-show="submitImgBtn"> | |||||
| <button class="uploadBtn"> | |||||
| {{ $t("createVideo.reselect") }} | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | |||||
| </button> | |||||
| <button class="uploadBtn" @click="changeFile"> | |||||
| {{ $t("createVideo.sureUpload") }} | |||||
| </button> | |||||
| </div> | |||||
| </el-row> | </el-row> | ||||
| <!-- 中间展示大图 --> | <!-- 中间展示大图 --> | ||||
| <div class="bigImg inmiddle"> | <div class="bigImg inmiddle"> | ||||
| <img :src="imgUrl" alt="" class="inmiddle" /> | <img :src="imgUrl" alt="" class="inmiddle" /> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 没有图片时 --> | |||||
| <div class="left-top" v-show="showUploadBtn"> | |||||
| <!-- 选中需要上传的图片前 --> | |||||
| <div class="left-top" v-show="showUploadBtn == 2"> | |||||
| <!-- 中间展示大图 --> | <!-- 中间展示大图 --> | ||||
| <div class="noImg"> | <div class="noImg"> | ||||
| <my-loading | <my-loading | ||||
| @@ -43,6 +33,9 @@ | |||||
| :isLoading="compressionImgLoad" | :isLoading="compressionImgLoad" | ||||
| ></my-loading> | ></my-loading> | ||||
| <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | ||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/trueImg.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">✔</div> | <div class="icon">✔</div> | ||||
| </div> | </div> | ||||
| <div v-if="!compressionImgLoad" class="upload inmiddle"> | <div v-if="!compressionImgLoad" class="upload inmiddle"> | ||||
| @@ -50,10 +43,84 @@ | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | <input accept="image/*" type="file" @change="lookImg" /> | ||||
| </div> | </div> | ||||
| <div v-if="!compressionImgLoad" class="falseImg inmiddle"> | <div v-if="!compressionImgLoad" class="falseImg inmiddle"> | ||||
| <div><div class="icon">×</div></div> | |||||
| <div><div class="icon">×</div></div> | |||||
| <div><div class="icon">×</div></div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false1.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false2.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false3.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- loading --> | |||||
| <div class="left-top" v-show="showUploadBtn == 3"> | |||||
| <!-- 中间展示大图 --> | |||||
| <div class="noImg"> | |||||
| <my-loading | |||||
| style="margin-top: 150px" | |||||
| :isLoading="compressionImgLoad" | |||||
| ></my-loading> | |||||
| <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/trueImg.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">✔</div> | |||||
| </div> | |||||
| <div v-if="!compressionImgLoad" class="upload inmiddle"> | |||||
| + | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | |||||
| </div> | |||||
| <div v-if="!compressionImgLoad" class="falseImg inmiddle"> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false1.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false2.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| <div> | |||||
| <div class="imgBox"> | |||||
| <img src="../../assets/img/false3.png" alt="" /> | |||||
| </div> | |||||
| <div class="icon">×</div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 选中需要上传的图片前后 --> | |||||
| <div class="left-top" v-show="showUploadBtn == 4"> | |||||
| <el-row class="justify-between"> | |||||
| <!-- 上传按钮 --> | |||||
| <div class="btnBox" v-show="submitImgBtn"> | |||||
| <button class="uploadBtn"> | |||||
| {{ $t("createVideo.reselect") }} | |||||
| <input accept="image/*" type="file" @change="lookImg" /> | |||||
| </button> | |||||
| <button class="uploadBtn" @click="changeFile"> | |||||
| {{ $t("createVideo.sureUpload") }} | |||||
| </button> | |||||
| </div> | </div> | ||||
| </el-row> | |||||
| <!-- 中间展示大图 --> | |||||
| <div class="bigImg inmiddle"> | |||||
| <img :src="imgUrl" alt="" class="inmiddle" /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -75,7 +142,8 @@ | |||||
| {{ $t("createVideo.personalWarehouse") }} | {{ $t("createVideo.personalWarehouse") }} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="faceList"> | |||||
| <!-- 系统相册 --> | |||||
| <div class="faceList" v-if="showFace == 0"> | |||||
| <!-- 上传图片组件 --> | <!-- 上传图片组件 --> | ||||
| <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | ||||
| <span class="uploadImg">+ </span> | <span class="uploadImg">+ </span> | ||||
| @@ -95,6 +163,33 @@ | |||||
| s | s | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 个人相册 --> | |||||
| <div class="faceList" v-if="showFace == 1"> | |||||
| <!-- 上传图片组件 --> | |||||
| <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn"> | |||||
| <span class="uploadImg">+ </span> | |||||
| </div> | |||||
| <my-loading :isLoading="feceItemLoading2"></my-loading> | |||||
| <!-- face列表 --> | |||||
| <div | |||||
| :class="faceItemActive == item.id ? 'faceItemActive' : ''" | |||||
| class="faceItem pointer" | |||||
| @click="setImgUrl(item.material, item.id)" | |||||
| v-for="item in userAiFaceList" | |||||
| :key="item.id" | |||||
| > | |||||
| <div class="imgBox"> | |||||
| <img :src="item.material" alt="" /> | |||||
| </div> | |||||
| <div | |||||
| v-if="faceItemActive == item.id" | |||||
| @click="deleteFaceImg(item.id)" | |||||
| class="deleteIcon" | |||||
| > | |||||
| ✖︎ | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 右侧栏 --> | <!-- 右侧栏 --> | ||||
| @@ -353,7 +448,9 @@ | |||||
| import { getCurrentInstance } from "vue"; | import { getCurrentInstance } from "vue"; | ||||
| import { | import { | ||||
| personPhotoList, | personPhotoList, | ||||
| personPhotoUserListList, | |||||
| awsImgUpload, | awsImgUpload, | ||||
| delImgApi, | |||||
| videoUpload, | videoUpload, | ||||
| saveImgApi, | saveImgApi, | ||||
| uploadProgressApi, | uploadProgressApi, | ||||
| @@ -374,7 +471,9 @@ const lanChange = ref(locale); | |||||
| //#region 头像区的逻辑 | //#region 头像区的逻辑 | ||||
| // 获取AI头像 | // 获取AI头像 | ||||
| const AiFaceList = ref([]); | const AiFaceList = ref([]); | ||||
| const userAiFaceList = ref([]); | |||||
| const feceItemLoading = ref(false); | const feceItemLoading = ref(false); | ||||
| const feceItemLoading2 = ref(false); | |||||
| function getAiFaceList(pageNum, pageSize, sendType) { | function getAiFaceList(pageNum, pageSize, sendType) { | ||||
| feceItemLoading.value = true; | feceItemLoading.value = true; | ||||
| personPhotoList(pageNum, pageSize, sendType) | personPhotoList(pageNum, pageSize, sendType) | ||||
| @@ -387,6 +486,18 @@ function getAiFaceList(pageNum, pageSize, sendType) { | |||||
| console.log(err, "err"); | 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列表 | // 选择显示的face列表 | ||||
| const showFace = ref("0"); | const showFace = ref("0"); | ||||
| function ChangeShowFaceList(index) { | function ChangeShowFaceList(index) { | ||||
| @@ -395,7 +506,7 @@ function ChangeShowFaceList(index) { | |||||
| getAiFaceList(1, 100, 1); | getAiFaceList(1, 100, 1); | ||||
| } | } | ||||
| if (index == 1) { | if (index == 1) { | ||||
| getAiFaceList(1, 100, 3); | |||||
| getAiFaceUserList(1, 100, 3); | |||||
| } | } | ||||
| showFace.value = index; | showFace.value = index; | ||||
| } | } | ||||
| @@ -403,10 +514,32 @@ const faceItemActive = ref(); //高亮处理和当前选择图片的ID | |||||
| // 点击aifece | // 点击aifece | ||||
| function setImgUrl(url, id) { | function setImgUrl(url, id) { | ||||
| faceItemActive.value = id; | faceItemActive.value = id; | ||||
| showUploadBtn.value = false; | |||||
| showUploadBtn.value = 1; | |||||
| submitImgBtn.value = false; | submitImgBtn.value = false; | ||||
| imgUrl.value = url; | 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 ------------------------------ | //#endregion ------------------------------ | ||||
| //#region 预览图片 | //#region 预览图片 | ||||
| @@ -416,7 +549,7 @@ async function lookImg(e) { | |||||
| faceItemActive.value = null; | faceItemActive.value = null; | ||||
| imgUrl.value = null; | imgUrl.value = null; | ||||
| imgData.value = null; | imgData.value = null; | ||||
| showUploadBtn.value = true; | |||||
| showUploadBtn.value = 3; | |||||
| submitImgBtn.value = false; | submitImgBtn.value = false; | ||||
| compressionImgLoad.value = true; | compressionImgLoad.value = true; | ||||
| // 压缩配置 | // 压缩配置 | ||||
| @@ -427,7 +560,7 @@ async function lookImg(e) { | |||||
| const compressedFile = await imageCompression(e.target.files[0], options); | const compressedFile = await imageCompression(e.target.files[0], options); | ||||
| imgUrl.value = URL.createObjectURL(compressedFile); | imgUrl.value = URL.createObjectURL(compressedFile); | ||||
| imgData.value = compressedFile; | imgData.value = compressedFile; | ||||
| showUploadBtn.value = false; | |||||
| showUploadBtn.value = 4; | |||||
| submitImgBtn.value = true; | submitImgBtn.value = true; | ||||
| compressionImgLoad.value = false; | compressionImgLoad.value = false; | ||||
| } else { | } else { | ||||
| @@ -442,15 +575,17 @@ const title = ref(""); | |||||
| //#region 上传图片 | //#region 上传图片 | ||||
| const imgUrl = ref(""); //图片回显路径 | const imgUrl = ref(""); //图片回显路径 | ||||
| const imgData = ref(""); // 上传图片文件 | const imgData = ref(""); // 上传图片文件 | ||||
| const showUploadBtn = ref(false); //上传图片+号的显示隐藏 | |||||
| const showUploadBtn = ref(1); //上传图片+号的显示隐藏 | |||||
| const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 | const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 | ||||
| // 点击AI头像区的+号 | // 点击AI头像区的+号 | ||||
| function clickAddBtn() { | function clickAddBtn() { | ||||
| faceItemActive.value = null; | faceItemActive.value = null; | ||||
| showUploadBtn.value = true; | |||||
| showUploadBtn.value = 2; | |||||
| } | } | ||||
| // 上传图片 | // 上传图片 | ||||
| async function changeFile() { | async function changeFile() { | ||||
| compressionImgLoad.value = true; | |||||
| showUploadBtn.value = 3; | |||||
| imgUrl.value = URL.createObjectURL(imgData.value); | imgUrl.value = URL.createObjectURL(imgData.value); | ||||
| let formData = new FormData(); | let formData = new FormData(); | ||||
| const timestamp = Date.now(); | const timestamp = Date.now(); | ||||
| @@ -461,7 +596,9 @@ async function changeFile() { | |||||
| // 保存图片 | // 保存图片 | ||||
| const res2 = await saveImgApi({ material: res.data.url }); | 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) { | if (res2.code == 200) { | ||||
| ElMessage.success( | ElMessage.success( | ||||
| lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully` | lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully` | ||||
| @@ -661,6 +798,7 @@ async function uploadProgress(videoId, isSaveVideo) { | |||||
| } | } | ||||
| // 定义参数 | // 定义参数 | ||||
| const saveOrUpdateData = { | const saveOrUpdateData = { | ||||
| title: title.value, | |||||
| personPhotoId: faceItemActive.value, //任务照片id, | personPhotoId: faceItemActive.value, //任务照片id, | ||||
| voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 | voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 | ||||
| paperwork: textareaContent.value, //文案 | paperwork: textareaContent.value, //文案 | ||||
| @@ -706,6 +844,7 @@ async function saveOrUpdate(index, isSaveVideo) { | |||||
| } | } | ||||
| tabFrom.value = index; | tabFrom.value = index; | ||||
| const saveOrUpdateData = { | const saveOrUpdateData = { | ||||
| title: title.value, | |||||
| personPhotoId: faceItemActive.value, //任务照片id, | personPhotoId: faceItemActive.value, //任务照片id, | ||||
| voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 | voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传 | ||||
| paperwork: textareaContent.value, //文案 | paperwork: textareaContent.value, //文案 | ||||
| @@ -765,6 +904,7 @@ const t = globalProperties.$t(string); | |||||
| onMounted(() => { | onMounted(() => { | ||||
| getAiFaceList(1, 100, 1); | getAiFaceList(1, 100, 1); | ||||
| getAiFaceUserList(1, 100, 3); | |||||
| voiceTotal(); | voiceTotal(); | ||||
| chooseType(); | chooseType(); | ||||
| }); | }); | ||||
| @@ -835,13 +975,34 @@ onMounted(() => { | |||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| border: 1px solid #000; | 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 { | .trueImg { | ||||
| position: relative; | |||||
| top: 60px; | top: 60px; | ||||
| width: 100px; | width: 100px; | ||||
| height: 100px; | height: 100px; | ||||
| background-color: green; | |||||
| border-radius: 50%; | border-radius: 50%; | ||||
| .icon { | |||||
| position: absolute; | |||||
| top: 0%; | |||||
| right: -5%; | |||||
| border: 2px solid #00ff95; | |||||
| color: #00ff95; | |||||
| } | |||||
| } | } | ||||
| .el-upload { | .el-upload { | ||||
| position: absolute; | position: absolute; | ||||
| @@ -858,7 +1019,7 @@ onMounted(() => { | |||||
| font-size: 50px; | font-size: 50px; | ||||
| line-height: 100px; | line-height: 100px; | ||||
| text-align: center; | text-align: center; | ||||
| background-color: pink; | |||||
| background-color: #ccc; | |||||
| border-radius: 50%; | border-radius: 50%; | ||||
| } | } | ||||
| @@ -867,7 +1028,7 @@ onMounted(() => { | |||||
| // background-color: #795562; | // background-color: #795562; | ||||
| display: flex; | display: flex; | ||||
| justify-content: space-evenly; | justify-content: space-evenly; | ||||
| width: 500px; | |||||
| width: 700px; | |||||
| height: 100px; | height: 100px; | ||||
| > div { | > div { | ||||
| @@ -876,6 +1037,13 @@ onMounted(() => { | |||||
| height: 100px; | height: 100px; | ||||
| background-color: #ccc; | background-color: #ccc; | ||||
| border-radius: 50%; | border-radius: 50%; | ||||
| .icon { | |||||
| position: absolute; | |||||
| top: 0%; | |||||
| right: -5%; | |||||
| border: 2px solid red; | |||||
| color: red; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -888,6 +1056,7 @@ onMounted(() => { | |||||
| width: 100%; | width: 100%; | ||||
| height: 100%; | height: 100%; | ||||
| opacity: 0; | opacity: 0; | ||||
| cursor: pointer; | |||||
| } | } | ||||
| .icon { | .icon { | ||||
| @@ -973,6 +1142,20 @@ onMounted(() => { | |||||
| width: 100%; | 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 { | .uploadImg { | ||||
| line-height: 145px; | line-height: 145px; | ||||
| font-size: 50px; | font-size: 50px; | ||||
| @@ -68,12 +68,17 @@ | |||||
| /></el-icon> | /></el-icon> | ||||
| <div class="showBtn" @click.stop="mouseenter(item)">...</div> | <div class="showBtn" @click.stop="mouseenter(item)">...</div> | ||||
| <div class="btns" v-show="showPopup"> | <div class="btns" v-show="showPopup"> | ||||
| <div class="btns-item" @click.stop="handleDownload(item.id)"> | |||||
| <!-- 下载按钮 --> | |||||
| <div | |||||
| class="btns-item" | |||||
| @click.stop="handleDownload(item.videoPlayUrl)" | |||||
| > | |||||
| <div class="btns-item-icon"> | <div class="btns-item-icon"> | ||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon> | <el-icon class="icon-delete"><i-ep-download /></el-icon> | ||||
| </div> | </div> | ||||
| <div class="text">{{ $t("myCreating.download") }}</div> | <div class="text">{{ $t("myCreating.download") }}</div> | ||||
| </div> | </div> | ||||
| <!-- 删除按钮 --> | |||||
| <div | <div | ||||
| class="btns-item" | class="btns-item" | ||||
| @click.stop="handelDelete(item.id, item.title)" | @click.stop="handelDelete(item.id, item.title)" | ||||
| @@ -134,16 +139,19 @@ | |||||
| }}</span> | }}</span> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 有视频路径的页脚 --> | |||||
| <template #footer v-if="presentItem.videoPlayUrl"> | <template #footer v-if="presentItem.videoPlayUrl"> | ||||
| <span class="dialog-footer"> | <span class="dialog-footer"> | ||||
| <!-- dialog下载按钮 --> | |||||
| <button | <button | ||||
| class="elBtn" | class="elBtn" | ||||
| type="primary" | type="primary" | ||||
| @click.stop="handleDownload(presentItem.id)" | |||||
| @click.stop="handleDownload(presentItem.videoPlayUrl)" | |||||
| > | > | ||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon | <el-icon class="icon-delete"><i-ep-download /></el-icon | ||||
| >{{ $t("myCreating.download") }} | >{{ $t("myCreating.download") }} | ||||
| </button> | </button> | ||||
| <!-- dialog删除按钮 --> | |||||
| <button | <button | ||||
| class="elBtn" | class="elBtn" | ||||
| @click.stop="handelDelete(presentItem.id, presentItem.title)" | @click.stop="handelDelete(presentItem.id, presentItem.title)" | ||||
| @@ -153,6 +161,15 @@ | |||||
| </button> | </button> | ||||
| </span> | </span> | ||||
| </template> | </template> | ||||
| <!-- 无视频路径的页脚 --> | |||||
| <template #footer v-if="!presentItem.videoPlayUrl"> | |||||
| <span class="dialog-footer"> | |||||
| <!-- dialog编辑按钮 --> | |||||
| <button class="elBtn" type="primary" @click.stop=""> | |||||
| {{ $t("myCreating.edit") }} | |||||
| </button> | |||||
| </span> | |||||
| </template> | |||||
| </el-dialog> | </el-dialog> | ||||
| <div v-if="!isLoading" class="pagination"> | <div v-if="!isLoading" class="pagination"> | ||||
| @@ -171,6 +188,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| <script setup> | <script setup> | ||||
| import { userPhotoVideoList, delUserPhotoVideoByID } from "@/apis/myCreating"; | import { userPhotoVideoList, delUserPhotoVideoByID } from "@/apis/myCreating"; | ||||
| import { timestampToTime } from "@/utils/tools"; | import { timestampToTime } from "@/utils/tools"; | ||||
| @@ -221,8 +239,20 @@ function mouseenter(item) { | |||||
| presentItem.value = item; | presentItem.value = item; | ||||
| showPopup.value = !showPopup.value; | showPopup.value = !showPopup.value; | ||||
| } | } | ||||
| function handleDownload() {} | |||||
| // 下载 | |||||
| function handleDownload(itemVideoPlayUrl) { | |||||
| if (itemVideoPlayUrl) { | |||||
| const link = document.createElement("a"); | |||||
| link.href = itemVideoPlayUrl; | |||||
| document.body.appendChild(link); | |||||
| link.click(); | |||||
| document.body.removeChild(link); | |||||
| } else { | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" ? `无法下载` : `Unable to download` | |||||
| ); | |||||
| } | |||||
| } | |||||
| function goCreate() { | function goCreate() { | ||||
| router.push("/createVideo"); | router.push("/createVideo"); | ||||
| @@ -300,6 +330,7 @@ function delPhotoVideo(videoID) { | |||||
| console.log(res, "res"); | console.log(res, "res"); | ||||
| const msg = lanChange.value == "zh-cn" ? `删除成功!` : `Success !`; | const msg = lanChange.value == "zh-cn" ? `删除成功!` : `Success !`; | ||||
| ElMessage.success(msg); | ElMessage.success(msg); | ||||
| showDialog.value = false; | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value); | getPhotoVideoList(pageNum.value, pageSize.value, title.value); | ||||
| }) | }) | ||||
| .catch((err) => { | .catch((err) => { | ||||
| @@ -316,8 +347,8 @@ onMounted(() => { | |||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| .page { | .page { | ||||
| height: 1200px; | |||||
| padding: 50px 130px; | |||||
| min-height: calc(100vh - 80px); | |||||
| padding: 20px 130px; | |||||
| background-color: #fff; | background-color: #fff; | ||||
| border-radius: 25px 0 0; | border-radius: 25px 0 0; | ||||
| .top { | .top { | ||||
| @@ -338,8 +369,9 @@ onMounted(() => { | |||||
| flex-wrap: wrap; | flex-wrap: wrap; | ||||
| justify-content: flex-start; | justify-content: flex-start; | ||||
| width: 100%; | width: 100%; | ||||
| height: 200px; | |||||
| // height: 200px; | |||||
| margin-top: 20px; | margin-top: 20px; | ||||
| padding-bottom: 50px; | |||||
| cursor: pointer; | cursor: pointer; | ||||
| .workItem { | .workItem { | ||||
| position: relative; | position: relative; | ||||
| @@ -356,6 +388,7 @@ onMounted(() => { | |||||
| height: 170px; | height: 170px; | ||||
| cursor: pointer; | cursor: pointer; | ||||
| padding: 10px; | padding: 10px; | ||||
| overflow: hidden; | |||||
| .coverImg { | .coverImg { | ||||
| max-width: 90%; | max-width: 90%; | ||||
| max-height: 170px; | max-height: 170px; | ||||
| @@ -541,7 +574,7 @@ onMounted(() => { | |||||
| } | } | ||||
| .pagination { | .pagination { | ||||
| position: fixed; | position: fixed; | ||||
| bottom: 50px; | |||||
| bottom: 20px; | |||||
| left: 50%; | left: 50%; | ||||
| transform: translateX(-50%); | transform: translateX(-50%); | ||||
| background-color: #ffffff; | background-color: #ffffff; | ||||
| @@ -583,7 +616,8 @@ onMounted(() => { | |||||
| padding: 10px 40px 30px 40px; | padding: 10px 40px 30px 40px; | ||||
| video { | video { | ||||
| width: 100%; | |||||
| max-width: 100%; | |||||
| max-height: 600px; | |||||
| margin: auto; | margin: auto; | ||||
| } | } | ||||
| .insteadVideo { | .insteadVideo { | ||||