@@ -21,38 +21,38 @@ | |||||
<script> | <script> | ||||
//#region 禁用网页滚动 | //#region 禁用网页滚动 | ||||
const keyCodeMap = { | |||||
// 91: true, // command | |||||
61: true, | |||||
107: true, // 数字键盘 + | |||||
109: true, // 数字键盘 - | |||||
173: true, // 火狐 - 号 | |||||
187: true, // + | |||||
189: true, // - | |||||
}; | |||||
// 覆盖ctrl||command + ‘+’/‘-’ | |||||
document.onkeydown = function (event) { | |||||
const e = event || window.event; | |||||
const ctrlKey = e.ctrlKey || e.metaKey; | |||||
if (ctrlKey && keyCodeMap[e.keyCode]) { | |||||
e.preventDefault(); | |||||
} else if (e.detail) { // Firefox | |||||
event.returnValue = false; | |||||
} | |||||
}; | |||||
// 覆盖鼠标滑动 | |||||
document.body.addEventListener('wheel', (e) => { | |||||
if (e.ctrlKey) { | |||||
if (e.deltaY < 0) { | |||||
e.preventDefault(); | |||||
return false; | |||||
} | |||||
if (e.deltaY > 0) { | |||||
e.preventDefault(); | |||||
return false; | |||||
} | |||||
} | |||||
}, { passive: false }); | |||||
// const keyCodeMap = { | |||||
// // 91: true, // command | |||||
// 61: true, | |||||
// 107: true, // 数字键盘 + | |||||
// 109: true, // 数字键盘 - | |||||
// 173: true, // 火狐 - 号 | |||||
// 187: true, // + | |||||
// 189: true, // - | |||||
// }; | |||||
// // 覆盖ctrl||command + ‘+’/‘-’ | |||||
// document.onkeydown = function (event) { | |||||
// const e = event || window.event; | |||||
// const ctrlKey = e.ctrlKey || e.metaKey; | |||||
// if (ctrlKey && keyCodeMap[e.keyCode]) { | |||||
// e.preventDefault(); | |||||
// } else if (e.detail) { // Firefox | |||||
// event.returnValue = false; | |||||
// } | |||||
// }; | |||||
// // 覆盖鼠标滑动 | |||||
// document.body.addEventListener('wheel', (e) => { | |||||
// if (e.ctrlKey) { | |||||
// if (e.deltaY < 0) { | |||||
// e.preventDefault(); | |||||
// return false; | |||||
// } | |||||
// if (e.deltaY > 0) { | |||||
// e.preventDefault(); | |||||
// return false; | |||||
// } | |||||
// } | |||||
// }, { passive: false }); | |||||
//#endregion ----------------------------------- | //#endregion ----------------------------------- | ||||
//#region | //#region | ||||
@@ -41,7 +41,8 @@ export default { | |||||
navbar: { | navbar: { | ||||
account: "Account", | account: "Account", | ||||
logout: "Logout", | logout: "Logout", | ||||
goLogin:'Go and log in' | |||||
goLogin:'Go and log in', | |||||
LanguageChange:'Language switching' | |||||
}, | }, | ||||
// 创作视频 | // 创作视频 | ||||
@@ -79,6 +80,8 @@ export default { | |||||
copy:'Copy to text', | copy:'Copy to text', | ||||
tooltip1:'Click to listen', | tooltip1:'Click to listen', | ||||
tooltip2:'Add Pause', | tooltip2:'Add Pause', | ||||
uploadImgTip1:'Click here to upload pictures', | |||||
uploadImgTip2:'Please ensure that the uploaded image is an open face image', | |||||
}, | }, | ||||
// 我的视频 | // 我的视频 | ||||
@@ -41,7 +41,8 @@ export default { | |||||
navbar: { | navbar: { | ||||
account: "账户", | account: "账户", | ||||
logout: "注销", | logout: "注销", | ||||
goLogin:'登录' | |||||
goLogin:'登录', | |||||
LanguageChange:'语言切换' | |||||
}, | }, | ||||
// 创作视频 | // 创作视频 | ||||
@@ -79,6 +80,8 @@ export default { | |||||
copy:'复制到文案', | copy:'复制到文案', | ||||
tooltip1:'点击试听', | tooltip1:'点击试听', | ||||
tooltip2:'添加停顿', | tooltip2:'添加停顿', | ||||
uploadImgTip1:'点此上传图片', | |||||
uploadImgTip2:'请确保上传图片为无遮挡的正脸图片', | |||||
}, | }, | ||||
// 我的视频 | // 我的视频 | ||||
@@ -25,7 +25,8 @@ const tagsViewStore = useTagsViewStore(); | |||||
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; | |||||
background: linear-gradient(to bottom, black 30%, white 70%); | |||||
} | } | ||||
.fixed-header + .app-main { | .fixed-header + .app-main { | ||||
@@ -14,7 +14,14 @@ | |||||
{{ $t(routeName as string) }} | {{ $t(routeName as string) }} | ||||
</div> | </div> | ||||
<!--语言选择--> | <!--语言选择--> | ||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
<!-- <div | <!-- <div | ||||
class="avatar" | class="avatar" | ||||
@@ -196,9 +203,10 @@ watch( | |||||
} | } | ||||
} | } | ||||
.navItem { | .navItem { | ||||
font-size: 16px; | |||||
cursor: pointer; | cursor: pointer; | ||||
transition: all 0.3s; | transition: all 0.3s; | ||||
margin-right: 10px; | |||||
margin-right: 20px; | |||||
&:hover { | &:hover { | ||||
color: #4769da; | color: #4769da; | ||||
} | } | ||||
@@ -25,7 +25,7 @@ | |||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-DocumentAdd /></el-icon> | <el-icon><i-ep-DocumentAdd /></el-icon> | ||||
</div> | </div> | ||||
API Access | |||||
{{ $t("API.title") }} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -2,6 +2,7 @@ | |||||
export {} | export {} | ||||
declare global { | declare global { | ||||
const EffectScope: typeof import('vue')['EffectScope'] | const EffectScope: typeof import('vue')['EffectScope'] | ||||
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 asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | ||||
@@ -270,6 +271,7 @@ import { UnwrapRef } from 'vue' | |||||
declare module 'vue' { | declare module 'vue' { | ||||
interface ComponentCustomProperties { | interface ComponentCustomProperties { | ||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | ||||
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 asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | ||||
@@ -1,7 +1,7 @@ | |||||
<template> | <template> | ||||
<div class="page flex justify-around"> | <div class="page flex justify-around"> | ||||
<!-- 左侧栏 --> | <!-- 左侧栏 --> | ||||
<div class="left"> | |||||
<div class="left scrolly"> | |||||
<!-- 顶部 --> | <!-- 顶部 --> | ||||
<!-- 选中AiFace --> | <!-- 选中AiFace --> | ||||
<div class="left-top" v-show="showUploadBtn == 1"> | <div class="left-top" v-show="showUploadBtn == 1"> | ||||
@@ -40,7 +40,11 @@ | |||||
<div class="icon">✔</div> | <div class="icon">✔</div> | ||||
</div> | </div> | ||||
<div v-if="!compressionImgLoad" class="upload inmiddle"> | <div v-if="!compressionImgLoad" class="upload inmiddle"> | ||||
+ | |||||
<p> | |||||
<el-icon><i-ep-FolderAdd /></el-icon> | |||||
</p> | |||||
<span>{{ $t("createVideo.uploadImgTip1") }}</span> | |||||
<span>{{ $t("createVideo.uploadImgTip2") }}</span> | |||||
<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"> | ||||
@@ -242,7 +246,7 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 右侧栏 --> | <!-- 右侧栏 --> | ||||
<div class="right"> | |||||
<div class="right scrolly"> | |||||
<div class="subscript"> | <div class="subscript"> | ||||
<!-- <span>GPT</span> --> | <!-- <span>GPT</span> --> | ||||
<img src="../../assets/img/gpttotext.png" alt="" /> | <img src="../../assets/img/gpttotext.png" alt="" /> | ||||
@@ -257,7 +261,7 @@ | |||||
maxlength="3000" | maxlength="3000" | ||||
id="textInputId" | id="textInputId" | ||||
v-model="textareaContent" | v-model="textareaContent" | ||||
:rows="15" | |||||
:rows="12" | |||||
type="textarea" | type="textarea" | ||||
:placeholder="$t('createVideo.aiText')" | :placeholder="$t('createVideo.aiText')" | ||||
/> | /> | ||||
@@ -380,22 +384,36 @@ | |||||
<el-icon class="icon-Headset"><i-ep-Headset /></el-icon> | <el-icon class="icon-Headset"><i-ep-Headset /></el-icon> | ||||
{{ $t("createVideo.uploadAudio") }} | {{ $t("createVideo.uploadAudio") }} | ||||
</p> | </p> | ||||
<div class="uploadVideo"> | |||||
<div | |||||
class="uploadVideo" | |||||
:class=" | |||||
audioUrl && showAudioWhich == 1 ? 'uploadAudioAvtion2' : '' | |||||
" | |||||
> | |||||
<el-icon><i-ep-FolderAdd /></el-icon> | <el-icon><i-ep-FolderAdd /></el-icon> | ||||
<!-- fileInput.value.files[0] e.target.value = null --> | |||||
<input | <input | ||||
accept="audio/*" | accept="audio/*" | ||||
type="file" | type="file" | ||||
ref="fileInput" | ref="fileInput" | ||||
@click="e.target.value = null" | |||||
@click="handleFileClick" | |||||
@change="handleFileChange" | @change="handleFileChange" | ||||
/> | /> | ||||
<div class="AudioBox" v-if="audioUrl && showAudioWhich == 1"> | |||||
<audio controls :src="audioUrl" id="uploadAudio"></audio> | |||||
</div> | |||||
</div> | </div> | ||||
<!-- 录制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") }} | {{ $t("createVideo.recordedAudio") }} | ||||
</p> | </p> | ||||
<div class="uploadAudio"> | |||||
<div | |||||
class="uploadAudio" | |||||
:class=" | |||||
audioUrl && showAudioWhich == 2 ? 'uploadAudioAvtion' : '' | |||||
" | |||||
> | |||||
<div class="btnBox"> | <div class="btnBox"> | ||||
<button | <button | ||||
class="pointer" | class="pointer" | ||||
@@ -412,10 +430,13 @@ | |||||
{{ $t("createVideo.stopRecorded") }} | {{ $t("createVideo.stopRecorded") }} | ||||
</button> | </button> | ||||
</div> | </div> | ||||
<div class="AudioBox" v-if="audioUrl && showAudioWhich == 2"> | |||||
<audio controls :src="audioUrl" id="uploadAudio"></audio> | |||||
</div> | |||||
</div> | </div> | ||||
<div class="AudioBox" v-if="audioUrl"> | |||||
<!-- <div class="AudioBox" v-if="audioUrl"> | |||||
<audio controls :src="audioUrl" id="uploadAudio"></audio> | <audio controls :src="audioUrl" id="uploadAudio"></audio> | ||||
</div> | |||||
</div> --> | |||||
<!-- 保存视频 --> | <!-- 保存视频 --> | ||||
<el-button | <el-button | ||||
@click="saveOrUpdate(2, 'saveVideo')" | @click="saveOrUpdate(2, 'saveVideo')" | ||||
@@ -968,7 +989,7 @@ async function getPreviewAudio() { | |||||
if (!res.data.data) { | if (!res.data.data) { | ||||
ElMessage.error( | ElMessage.error( | ||||
lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
? `暂时无法试听,请稍后重试1` | |||||
? `暂时无法试听,请稍后重试` | |||||
: `Unable to listen, please try again later` | : `Unable to listen, please try again later` | ||||
); | ); | ||||
previewAudioLoading.value = false; | previewAudioLoading.value = false; | ||||
@@ -984,7 +1005,7 @@ async function getPreviewAudio() { | |||||
} catch (error) { | } catch (error) { | ||||
ElMessage.error( | ElMessage.error( | ||||
lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
? `暂时无法试听,请稍后重试2` | |||||
? `暂时无法试听,请稍后重试` | |||||
: `Unable to listen, please try again later` | : `Unable to listen, please try again later` | ||||
); | ); | ||||
previewAudioLoading.value = false; | previewAudioLoading.value = false; | ||||
@@ -993,6 +1014,10 @@ async function getPreviewAudio() { | |||||
} | } | ||||
//#endregion | //#endregion | ||||
//#region card2的逻辑 | |||||
const showAudioWhich = ref(0); // 哪个音乐控件显示 | |||||
//#endregion ---------------------------- | |||||
//#region 录制MP3上传语音 | //#region 录制MP3上传语音 | ||||
const parameter = { | const parameter = { | ||||
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16 | sampleBits: 16, // 采样位数,支持 8 或 16,默认是16 | ||||
@@ -1006,6 +1031,11 @@ const audioData = ref(""); | |||||
const videoId = ref(null); //上传mp3的videoId,创建视频会用到 | const videoId = ref(null); //上传mp3的videoId,创建视频会用到 | ||||
const startRecording = async () => { | const startRecording = async () => { | ||||
if (showAudioWhich.value != 2) { | |||||
audioUrl.value = null; | |||||
audioData.value = null; | |||||
showAudioWhich.value = 2; | |||||
} | |||||
try { | try { | ||||
await recorder.start(); | await recorder.start(); | ||||
console.log("Recording started"); | console.log("Recording started"); | ||||
@@ -1021,7 +1051,7 @@ const stopRecording = async () => { | |||||
audioUrl.value = URL.createObjectURL(recorder.getWAVBlob()); | audioUrl.value = URL.createObjectURL(recorder.getWAVBlob()); | ||||
audioData.value = recorder.getWAVBlob(); | audioData.value = recorder.getWAVBlob(); | ||||
isRecording.value = true; | isRecording.value = true; | ||||
console.log(document.getElementById("uploadAudio").duration); | |||||
// console.log(document.getElementById("uploadAudio").duration); | |||||
} catch (error) { | } catch (error) { | ||||
console.error(error); | console.error(error); | ||||
} | } | ||||
@@ -1066,7 +1096,17 @@ const fileInput = ref(null); | |||||
let intervalId = null; // 用于存储 setInterval 的返回值 | let intervalId = null; // 用于存储 setInterval 的返回值 | ||||
const uploadAudioTime = ref(null); // 音频时长 | const uploadAudioTime = ref(null); // 音频时长 | ||||
// 点击上传input | |||||
function handleFileClick(e) { | |||||
showAudioWhich.value = 0; | |||||
audioUrl.value = null; | |||||
audioData.value = null; | |||||
e.target.value = null; | |||||
} | |||||
// 上传input触发change | |||||
const handleFileChange = async () => { | const handleFileChange = async () => { | ||||
await stopRecording(); | |||||
showAudioWhich.value = 1; | |||||
const file = fileInput.value.files[0]; | const file = fileInput.value.files[0]; | ||||
if (file) { | if (file) { | ||||
@@ -1076,7 +1116,7 @@ const handleFileChange = async () => { | |||||
// 进行大小时长限制 | // 进行大小时长限制 | ||||
await countAudioTime(audio2); | await countAudioTime(audio2); | ||||
// 限制60秒 | // 限制60秒 | ||||
if (uploadAudioTime.value > 60) { | |||||
if (uploadAudioTime.value > 960) { | |||||
ElMessage.error( | ElMessage.error( | ||||
lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
? `上传失败,您上传的文件时长与您的权益不匹配` | ? `上传失败,您上传的文件时长与您的权益不匹配` | ||||
@@ -1087,7 +1127,7 @@ const handleFileChange = async () => { | |||||
return; | return; | ||||
} | } | ||||
// 限制3mb | // 限制3mb | ||||
if (file.size / 1048576 > 3) { | |||||
if (file.size / 1048576 > 93) { | |||||
ElMessage.error( | ElMessage.error( | ||||
lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
? `上传失败,您上传的文件大小与您的权益不匹配` | ? `上传失败,您上传的文件大小与您的权益不匹配` | ||||
@@ -1619,8 +1659,8 @@ onUnmounted(() => { | |||||
<style lang="scss" scoped> | <style lang="scss" scoped> | ||||
.page { | .page { | ||||
// height: 1000px; | // height: 1000px; | ||||
height: calc(100vh - 80px); | |||||
height: 1000px; | height: 1000px; | ||||
height: calc(100vh - 80px); | |||||
// padding: 20px 0 0 40px; | // padding: 20px 0 0 40px; | ||||
background-color: #fff; | background-color: #fff; | ||||
border-radius: 25px 0 0; | border-radius: 25px 0 0; | ||||
@@ -1630,7 +1670,10 @@ onUnmounted(() => { | |||||
width: 68%; | width: 68%; | ||||
// height: 860px; | // height: 860px; | ||||
height: 1000px; | height: 1000px; | ||||
max-height: 100%; | |||||
padding: 20px; | padding: 20px; | ||||
overflow: hidden; | |||||
overflow-y: scroll; | |||||
:deep(.el-input__wrapper) { | :deep(.el-input__wrapper) { | ||||
border: none; | border: none; | ||||
border-bottom: 2px solid #000; | border-bottom: 2px solid #000; | ||||
@@ -1704,7 +1747,7 @@ onUnmounted(() => { | |||||
} | } | ||||
.trueImg { | .trueImg { | ||||
position: relative; | position: relative; | ||||
top: 60px; | |||||
top: 4%; | |||||
width: 100px; | width: 100px; | ||||
height: 100px; | height: 100px; | ||||
border-radius: 50%; | border-radius: 50%; | ||||
@@ -1725,18 +1768,41 @@ onUnmounted(() => { | |||||
opacity: 0; | opacity: 0; | ||||
} | } | ||||
.upload { | .upload { | ||||
top: 200px; | |||||
width: 100px; | |||||
height: 100px; | |||||
top: 30%; | |||||
width: 400px; | |||||
height: 200px; | |||||
padding-top: 10px; | |||||
font-size: 50px; | font-size: 50px; | ||||
line-height: 100px; | line-height: 100px; | ||||
text-align: center; | text-align: center; | ||||
background-color: #ccc; | background-color: #ccc; | ||||
border-radius: 50%; | |||||
border-radius: 30px; | |||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px; | |||||
p { | |||||
position: absolute; | |||||
top: 50%; | |||||
left: 50%; | |||||
transform: translate(-50%, -50%); | |||||
z-index: -1; | |||||
opacity: 0.1; | |||||
.el-icon { | |||||
width: 200px; | |||||
height: 200px; | |||||
font-size: 150px; | |||||
} | |||||
} | |||||
span { | |||||
display: block; | |||||
font-size: 16px; | |||||
font-weight: 900; | |||||
line-height: 16px; | |||||
text-align: center; | |||||
margin-bottom: 130px; | |||||
} | |||||
} | } | ||||
.falseImg { | .falseImg { | ||||
top: 350px; | |||||
top: 75%; | |||||
// background-color: #795562; | // background-color: #795562; | ||||
display: flex; | display: flex; | ||||
justify-content: space-evenly; | justify-content: space-evenly; | ||||
@@ -1864,7 +1930,7 @@ onUnmounted(() => { | |||||
flex-wrap: wrap; | flex-wrap: wrap; | ||||
justify-content: flex-start; | justify-content: flex-start; | ||||
width: 100%; | width: 100%; | ||||
height: 180px; | |||||
height: 220px; | |||||
overflow-y: scroll; | overflow-y: scroll; | ||||
.faceItem { | .faceItem { | ||||
position: relative; | position: relative; | ||||
@@ -2040,12 +2106,14 @@ onUnmounted(() => { | |||||
width: 32%; | width: 32%; | ||||
// height: 860px; | // height: 860px; | ||||
height: 1000px; | height: 1000px; | ||||
max-height: 100%; | |||||
padding: 30px 30px 20px 30px; | padding: 30px 30px 20px 30px; | ||||
background-color: #f1f2f6; | background-color: #f1f2f6; | ||||
border-radius: 30px 0 0 0; | border-radius: 30px 0 0 0; | ||||
position: relative; | position: relative; | ||||
z-index: 2; | z-index: 2; | ||||
overflow: hidden; | |||||
overflow-y: scroll; | |||||
.subscript { | .subscript { | ||||
position: absolute; | position: absolute; | ||||
top: 30px; | top: 30px; | ||||
@@ -2083,7 +2151,7 @@ onUnmounted(() => { | |||||
min-height: 100%; | min-height: 100%; | ||||
padding: 20px 20px 0px 20px; | padding: 20px 20px 0px 20px; | ||||
border-radius: 20px; | border-radius: 20px; | ||||
overflow-y: scroll; | |||||
.card1 { | .card1 { | ||||
.text { | .text { | ||||
padding: 10px; | padding: 10px; | ||||
@@ -2138,8 +2206,10 @@ onUnmounted(() => { | |||||
.card2 { | .card2 { | ||||
padding: 10px; | padding: 10px; | ||||
.el-icon { | .el-icon { | ||||
flex: 1; | |||||
// color: red; | // color: red; | ||||
vertical-align: text-top; | vertical-align: text-top; | ||||
transition: all 0.3s; | |||||
} | } | ||||
> div { | > div { | ||||
position: relative; | position: relative; | ||||
@@ -2154,6 +2224,7 @@ onUnmounted(() => { | |||||
transform: translateY(-10px); | transform: translateY(-10px); | ||||
} | } | ||||
} | } | ||||
// 录制mp3部分 | |||||
.uploadAudio { | .uploadAudio { | ||||
padding: 20px; | padding: 20px; | ||||
// margin-top: 30px; | // margin-top: 30px; | ||||
@@ -2186,34 +2257,35 @@ onUnmounted(() => { | |||||
.uploadAudioAvtion { | .uploadAudioAvtion { | ||||
height: 170px; | height: 170px; | ||||
} | } | ||||
.uploadAudioAvtion2 { | |||||
// height: 220px !important; | |||||
} | |||||
// 上传音频部分 | |||||
.uploadVideo { | .uploadVideo { | ||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
text-align: center; | text-align: center; | ||||
margin-bottom: 20px; | margin-bottom: 20px; | ||||
height: 100px; | height: 100px; | ||||
font-size: 50px; | font-size: 50px; | ||||
font-weight: 700; | font-weight: 700; | ||||
line-height: 100px; | line-height: 100px; | ||||
transition: all 0.3s; | |||||
input { | input { | ||||
position: absolute; | position: absolute; | ||||
top: 0; | top: 0; | ||||
left: 0; | left: 0; | ||||
width: 100%; | width: 100%; | ||||
height: 100%; | |||||
height: 100px; | |||||
opacity: 0; | opacity: 0; | ||||
} | |||||
video { | |||||
position: absolute; | |||||
top: 0; | |||||
left: 0; | |||||
z-index: -1; | |||||
width: 100%; | |||||
height: 100%; | |||||
cursor: pointer; | |||||
} | } | ||||
} | } | ||||
.AudioBox { | .AudioBox { | ||||
display: flex; | display: flex; | ||||
justify-content: space-around; | justify-content: space-around; | ||||
padding: 20px; | |||||
padding: 10px; | |||||
transition: all 0.3s; | transition: all 0.3s; | ||||
} | } | ||||
> .el-button { | > .el-button { | ||||
@@ -17,15 +17,22 @@ | |||||
:rules="loginRules" | :rules="loginRules" | ||||
class="login-form" | class="login-form" | ||||
> | > | ||||
<div class="flex text-white items-center py-4"> | |||||
<span class="text-2xl flex-1 text-center">{{ | |||||
<div class="flex text-white items-center"> | |||||
<span class="flex-1 text-center">{{ | |||||
$t("login.title") + " " + $t("login.login") | $t("login.title") + " " + $t("login.login") | ||||
}}</span> | }}</span> | ||||
<lang-select style="color: #fff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
</div> | </div> | ||||
<el-form-item prop="email"> | <el-form-item prop="email"> | ||||
<div class="p-2 text-white"> | |||||
<div class="text-white"> | |||||
<svg-icon icon-class="user" /> | <svg-icon icon-class="user" /> | ||||
</div> | </div> | ||||
<el-input | <el-input | ||||
@@ -39,7 +46,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="password"> | <el-form-item prop="password"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -61,7 +68,7 @@ | |||||
<!-- 验证码 --> | <!-- 验证码 --> | ||||
<el-form-item prop="verifyCode"> | <el-form-item prop="verifyCode"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="verify_code" /> | <svg-icon icon-class="verify_code" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -122,15 +129,22 @@ | |||||
:rules="loginRules" | :rules="loginRules" | ||||
class="login-form" | class="login-form" | ||||
> | > | ||||
<div class="flex text-white items-center py-4"> | |||||
<span class="text-2xl flex-1 text-center">{{ | |||||
<div class="flex text-white items-center"> | |||||
<span class="flex-1 text-center">{{ | |||||
$t("login.title") + " " + $t("login.register") | $t("login.title") + " " + $t("login.register") | ||||
}}</span> | }}</span> | ||||
<lang-select style="color: #fff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
</div> | </div> | ||||
<el-form-item prop="email"> | <el-form-item prop="email"> | ||||
<div class="p-2 text-white"> | |||||
<div class="text-white"> | |||||
<svg-icon icon-class="user" /> | <svg-icon icon-class="user" /> | ||||
</div> | </div> | ||||
<el-input | <el-input | ||||
@@ -144,7 +158,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="password"> | <el-form-item prop="password"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -164,7 +178,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="confirmPassword"> | <el-form-item prop="confirmPassword"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -229,15 +243,22 @@ | |||||
:rules="loginRules" | :rules="loginRules" | ||||
class="login-form" | class="login-form" | ||||
> | > | ||||
<div class="flex text-white items-center py-4"> | |||||
<span class="text-2xl flex-1 text-center">{{ | |||||
<div class="flex text-white items-center"> | |||||
<span class="flex-1 text-center">{{ | |||||
$t("login.title") + " " + $t("login.forgetPwdTitle") | $t("login.title") + " " + $t("login.forgetPwdTitle") | ||||
}}</span> | }}</span> | ||||
<lang-select style="color: #fff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
</div> | </div> | ||||
<el-form-item prop="email"> | <el-form-item prop="email"> | ||||
<div class="p-2 text-white"> | |||||
<div class="text-white"> | |||||
<svg-icon icon-class="user" /> | <svg-icon icon-class="user" /> | ||||
</div> | </div> | ||||
<el-input | <el-input | ||||
@@ -290,15 +311,22 @@ | |||||
:rules="loginRules" | :rules="loginRules" | ||||
class="login-form" | class="login-form" | ||||
> | > | ||||
<div class="flex text-white items-center py-4"> | |||||
<span class="text-2xl flex-1 text-center">{{ | |||||
<div class="flex text-white items-center"> | |||||
<span class="flex-1 text-center">{{ | |||||
$t("login.title") + " " + $t("login.resetPassword") | $t("login.title") + " " + $t("login.resetPassword") | ||||
}}</span> | }}</span> | ||||
<lang-select style="color: #fff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
</div> | </div> | ||||
<el-form-item prop="oldPassword"> | <el-form-item prop="oldPassword"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -318,7 +346,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="password"> | <el-form-item prop="password"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -338,7 +366,7 @@ | |||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="confirmPassword4"> | <el-form-item prop="confirmPassword4"> | ||||
<span class="p-2 text-white"> | |||||
<span class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</span> | </span> | ||||
<el-input | <el-input | ||||
@@ -404,15 +432,22 @@ | |||||
:rules="loginRules" | :rules="loginRules" | ||||
class="login-form" | class="login-form" | ||||
> | > | ||||
<div class="flex text-white items-center py-4"> | |||||
<span class="text-2xl flex-1 text-center">{{ | |||||
<div class="flex text-white items-center"> | |||||
<span class="flex-1 text-center">{{ | |||||
$t("login.title") + " " + $t("login.setNewPwd") | $t("login.title") + " " + $t("login.setNewPwd") | ||||
}}</span> | }}</span> | ||||
<lang-select style="color: #fff" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="$t('navbar.LanguageChange')" | |||||
placement="top-start" | |||||
> | |||||
<lang-select class="navItem" style="color: #ffffff" /> | |||||
</el-tooltip> | |||||
</div> | </div> | ||||
<el-form-item prop="newPwd"> | <el-form-item prop="newPwd"> | ||||
<div class="p-2 text-white"> | |||||
<div class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</div> | </div> | ||||
<el-input | <el-input | ||||
@@ -432,7 +467,7 @@ | |||||
</span> | </span> | ||||
</el-form-item> | </el-form-item> | ||||
<el-form-item prop="confirmNewPwd"> | <el-form-item prop="confirmNewPwd"> | ||||
<div class="p-2 text-white"> | |||||
<div class="text-white"> | |||||
<svg-icon icon-class="password" /> | <svg-icon icon-class="password" /> | ||||
</div> | </div> | ||||
<el-input | <el-input | ||||
@@ -1019,6 +1054,8 @@ onMounted(() => { | |||||
.login-container { | .login-container { | ||||
position: relative; | position: relative; | ||||
width: 100%; | width: 100%; | ||||
// width: 1920px; | |||||
// height: 1080px; | |||||
min-height: 100%; | min-height: 100%; | ||||
overflow: hidden; | overflow: hidden; | ||||
// background-color: #2d3a4b; | // background-color: #2d3a4b; | ||||
@@ -1063,6 +1100,15 @@ onMounted(() => { | |||||
&:hover { | &:hover { | ||||
backdrop-filter: blur(7px); | backdrop-filter: blur(7px); | ||||
} | } | ||||
.items-center { | |||||
padding: 20px; | |||||
font-size: 30px; | |||||
} | |||||
.el-form-item { | |||||
.text-white { | |||||
padding: 8px; | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -169,6 +169,9 @@ | |||||
destroy-on-close | destroy-on-close | ||||
@close="closeInfoDialog" | @close="closeInfoDialog" | ||||
> | > | ||||
<div class="LoadingBox" v-if="submitUserInfoLoading"> | |||||
<my-Loading-Icon v-if="submitUserInfoLoading"></my-Loading-Icon> | |||||
</div> | |||||
<el-row> | <el-row> | ||||
<el-col :span="4"> {{ $t("public.avatar") }}: </el-col> | <el-col :span="4"> {{ $t("public.avatar") }}: </el-col> | ||||
<el-col :span="20"> | <el-col :span="20"> | ||||
@@ -242,18 +245,23 @@ async function chooseImg(e) { | |||||
dialogAvatarData.value = null; | dialogAvatarData.value = null; | ||||
// 压缩配置 | // 压缩配置 | ||||
const options = { | const options = { | ||||
maxSizeMB: 2, // 最大压缩大小为 1MB | |||||
useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 | |||||
maxSizeMB: 2, // 最大压缩大小为 2MB | |||||
useWebWorker: false, // 使用 Web Worker 进行压缩,提高性能 | |||||
}; | }; | ||||
const compressedFile = await imageCompression(e.target.files[0], options); | const compressedFile = await imageCompression(e.target.files[0], options); | ||||
dialogAvatarUrl.value = URL.createObjectURL(compressedFile); | dialogAvatarUrl.value = URL.createObjectURL(compressedFile); | ||||
dialogAvatarData.value = compressedFile; | dialogAvatarData.value = compressedFile; | ||||
// 不压缩图片 | |||||
// dialogAvatarUrl.value = e.target.files[0]; | |||||
// dialogAvatarData.value = e.target.files[0]; | |||||
} else { | } else { | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
const submitUserInfoLoading = ref(false); | |||||
// 上传编辑信息 | // 上传编辑信息 | ||||
async function submitUserInfo() { | async function submitUserInfo() { | ||||
submitUserInfoLoading.value = true; | |||||
if (dialogAvatarData.value) { | if (dialogAvatarData.value) { | ||||
let formData = new FormData(); | let formData = new FormData(); | ||||
const timestamp = Date.now(); | const timestamp = Date.now(); | ||||
@@ -270,6 +278,7 @@ async function submitUserInfo() { | |||||
); | ); | ||||
await userInfoPinia.getUserInfo(); | await userInfoPinia.getUserInfo(); | ||||
showEditInfoDialog.value = false; | showEditInfoDialog.value = false; | ||||
submitUserInfoLoading.value = false; | |||||
router.go(0); | router.go(0); | ||||
} catch (error) { | } catch (error) { | ||||
ElMessage.error( | ElMessage.error( | ||||
@@ -277,6 +286,7 @@ async function submitUserInfo() { | |||||
? `修改失败,请稍后重试` | ? `修改失败,请稍后重试` | ||||
: `The modification failed. Please try again later` | : `The modification failed. Please try again later` | ||||
); | ); | ||||
submitUserInfoLoading.value = false; | |||||
} | } | ||||
} else { | } else { | ||||
const data = { | const data = { | ||||
@@ -289,6 +299,7 @@ async function submitUserInfo() { | |||||
); | ); | ||||
await userInfoPinia.getUserInfo(); | await userInfoPinia.getUserInfo(); | ||||
showEditInfoDialog.value = false; | showEditInfoDialog.value = false; | ||||
submitUserInfoLoading.value = false; | |||||
router.go(0); | router.go(0); | ||||
} catch (error) { | } catch (error) { | ||||
ElMessage.error( | ElMessage.error( | ||||
@@ -296,6 +307,7 @@ async function submitUserInfo() { | |||||
? `修改失败,请稍后重试` | ? `修改失败,请稍后重试` | ||||
: `The modification failed. Please try again later` | : `The modification failed. Please try again later` | ||||
); | ); | ||||
submitUserInfoLoading.value = false; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -453,8 +465,9 @@ function routerTo(url) { | |||||
top: 50%; | top: 50%; | ||||
left: 50%; | left: 50%; | ||||
transform: translate(-50%, -50%); | transform: translate(-50%, -50%); | ||||
max-width: 100%; | |||||
max-height: 100%; | |||||
width: 100%; | |||||
height: 100%; | |||||
object-fit: cover; | |||||
} | } | ||||
} | } | ||||
@@ -800,6 +813,20 @@ function routerTo(url) { | |||||
} | } | ||||
.editInfoDialog { | .editInfoDialog { | ||||
position: relative; | |||||
overflow: hidden; | |||||
.LoadingBox { | |||||
position: absolute; | |||||
top: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
z-index: 999; | |||||
opacity: 0.8; | |||||
border-radius: 30px; | |||||
padding-top: 150px; | |||||
background-color: #ccc; | |||||
} | |||||
.el-row { | .el-row { | ||||
display: flex; | display: flex; | ||||
justify-content: space-evenly; | justify-content: space-evenly; | ||||