@@ -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 { | ||||