|
- <template>
- <div class="page flex justify-around">
- <!-- 左侧栏 -->
- <div class="left">
- <!-- 顶部 -->
- <!-- 有图片时 -->
- <div class="left-top" v-show="!showUploadBtn">
- <el-row class="justify-between">
- <!-- title框 -->
- <div
- v-show="!submitImgBtn"
- class="flex justify-between"
- style="width: 300px"
- >
- <el-input
- v-model="title"
- :placeholder="$t('createVideo.typeTitle')"
- />
- <el-icon class="icon-edit"><i-ep-edit /></el-icon>
- </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>
- <!-- 中间展示大图 -->
- <div class="bigImg inmiddle">
- <img :src="imgUrl" alt="" class="inmiddle" />
- </div>
- </div>
- <!-- 没有图片时 -->
- <div class="left-top" v-show="showUploadBtn">
- <!-- 中间展示大图 -->
- <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-bottom">
- <div class="tab flex">
- <div
- class="pointer"
- :class="showFace == 0 ? 'tabAvtive' : ''"
- @click="ChangeShowFaceList(0)"
- >
- {{ $t("createVideo.availableMould") }}
- </div>
- <div
- class="pointer"
- :class="showFace == 1 ? 'tabAvtive' : ''"
- @click="ChangeShowFaceList(1)"
- >
- {{ $t("createVideo.personalWarehouse") }}
- </div>
- </div>
- <div class="faceList">
- <!-- 上传图片组件 -->
- <div v-if="showFace == 1" class="faceItem" @click="clickAddBtn">
- <span class="uploadImg">+ </span>
- </div>
- <my-loading :isLoading="feceItemLoading"></my-loading>
- <!-- face列表 -->
- <div
- :class="faceItemActive == item.id ? 'faceItemActive' : ''"
- class="faceItem pointer"
- @click="setImgUrl(item.material, item.id)"
- v-for="item in AiFaceList"
- :key="item.id"
- >
- <div class="imgBox">
- <img :src="item.material" alt="" />
- </div>
- s
- </div>
- </div>
- </div>
- </div>
- <!-- 右侧栏 -->
- <div class="right">
- <el-tabs type="border-card" class="tabs">
- <!-- ----------------------------- 1 -->
- <el-tab-pane :label="$t('createVideo.typeScript')">
- <div class="card1">
- <div class="text">
- <!-- 文本域 -->
- <el-input
- id="textInputId"
- v-model="textareaContent"
- :rows="15"
- type="textarea"
- :placeholder="$t('createVideo.aiText')"
- />
- <span
- class="pointer"
- @click="getPreviewAudio"
- style="margin-right: 10px; font-size: 30px"
- >🕬</span
- >
- <span class="pointer" @click="insertIcon">🕗</span>
- </div>
- <p>{{ $t("createVideo.languages") }}</p>
- <!-- 语言 -->
- <el-select
- @change="chooseType"
- v-model="language"
- :placeholder="$t('createVideo.select')"
- style="width: 100%"
- >
- <el-option
- v-for="item in languageOptions"
- :key="item.value"
- :label="item.name"
- :value="item.id"
- >
- <img
- :src="item.img"
- alt=""
- style="
- width: 20px;
- margin-right: 10px;
- vertical-align: text-top;
- "
- />
- <span style="line-height: 20px">{{ item.name }}</span>
- </el-option>
- </el-select>
- <p>{{ $t("createVideo.voices") }}</p>
- <!-- 声音 -->
- <el-select
- @change="chooseStyle"
- :disabled="language ? false : true"
- v-model="sound"
- :placeholder="$t('createVideo.select')"
- style="width: 100%"
- >
- <el-option
- v-for="item in soundOptions"
- :key="item.value"
- :label="item.displayName"
- :value="item.id"
- />
- </el-select>
- <p>{{ $t("createVideo.styles") }}</p>
- <!-- 风格 -->
- <el-select
- :disabled="soundStyleOptions ? false : true"
- v-model="soundStyle"
- :placeholder="$t('createVideo.select')"
- style="width: 100%"
- >
- <el-option
- v-for="item in soundStyleOptions"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- <!-- 生成视频 -->
- <el-button @click="saveOrUpdate(1)" color="#000" type="primary">
- <my-loading :isLoading="createLoading"></my-loading>
- <span v-if="!createLoading">{{
- $t("createVideo.generateVideo")
- }}</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>
- </el-tab-pane>
- <!-- ------------------------ 2 -->
- <el-tab-pane :label="$t('createVideo.uploadAudio')">
- <div class="card2">
- <!-- 上传视频 -->
- <p>
- <el-icon class="icon-VideoCamera"><i-ep-VideoCamera /></el-icon>
- {{ $t("createVideo.uploadAudio") }}
- </p>
- <div class="uploadVideo">
- +
- <input
- accept="audio/*"
- type="file"
- ref="fileInput"
- @click="e.target.value = null"
- @change="handleFileChange"
- />
- <!-- <video
- style="position: absolute; top: 0"
- v-if="videoSrc"
- :src="videoSrc"
- ref="videoPlayer"
- controls
- ></video> -->
- </div>
- <!-- 录制MP3上传语音 -->
- <p>
- <el-icon class="icon-Mic"><i-ep-Mic /></el-icon>
- {{ $t("createVideo.recordedAudio") }}
- </p>
- <div
- class="uploadAudio"
- :class="audioUrl ? 'uploadAudioAvtion' : ''"
- >
- <div class="btnBox">
- <button
- class="pointer"
- :disabled="!isRecording"
- @click="startRecording"
- >
- {{ $t("createVideo.startRecorded") }}
- </button>
- <button
- class="pointer"
- @click="stopRecording"
- :disabled="isRecording"
- >
- {{ $t("createVideo.stopRecorded") }}
- </button>
- </div>
- <!-- <button @click="playRecording">播放录音</button> -->
- <audio v-if="audioUrl" controls :src="audioUrl"></audio>
- <!-- <button v-if="audioUrl" @click="uploadAudio" class="pointer">
- 上传音频
- </button> -->
- </div>
- <!-- 生成视频 -->
- <el-button @click="saveOrUpdate(2)" color="#000" type="primary">
- <my-loading :isLoading="createLoading"></my-loading>
- <span v-if="!createLoading">{{
- $t("createVideo.generateVideo")
- }}</span>
- </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>
- </el-tab-pane>
- <!-- ----------------------- 3 -->
- <el-tab-pane v-if="false" :label="$t('createVideo.aiScript')">
- <div class="card3">
- <div class="text">
- <el-input
- v-model="title"
- :placeholder="$t('createVideo.typeTitle')"
- />
- <el-button type="primary">
- {{ $t("createVideo.confirm") }}
- </el-button>
- <el-input
- v-model="title"
- :rows="15"
- type="textarea"
- :placeholder="$t('createVideo.aiText')"
- />
- <el-icon :size="20">
- <Edit />
- </el-icon>
- </div>
- <p>{{ $t("createVideo.languages") }}</p>
- <el-select
- v-model="language"
- placeholder="Select"
- style="width: 100%"
- >
- <el-option
- v-for="item in languageOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- <p>{{ $t("createVideo.voices") }}</p>
- <el-select
- v-model="language"
- placeholder="Select"
- style="width: 100%"
- >
- <el-option
- v-for="item in languageOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- <p>{{ $t("createVideo.styles") }}</p>
- <el-select
- v-model="language"
- placeholder="Select"
- style="width: 100%"
- >
- <el-option
- v-for="item in languageOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- <el-button type="primary">{{
- $t("createVideo.generateVideo")
- }}</el-button>
- </div>
- </el-tab-pane>
- </el-tabs>
- </div>
- <!-- 试听的mp3 -->
- <div style="opacity: 0; width: 0">
- <audio autoplay :src="previewAudioUrl"></audio>
- </div>
- </div>
- </template>
-
- <script setup>
- import { getCurrentInstance } from "vue";
- import {
- personPhotoList,
- awsImgUpload,
- videoUpload,
- saveImgApi,
- uploadProgressApi,
- saveAudioApi,
- voiceTotalApi,
- chooseTypeApi,
- saveOrUpdateApi,
- createVideoApi,
- previewAudioApi,
- } from "@/apis/createVideo";
- import { useI18n } from "vue-i18n";
- import Recorder from "js-audio-recorder"; //mp3插件
- import imageCompression from "browser-image-compression"; //压缩图片插件
-
- const { locale } = useI18n();
- const lanChange = ref(locale);
-
- //#region 头像区的逻辑
- // 获取AI头像
- const AiFaceList = ref([]);
- const feceItemLoading = ref(false);
- function getAiFaceList(pageNum, pageSize, sendType) {
- feceItemLoading.value = true;
- personPhotoList(pageNum, pageSize, sendType)
- .then((res) => {
- AiFaceList.value = res.data.list;
- feceItemLoading.value = false;
- })
- .catch((err) => {
- feceItemLoading.value = false;
- console.log(err, "err");
- });
- }
- // 选择显示的face列表
- const showFace = ref("0");
- function ChangeShowFaceList(index) {
- AiFaceList.value = null;
- if (index == 0) {
- getAiFaceList(1, 100, 1);
- }
- if (index == 1) {
- getAiFaceList(1, 100, 3);
- }
- showFace.value = index;
- }
- const faceItemActive = ref(); //高亮处理和当前选择图片的ID
- // 点击aifece
- function setImgUrl(url, id) {
- faceItemActive.value = id;
- showUploadBtn.value = false;
- submitImgBtn.value = false;
- imgUrl.value = url;
- }
- //#endregion ------------------------------
-
- //#region 预览图片
- const compressionImgLoad = ref(false);
- async function lookImg(e) {
- 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 ------------------
-
- // 标题
- const title = ref("");
-
- //#region 上传图片
- const imgUrl = ref(""); //图片回显路径
- const imgData = ref(""); // 上传图片文件
- const showUploadBtn = ref(false); //上传图片+号的显示隐藏
- const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏
- // 点击AI头像区的+号
- function clickAddBtn() {
- faceItemActive.value = null;
- showUploadBtn.value = true;
- }
- // 上传图片
- async function changeFile() {
- imgUrl.value = URL.createObjectURL(imgData.value);
- let formData = new FormData();
- const timestamp = Date.now();
- formData.append("file", imgData.value, timestamp + ".png");
- try {
- // 上传图片
- const res = await awsImgUpload(formData);
- // 保存图片
- const res2 = await saveImgApi({ material: res.data.url });
- // 重新获取列表
- getAiFaceList(1, 100, 1);
- if (res2.code == 200) {
- ElMessage.success(
- lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully`
- );
- } else {
- ElMessage.error(
- lanChange.value == "zh-cn" ? `上传失败` : `Upload failure`
- );
- }
- } catch (error) {
- ElMessage.error(error);
- }
- }
- //#endregion ---------------------------
-
- //#region card1的逻辑
- const textareaContent = ref("");
- function insertIcon() {
- const textarea = document.getElementById("textInputId");
- const icon = "🕗"; // 这里使用了一个星星作为示例图标,你可以替换为你自己的图标
-
- // 获取光标位置
- const startPos = textarea.selectionStart;
- const endPos = textarea.selectionEnd;
-
- console.log(startPos);
- console.log(endPos);
- // 在光标位置插入图标
- textareaContent.value =
- textareaContent.value.substring(0, startPos) +
- icon +
- textareaContent.value.substring(endPos, textareaContent.value.length);
-
- // 设置光标位置为插入图标后的位置
- const newCursorPos = startPos + icon.length;
- textarea.setSelectionRange(newCursorPos, newCursorPos);
- textarea.focus();
- }
- const language = ref(""); //选择的语言
- const sound = ref(""); // 选择的声音
- const soundStyle = ref(""); //选择的风格
- // 语言下拉框内容
- const languageOptions = ref([
- {
- id: "0",
- name: "中文",
- },
- {
- id: "1",
- name: "English",
- },
- ]);
- async function voiceTotal() {
- const res = await voiceTotalApi();
- languageOptions.value = res.data;
- }
- // 声音下拉框内容
- const soundOptions = ref([]);
- async function chooseType() {
- const res = await chooseTypeApi(language.value);
- soundOptions.value = res.data;
- sound.value = null;
- }
- // 风格下拉框内容
- const soundStyleOptions = ref(null);
- async function chooseStyle() {
- const item = soundOptions.value.find((element) => element.id == sound.value);
-
- soundStyle.value = null;
- soundStyleOptions.value = item.style;
- }
-
- // 试听
- const previewAudioUrl = ref(null);
- async function getPreviewAudio() {
- if (!textareaContent.value) {
- ElMessage.error(
- lanChange.value == "zh-cn"
- ? `您还没有输入文案`
- : `You have not entered the copy yet`
- );
- return;
- }
- if (!sound.value) {
- ElMessage.error(
- lanChange.value == "zh-cn"
- ? `您还没有选择声音`
- : `You have not selected the sound`
- );
- return;
- }
-
- try {
- const res = await previewAudioApi(
- textareaContent.value,
- sound.value,
- soundStyle.value
- );
- previewAudioUrl.value = res.data.data;
- console.log(previewAudioUrl.value);
- } catch (error) {
- ElMessage.error(error);
- }
- }
- //#endregion
-
- //#region 录制MP3上传语音
- const parameter = {
- sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
- sampleRate: 8000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
- numChannels: 1, // 声道,支持 1 或 2, 默认是1
- };
- const recorder = new Recorder(parameter);
- const isRecording = ref(true);
- const audioUrl = ref(null); // audio控件的url
- const audioData = ref("");
- const videoId = ref(null); //上传mp3的videoId,创建视频会用到
-
- const startRecording = async () => {
- try {
- await recorder.start();
- console.log("Recording started");
- isRecording.value = false;
- } catch (error) {
- console.error(error);
- }
- };
-
- const stopRecording = async () => {
- try {
- const recording = await recorder.stop();
- audioUrl.value = URL.createObjectURL(recorder.getWAVBlob());
- audioData.value = recorder.getWAVBlob();
- isRecording.value = true;
- } catch (error) {
- console.error(error);
- }
- };
-
- const playRecording = () => {
- if (audioUrl.value) {
- const audio = new Audio(audioUrl.value);
- audio.play();
- }
- };
- // 上传音频
- async function uploadAudio(isSaveVideo) {
- createLoading.value = true;
- let formData = new FormData();
- const timestamp = Date.now();
- formData.append("file", audioData.value, timestamp + ".mp3");
- try {
- const res = await videoUpload(formData);
- videoId.value = res.data.videoId;
- if (res) {
- // ElMessage.success("上传成功!");
- } else {
- ElMessage.error(
- lanChange.value == "zh-cn" ? `上传音频失败!` : `Failed to upload audio!`
- );
- return;
- }
- // 查询进度
- intervalId = setInterval(() => {
- uploadProgress(res.data.videoId, isSaveVideo);
- }, 1000);
- // ElMessage.success("上传成功!");
- } catch (error) {
- ElMessage.error(error);
- }
- }
- //#endregion ------------------------------------
-
- //#region 上传音频功能
- const fileInput = ref(null);
-
- let intervalId = null; // 用于存储 setInterval 的返回值
- const handleFileChange = async () => {
- const file = fileInput.value.files[0];
- if (file) {
- const videoUrl = URL.createObjectURL(file);
- audioUrl.value = videoUrl;
- audioData.value = file;
- }
- };
- // 获取视频上传进度
- const afterSaveAudioId = ref(null);
- async function uploadProgress(videoId, isSaveVideo) {
- const res = await uploadProgressApi(videoId);
- if (res.data == "complete") {
- clearInterval(intervalId);
- try {
- const res2 = await saveAudioApi({ videoId: videoId });
- afterSaveAudioId.value = res2.data.id; // 得到id
- } catch (error) {
- ElMessage.error(error);
- }
- // 定义参数
- const saveOrUpdateData = {
- personPhotoId: faceItemActive.value, //任务照片id,
- voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传
- paperwork: textareaContent.value, //文案
- speakTypeStr: soundStyle.value, //声音风格
- voiceMouldId: sound.value, //选择声音id voiceFrom=1 时必传
- voiceMaterialId: afterSaveAudioId.value, //上传音频且保存音频后得到的id voiceFrom=2 时必传
- };
- try {
- const res3 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据
- if (isSaveVideo == "saveVideo") {
- ElMessage.success(
- lanChange.value == "zh-cn" ? `已保存为草稿` : `Saved as manuscript`
- );
- createLoading.value = false;
- return;
- }
- const res4 = await createVideoApi({ id: res3.data.id }); // 生成视频
- if (res4.message == "success") {
- ElMessage.success(
- lanChange.value == "zh-cn"
- ? `视频正在生成中,请耐心等待`
- : `The video is being generated, please wait patiently`
- );
- }
- createLoading.value = false;
- } catch (error) {
- ElMessage.error(error);
- createLoading.value = false;
- }
- }
- }
- //#endregion --------------------------------------
-
- //#region 生成视频
- // tab栏切换
- const tabFrom = ref(1);
- const createLoading = ref(false);
- // 上传音频后,得到videoId
- // 保存数据
- async function saveOrUpdate(index, isSaveVideo) {
- if (createLoading.value == true) {
- return;
- }
- tabFrom.value = index;
- const saveOrUpdateData = {
- personPhotoId: faceItemActive.value, //任务照片id,
- voiceFrom: tabFrom.value, //:声音来源 1:来自选择模板,2:来自用户上传
- paperwork: textareaContent.value, //文案
- speakTypeStr: soundStyle.value, //声音风格
- voiceMouldId: sound.value, //选择声音id voiceFrom=1 时必传
- voiceMaterialId: afterSaveAudioId.value, //上传音频且保存音频后得到的id voiceFrom=2 时必传
- };
- if (index == 1) {
- createLoading.value = true;
- try {
- const res2 = await saveOrUpdateApi(saveOrUpdateData); // 保存数据
- if (isSaveVideo == "saveVideo") {
- ElMessage.success(
- lanChange.value == "zh-cn" ? `已保存为草稿` : `Saved as manuscript`
- );
- createLoading.value = false;
- return;
- }
- const res3 = await createVideoApi({ id: res2.data.id }); // 生成视频
- if (res3.message == "success") {
- ElMessage.success(
- lanChange.value == "zh-cn"
- ? `视频正在生成中,请耐心等待`
- : `The video is being generated, please wait patiently`
- );
- }
- createLoading.value = false;
- } catch (error) {
- ElMessage.error(error);
- createLoading.value = false;
- }
- }
- if (index == 2) {
- try {
- const res1 = await uploadAudio(isSaveVideo); // 上传音频
- } catch (error) {
- ElMessage.error(error);
- createLoading.value = false;
- }
- }
- }
- //#endregion ----------------------------
-
- //#region
-
- //#endregion ----------------------------
-
- // $t在script中的使用
- const {
- appContext: {
- config: { globalProperties },
- },
- } = getCurrentInstance();
-
- const string = "createVideo.typeScript";
- const t = globalProperties.$t(string);
-
- onMounted(() => {
- getAiFaceList(1, 100, 1);
- voiceTotal();
- chooseType();
- });
- </script>
-
- <style lang="scss" scoped>
- .page {
- // height: 1200px;
- height: calc(100vh - 80px);
- padding: 20px 0 0 40px;
- background-color: #fff;
- border-radius: 25px 0 0;
- }
-
- .left {
- width: 70%;
- height: 80%;
-
- :deep(.el-input__wrapper) {
- border: none;
- border-bottom: 2px solid #000;
- border-radius: 0;
- box-shadow: none;
- }
-
- .el-icon.icon-edit {
- width: 35px;
- height: 35px;
- font-size: 35px;
- color: #8c939d;
- text-align: center;
- }
-
- &-top {
- position: relative;
- width: 100%;
- // height: 65%;
- height: 580px;
-
- .uploadBtn {
- position: relative;
- padding: 5px 10px;
- margin-left: 10px;
- border-radius: 5px;
- transition: all 0.3s;
- &:hover {
- background-color: #000;
- color: #fff;
- }
- }
-
- .bigImg {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 80%;
- height: 88%;
- margin-top: 20px;
-
- img {
- max-width: 100%;
- max-height: 100%;
- }
- }
-
- .noImg {
- position: relative;
- width: 100%;
- height: 100%;
- border: 1px solid #000;
- .imgBox {
- position: relative;
- width: 100%;
- height: 100%;
- border-radius: 50%;
- overflow: hidden;
- border: 1px solid #ccc;
- img {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- max-width: 120%;
- }
- }
- .trueImg {
- position: relative;
- top: 60px;
- width: 100px;
- height: 100px;
- border-radius: 50%;
- .icon {
- position: absolute;
- top: 0%;
- right: -5%;
- border: 2px solid #00ff95;
- color: #00ff95;
- }
- }
- .el-upload {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- }
- .upload {
- top: 200px;
- width: 100px;
- height: 100px;
- font-size: 50px;
- line-height: 100px;
- text-align: center;
- background-color: #ccc;
- border-radius: 50%;
- }
-
- .falseImg {
- top: 350px;
- // background-color: #795562;
- display: flex;
- justify-content: space-evenly;
- width: 700px;
- height: 100px;
-
- > div {
- position: relative;
- width: 100px;
- height: 100px;
- background-color: #ccc;
- border-radius: 50%;
- .icon {
- position: absolute;
- top: 0%;
- right: -5%;
- border: 2px solid red;
- color: red;
- }
- }
- }
- }
-
- // 公共类名
- input {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- cursor: pointer;
- }
-
- .icon {
- position: absolute;
- right: 2px;
- width: 30px;
- height: 30px;
- font-size: 20px;
- font-weight: 700;
- line-height: 26px;
- text-align: center;
- border: 2px solid #000;
- border-radius: 50%;
- }
- }
-
- &-bottom {
- width: 100%;
- height: 32%;
- margin-top: 10px;
- .tab {
- padding: 10px;
- > div {
- margin-right: 20px;
- padding: 5px 10px;
- transition: all 0.3s;
- border-radius: 5px;
- &:hover {
- background-color: #000;
- color: #fff;
- }
- }
- .tabAvtive {
- background-color: #000;
- color: #fff;
- }
- }
- .ai {
- width: 100%;
- }
-
- .faceList {
- padding: 8px;
- display: flex;
- flex-wrap: wrap;
- justify-content: flex-start;
- width: 100%;
- height: 180px;
- overflow-y: scroll;
- .faceItem {
- position: relative;
- margin-right: 35px;
- margin-bottom: 35px;
- width: 150px;
- height: 150px;
- // padding: 0 25px;
- line-height: 150px;
- text-align: center;
- border-radius: 50%;
- background-color: #fbf8f8;
- // border: 2px solid #fff;
- box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px;
- // overflow: hidden;
- transition: all 0.3s;
- .imgBox {
- cursor: pointer;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 3;
- width: 150px;
- height: 150px;
- border-radius: 50%;
- background-color: #fbf8f8;
- overflow: hidden;
- img {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 100%;
- }
- }
- .uploadImg {
- line-height: 145px;
- font-size: 50px;
- font-weight: 700;
- text-align: center;
- }
- }
- .faceItemActive {
- position: relative;
- transition: all 0.3s;
- &::before {
- content: "";
- position: absolute;
- // top: -3px;
- // right: -7px;
- // left: -3px;
- // bottom: -7px;
- top: -3px;
- right: -3px;
- left: -3px;
- bottom: -3px;
- z-index: 2;
- border-radius: 50%;
- background: linear-gradient(
- 225deg,
- rgb(81 217 202 / 100%),
- rgb(114 100 245 / 100%)
- );
- }
- }
- }
- }
- }
-
- .right {
- width: 25%;
- height: 100%;
- background-color: green;
-
- :deep(.el-tabs--border-card) {
- font-size: 20px;
- border: none;
- }
-
- .tabs {
- height: 100%;
- .card1 {
- .text {
- padding: 10px;
- border: 1px solid #000;
- .el-button {
- float: right;
- margin-top: 10px;
- }
-
- :deep(.el-textarea__inner) {
- resize: none;
- box-shadow: none;
- }
- }
-
- p {
- margin: 10px 0;
- }
-
- > .el-button {
- width: 100%;
- height: 50px;
- margin-top: 10px;
- }
-
- :deep(.el-input .is-focus) {
- // box-shadow: none !important;
- // box-shadow: 0 0 0 1px #000 !important;
- }
- }
- .card2 {
- padding: 10px;
- .el-icon {
- // color: red;
- vertical-align: text-top;
- }
- > div {
- position: relative;
- margin-top: 10px;
- width: 100%;
- border: #000 1px solid;
- border-radius: 10px;
-
- overflow: hidden;
- transition: all 0.3s;
- box-shadow: #00000026 2px 2px 2px 2px;
- &:hover {
- transform: translateY(-10px);
- }
- }
- .uploadAudio {
- padding: 20px;
- // margin-top: 30px;
- margin-bottom: 20px;
- height: 70px;
- .btnBox {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- }
- audio {
- height: 50px;
- width: 100%;
- }
- button {
- border-radius: 10px;
- height: 30px;
- line-height: 22px;
- padding: 5px 10px;
- background-color: #fff;
- transition: all 0.3s;
- &:hover {
- background-color: #000;
-
- color: #fff;
- }
- }
- }
- .uploadAudioAvtion {
- height: 170px;
- }
- .uploadVideo {
- text-align: center;
- margin-bottom: 20px;
- height: 100px;
- font-size: 50px;
- font-weight: 700;
- line-height: 100px;
- input {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- }
- video {
- position: absolute;
- top: 0;
- left: 0;
- z-index: -1;
- width: 100%;
- height: 100%;
- }
- }
- > .el-button {
- width: 100%;
- height: 50px;
- margin-top: 10px;
- // background-color: #000;
- }
- }
- .card3 {
- .text {
- padding: 10px;
- border: 1px solid #000;
-
- .el-button {
- float: right;
- margin-top: 10px;
- }
-
- :deep(.el-textarea__inner) {
- resize: none;
- box-shadow: none;
- }
- }
-
- p {
- margin: 10px 0;
- }
-
- > .el-button {
- width: 100%;
- height: 50px;
- margin-top: 10px;
- }
- }
-
- :deep(.el-tabs__item.is-active) {
- color: #909393;
- background-color: #000;
- }
-
- :deep(.el-tabs__nav) {
- width: 100%;
- }
-
- :deep(.el-tabs__item) {
- width: 34%;
- }
-
- :deep(.el-tabs__item:hover) {
- color: #909393;
- }
-
- :deep(.el-tabs__content) {
- height: calc(100% - 60px);
- padding: 0;
- }
- }
- }
- </style>
|