Author | SHA1 | Message | Date |
---|---|---|---|
|
bf1dbdeef7 | 1 | 1 year ago |
|
af8a52f71a | 1 | 1 year ago |
|
3c02f7889b | 1 | 1 year ago |
|
e010b8687d | 1 | 1 year ago |
|
3ea71a8495 | 1 | 1 year ago |
|
ae78019597 | 1 | 1 year ago |
|
6f62765b56 | 1 | 1 year ago |
|
837db768cd | 1 | 1 year ago |
|
63b20451f0 | AI文案 | 1 year ago |
|
b2d3b0ad3e | Merge branch 'dev' of https://git.malls.iformall.com/suimang/Home_wap_pc into dev | 1 year ago |
|
a75a03d1b0 | 1 | 1 year ago |
@@ -6,5 +6,7 @@ NODE_ENV='development' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
VITE_APP_PORT = 3000 | |||
## VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||
VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||
# VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||
# VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C' | |||
VITE_APP_BASE_API = 'https://mtest.metavatar.cc/C' | |||
@@ -6,4 +6,4 @@ NODE_ENV='test' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
VITE_APP_PORT = 3000 | |||
# VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||
VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||
VITE_APP_BASE_API = 'https://mtest.metavatar.cc/C' |
@@ -34,6 +34,7 @@ | |||
"vue": "^3.2.45", | |||
"vue-cropper": "^1.0.9", | |||
"vue-i18n": "9", | |||
"vue-qr": "^4.0.9", | |||
"vue-router": "^4.0.13" | |||
}, | |||
"devDependencies": { | |||
@@ -188,3 +188,16 @@ export function getModelDetailByIdApi(id) { | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description:文字判断语种 | |||
* @param {number} id | |||
* @return data | |||
*/ | |||
export function getLanguageApi(data) { | |||
return request({ | |||
url: `/api/VoiceLanguage/getLanguage`, | |||
method: 'POST', | |||
data | |||
}) | |||
} |
@@ -0,0 +1,39 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description:购买金币下单 | |||
* @param productId | |||
* @return: data | |||
*/ | |||
export function createOrderApi(data) { | |||
return request({ | |||
url: `api/productOrder/createOrder`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description:获取订单数据 | |||
* @param data | |||
* @return: data | |||
*/ | |||
export function createPayApi(data) { | |||
return request({ | |||
url: `api/productOrder/createPay`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description:获取订单支付状态 | |||
* @param orderNumber | |||
* @return: data payStatus 查询支付状态 0:待支付,2:支付中,3:已支付 | |||
*/ | |||
export function getOrderStatusApi(orderNumber, payVendor) { | |||
return request({ | |||
url: `api/productOrder/findStatus?orderNumber=${orderNumber}&payVendor=${payVendor}`, | |||
method: 'get' | |||
}) | |||
} |
@@ -0,0 +1,51 @@ | |||
<template> | |||
<div class="loadingIcon"> | |||
<div> | |||
<el-icon class="is-loading"> | |||
<svg | |||
viewBox="0 0 1024 1024" | |||
xmlns="http://www.w3.org/2000/svg" | |||
data-v-ea893728="" | |||
> | |||
<path | |||
fill="currentColor" | |||
d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||
></path> | |||
</svg> | |||
</el-icon> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { useI18n } from "vue-i18n"; | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const props = defineProps({ | |||
isLoading: { | |||
required: false, //是否必传 | |||
}, | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.loadingIcon { | |||
position: relative; | |||
width: 100%; | |||
height: 60px; | |||
line-height: 60px; | |||
text-align: center; | |||
transform: scale(2); | |||
> div { | |||
position: absolute; | |||
top: 0; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
} | |||
.loadingText { | |||
position: relative; | |||
top: -2px; | |||
left: 4px; | |||
} | |||
} | |||
</style> |
@@ -85,6 +85,7 @@ export default { | |||
comingSoon: "COMING SOON", | |||
material: "Material", | |||
subtitles: "Subtitles", | |||
AItext:"AI Script", | |||
sex: "Sex", | |||
videoRatio: "Video Ratio", | |||
all: "All", | |||
@@ -104,6 +105,10 @@ export default { | |||
tooltip2: "Add Pause", | |||
SubtitlesTip: "Subtitles will be shown here", | |||
subtitlesSwitch: "Subtitles Switch", | |||
inputRequirement:'Please enter your requirements, for example: Please generate a beverage advertisement of 500 words or less', | |||
GeneratedText:'Generated Text', | |||
SmartText:'Smart Text', | |||
copy:'Copy to text', | |||
}, | |||
// 我的视频 | |||
@@ -86,6 +86,7 @@ export default { | |||
BackgroundImage: "背景", | |||
material: "素材", | |||
subtitles: "字幕", | |||
AItext:"AI生成文本", | |||
sex: "性别", | |||
videoRatio: "视频比例", | |||
all: "全部", | |||
@@ -105,6 +106,10 @@ export default { | |||
tooltip2: "添加停顿", | |||
SubtitlesTip: "字幕将在此处展示", | |||
subtitlesSwitch: "字幕开关", | |||
inputRequirement:'请输入您的需求,例如:请生成一个500字以内的饮料广告', | |||
GeneratedText:'生成文本', | |||
SmartText:'智能文本', | |||
copy:'复制到文案', | |||
}, | |||
// 我的视频 | |||
@@ -23,7 +23,7 @@ | |||
</div> | |||
{{ $t("myCreating.title") }} | |||
</div> | |||
<div class="myRouter-item" @click="showTalkUsDialog = true"> | |||
<div class="myRouter-item" @click="toUserModel"> | |||
<div class="icon"> | |||
<el-icon><i-ep-user /></el-icon> | |||
</div> | |||
@@ -169,6 +169,13 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
showTalkUsDialog.value = newValue; | |||
}; | |||
//#endregion ------------------------------------ | |||
//#region 页面跳转 | |||
function toUserModel() { | |||
router.push("/userModel"); | |||
showTalkUsDialog.value = true; | |||
} | |||
//#endregion ------------------------------------ | |||
</script> | |||
<!-- 新样式 --> | |||
@@ -196,6 +203,7 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
height: calc(100% - 80px); | |||
padding: 130px 20px 0; | |||
color: #fff; | |||
user-select: none; | |||
// color: #868593; | |||
.bottomBtx { | |||
@@ -55,6 +55,42 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
}, | |||
}, | |||
], | |||
}, // 定制分身 | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/userModel", | |||
children: [ | |||
{ | |||
path: "userModel", | |||
component: () => import("@/views/userModel/index.vue"), | |||
name: "userModel", | |||
meta: { | |||
title: "userModel", | |||
icon: "homepage", | |||
affix: true, | |||
name: "userModel.title", | |||
}, | |||
}, | |||
], | |||
}, // 定制声纹 | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/voiceModel", | |||
children: [ | |||
{ | |||
path: "voiceModel", | |||
component: () => import("@/views/voiceModel/index.vue"), | |||
name: "voiceModel", | |||
meta: { | |||
title: "voiceModel", | |||
icon: "homepage", | |||
affix: true, | |||
name: "voiceModel.title", | |||
}, | |||
}, | |||
], | |||
}, { | |||
path: "/", | |||
component: Layout, | |||
@@ -49,6 +49,7 @@ declare module '@vue/runtime-core' { | |||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | |||
MyLoading: typeof import('./../components/myLoading.vue')['default'] | |||
MyLoadingIcon: typeof import('./../components/myLoadingIcon.vue')['default'] | |||
MyLoadingIcon2: typeof import('./../components/myLoadingIcon2.vue')['default'] | |||
Pagination: typeof import('./../components/Pagination/index.vue')['default'] | |||
RouterLink: typeof import('vue-router')['RouterLink'] | |||
RouterView: typeof import('vue-router')['RouterView'] | |||
@@ -4,6 +4,203 @@ | |||
<div class="mask" v-show="showChooseModel"></div> | |||
<!-- 左侧栏 --> | |||
<div class="left"> | |||
<!-- 字幕框 --> | |||
<div v-show="videoType == 2" class="subtitlesBoxTop"> | |||
<!-- 开关 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p>{{ $t("createVideo.subtitlesSwitch") }}</p> | |||
<el-switch | |||
v-model="Subtitles.SubtitlesSwitch" | |||
style="--el-switch-on-color: #000" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字体系列 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体` : `Font Family` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesFontFamily" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontFamilyList" | |||
:key="item.value" | |||
:label="item.label" | |||
:value="item.value" | |||
/> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- y轴 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `纵坐标` : `Y-axis` }} | |||
</p> | |||
<el-input-number | |||
:precision="0" | |||
v-model="Subtitles.SubtitlesTop" | |||
size="large" | |||
controls-position="right" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字号大小 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字号大小` : `Font Size` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesSize" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontSizeList" | |||
:key="item" | |||
:label="item" | |||
:value="item" | |||
:style="{ | |||
height: item + 'px', | |||
lineHeight: item + 'px', | |||
}" | |||
> | |||
<span :style="{ fontSize: item + 'px', padding: '5px' }">{{ | |||
item | |||
}}</span> | |||
</el-option> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- 字色 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体颜色` : `Font Color` }} | |||
</p> | |||
<div | |||
@click="handleSubtitlesColorShow" | |||
class="myColorBox" | |||
:style="{ backgroundColor: Subtitles.SubtitlesColor }" | |||
> | |||
<div v-show="SubtitlesColorShow" class="selectColor"> | |||
<div | |||
v-for="item in Subtitles.colorList" | |||
:style="{ backgroundColor: item }" | |||
class="selectColor-item" | |||
@click="Subtitles.SubtitlesColor = item" | |||
></div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-show="videoType == 1" class="subtitlesBoxLeft"> | |||
<!-- 开关 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p>{{ $t("createVideo.subtitlesSwitch") }}</p> | |||
<el-switch | |||
v-model="Subtitles.SubtitlesSwitch" | |||
style="--el-switch-on-color: #000" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字体系列 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体` : `Font Family` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesFontFamily" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontFamilyList" | |||
:key="item.value" | |||
:label="item.label" | |||
:value="item.value" | |||
/> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- y轴 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `纵坐标` : `Y-axis` }} | |||
</p> | |||
<el-input-number | |||
:precision="0" | |||
v-model="Subtitles.SubtitlesTop" | |||
size="large" | |||
controls-position="right" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字号大小 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字号大小` : `Font Size` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesSize" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontSizeList" | |||
:key="item" | |||
:label="item" | |||
:value="item" | |||
:style="{ | |||
height: item + 'px', | |||
lineHeight: item + 'px', | |||
}" | |||
> | |||
<span :style="{ fontSize: item + 'px', padding: '5px' }">{{ | |||
item | |||
}}</span> | |||
</el-option> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- 字色 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体颜色` : `Font Color` }} | |||
</p> | |||
<div | |||
@click="handleSubtitlesColorShow" | |||
class="myColorBox" | |||
:style="{ backgroundColor: Subtitles.SubtitlesColor }" | |||
> | |||
<div v-show="SubtitlesColorShow" class="selectColor"> | |||
<div | |||
v-for="item in Subtitles.colorList" | |||
:style="{ backgroundColor: item }" | |||
class="selectColor-item" | |||
@click="Subtitles.SubtitlesColor = item" | |||
></div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 选择模版弹出框 --> | |||
<div class="chooseModelBox" :class="showChooseModel ? '' : 'noModel'"> | |||
<!-- 伸缩按钮 --> | |||
@@ -21,7 +218,7 @@ | |||
> | |||
< | |||
</div> | |||
<!-- tab栏 --> | |||
<!-- tab栏 性别--> | |||
<p>{{ $t("createVideo.sex") }}</p> | |||
<div class="tab" v-show="showChooseModel"> | |||
<div | |||
@@ -46,6 +243,7 @@ | |||
{{ $t("createVideo.female") }} | |||
</div> | |||
</div> | |||
<!-- 横屏竖屏 --> | |||
<p>{{ $t("createVideo.videoRatio") }}</p> | |||
<div class="tab" v-show="showChooseModel"> | |||
<div | |||
@@ -70,6 +268,17 @@ | |||
{{ $t("createVideo.portrait") }} | |||
</div> | |||
</div> | |||
<!-- 风格模版 --> | |||
<!-- <p>{{ $t("createVideo.videoRatio") }}</p> | |||
<div class="tab" v-show="showChooseModel"> | |||
<div | |||
class="tabItem" | |||
:class="modelTabItemActive3 == -1 ? 'tabItemActive' : ''" | |||
@click="changeModelStyle(-1)" | |||
> | |||
{{ $t("createVideo.all") }} | |||
</div> | |||
</div> --> | |||
<!-- 模版列表 --> | |||
<div | |||
class="modeListBox" | |||
@@ -177,6 +386,7 @@ | |||
<!-- tab栏 --> | |||
<div class="tab"> | |||
<div | |||
id="tab-0" | |||
class="tabItem" | |||
:class="tabItemActive == 1 ? 'tabItemActive' : ''" | |||
@click="tabItemActive = 1" | |||
@@ -202,8 +412,15 @@ | |||
:class="tabItemActive == 4 ? 'tabItemActive' : ''" | |||
@click="tabItemActive = 4" | |||
> | |||
{{ $t("createVideo.subtitles") }} | |||
{{ $t("createVideo.aiScript") }} | |||
</div> | |||
<!-- <div | |||
class="tabItem" | |||
:class="tabItemActive == 5 ? 'tabItemActive' : ''" | |||
@click="tabItemActive = 5" | |||
> | |||
{{ $t("createVideo.AItext") }} | |||
</div> --> | |||
</div> | |||
<!-- 文案 只能使用v-if,不能使用v-show--> | |||
<div v-if="tabItemActive == 1" class="tabContent tab1"> | |||
@@ -255,6 +472,7 @@ | |||
v-model="language" | |||
:placeholder="$t('createVideo.select')" | |||
style="width: 100%" | |||
filterable | |||
> | |||
<el-option | |||
v-for="item in languageOptions" | |||
@@ -443,149 +661,77 @@ | |||
/> | |||
<cutImg | |||
@reGetpersonSCIList="reGetpersonSCIList" | |||
:type="5" | |||
:videoType="videoType" | |||
style="width: 100%; height: 100%" | |||
></cutImg> | |||
</div> | |||
<div | |||
class="bjSystemBoxItem" | |||
v-for="item in personSCIList" | |||
:key="item.id" | |||
:class="scImgActive == item.id ? 'ImgBorderActive' : ''" | |||
@click="selectScImg(item)" | |||
> | |||
<div | |||
v-show="scImgActive == item.id" | |||
class="delIcon" | |||
@click="delImg(item.id)" | |||
> | |||
<img src="../../assets/img/delete.png" alt="" /> | |||
</div> | |||
<img class="boxCentreImg" :src="item.material" alt="" /> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 字幕 --> | |||
<div v-if="tabItemActive == 4" class="tabContent tab4"> | |||
<!-- 开关 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p>{{ $t("createVideo.subtitlesSwitch") }}</p> | |||
<el-switch | |||
v-model="Subtitles.SubtitlesSwitch" | |||
style="--el-switch-on-color: #000" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字体系列 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体` : `Font Family` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesFontFamily" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontFamilyList" | |||
:key="item.value" | |||
:label="item.label" | |||
:value="item.value" | |||
/> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- y轴 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `纵坐标` : `Y-axis` }} | |||
</p> | |||
<el-input-number | |||
:precision="0" | |||
v-model="Subtitles.SubtitlesTop" | |||
size="large" | |||
controls-position="right" | |||
/> | |||
</div> | |||
</div> | |||
<!-- 字号大小 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字号大小` : `Font Size` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesSize" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontSizeList" | |||
:key="item" | |||
:label="item" | |||
:value="item" | |||
:style="{ | |||
height: item + 'px', | |||
lineHeight: item + 'px', | |||
}" | |||
> | |||
<span :style="{ fontSize: item + 'px', padding: '5px' }">{{ | |||
item | |||
}}</span> | |||
</el-option> | |||
</el-select> | |||
</div> | |||
</div> | |||
<!-- 字色 --> | |||
<div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字体颜色` : `Font Color` }} | |||
</p> | |||
:type="5" | |||
:videoType="videoType" | |||
style="width: 100%; height: 100%" | |||
></cutImg> | |||
</div> | |||
<div | |||
class="bjSystemBoxItem" | |||
v-for="item in personSCIList" | |||
:key="item.id" | |||
:class="scImgActive == item.id ? 'ImgBorderActive' : ''" | |||
@click="selectScImg(item)" | |||
> | |||
<div | |||
@click="handleSubtitlesColorShow" | |||
class="myColorBox" | |||
:style="{ backgroundColor: Subtitles.SubtitlesColor }" | |||
v-show="scImgActive == item.id" | |||
class="delIcon" | |||
@click="delImg(item.id)" | |||
> | |||
<div v-show="SubtitlesColorShow" class="selectColor"> | |||
<div | |||
v-for="item in Subtitles.colorList" | |||
:style="{ backgroundColor: item }" | |||
class="selectColor-item" | |||
@click="Subtitles.SubtitlesColor = item" | |||
></div> | |||
</div> | |||
<img src="../../assets/img/delete.png" alt="" /> | |||
</div> | |||
<img class="boxCentreImg" :src="item.material" alt="" /> | |||
</div> | |||
</div> | |||
<!-- 字粗 --> | |||
<!-- <div class="tab4Item"> | |||
<div v-if="materialList.BGI.material" class="SubtitlesSwitch"> | |||
<p> | |||
{{ lanChange == "zh-cn" ? `字号大小` : `Font Size` }} | |||
</p> | |||
<el-select | |||
v-model="Subtitles.SubtitlesWeight" | |||
style="width: 100px" | |||
placeholder=" " | |||
size="default" | |||
</div> | |||
<!-- 智能文案 --> | |||
<div v-if="tabItemActive == 4" class="tabContent tab4"> | |||
<div class="card4"> | |||
<!-- 语言 --> | |||
<div class="text"> | |||
<!-- 文本域 --> | |||
<el-input | |||
maxlength="200" | |||
id="textInputId" | |||
v-model="problemContent" | |||
:rows="5" | |||
type="textarea" | |||
:placeholder="$t('createVideo.inputRequirement')" | |||
/> | |||
</div> | |||
<el-button | |||
type="primary" | |||
:disabled="sendLoading" | |||
@click="sendRequirement" | |||
color="#000" | |||
> | |||
<my-Loading-Icon2 v-if="sendLoading"></my-Loading-Icon2> | |||
<span v-if="!sendLoading"> | |||
{{ $t("createVideo.GeneratedText") }} | |||
</span> | |||
</el-button> | |||
<p>{{ $t("createVideo.SmartText") }}</p> | |||
<!-- 语言 --> | |||
<div class="text" style="cursor: text"> | |||
<!-- 文本域 --> | |||
<el-input | |||
maxlength="500" | |||
id="textInputId" | |||
v-model="answerContent" | |||
:rows="15" | |||
type="textarea" | |||
disabled="" | |||
/> | |||
<i | |||
>{{ $t("createVideo.entered") }} {{ answerContent.length }} / | |||
500</i | |||
> | |||
<el-option | |||
v-for="item in Subtitles.fontWeightList" | |||
:key="item" | |||
:label="item" | |||
:value="item" | |||
> | |||
</el-option> | |||
</el-select> | |||
</div> | |||
</div> --> | |||
<el-button color="#000" @click="copyAnswerContent"> | |||
{{ $t("createVideo.copy") }} | |||
</el-button> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 试听的mp3 --> | |||
@@ -613,6 +759,7 @@ import { | |||
saveOrUpdateApi, | |||
createVideoApi, | |||
getModelDetailByIdApi, | |||
getLanguageApi, | |||
} from "@/apis/createVideo"; | |||
import { useI18n } from "vue-i18n"; | |||
import Recorder from "js-audio-recorder"; //mp3插件 | |||
@@ -691,6 +838,13 @@ function changeTabVideoType(index) { | |||
tabVideoType.value | |||
); | |||
} | |||
// 模版风格tab | |||
const modelStyleTabList = ref([]); | |||
const modelTabItemActive3 = ref(-1); //模版风格tab栏 比例 | |||
function changeModelStyle(index) { | |||
modelTabItemActive3.value = index; | |||
} | |||
// watch(tabSex, (newVal, oldVal) => { | |||
// if (newVal == 0) { | |||
// getModeList("", modelPageNum.value, modelPageSize.value); | |||
@@ -736,7 +890,7 @@ const title = | |||
const textareaContent = ref(""); | |||
function insertIcon() { | |||
const textarea = document.getElementById("textInputId"); | |||
const icon = "🕗"; // 这里使用了一个星星作为示例图标,你可以替换为你自己的图标 | |||
const icon = "🕗"; | |||
// 获取光标位置 | |||
const startPos = textarea.selectionStart; | |||
const endPos = textarea.selectionEnd; | |||
@@ -754,6 +908,31 @@ function insertIcon() { | |||
const language = ref(""); //选择的语言 | |||
const sound = ref(""); // 选择的声音 | |||
const soundStyle = ref(""); //选择的风格 | |||
// 输入文字判断语种 | |||
const getLanguageTimeOut = ref(false); //定时器 | |||
watch( | |||
() => textareaContent.value, | |||
() => { | |||
clearTimeout(getLanguageTimeOut.value); | |||
getLanguageTimeOut.value = setTimeout(async () => { | |||
try { | |||
const data = { | |||
paperwork: textareaContent.value, | |||
}; | |||
const res = await getLanguageApi(data); | |||
if (res.code == 200) { | |||
language.value = res.data.id; | |||
} | |||
} catch (error) {} | |||
}, 1500); | |||
} | |||
); | |||
watch( | |||
() => language.value, | |||
() => { | |||
chooseType(); | |||
} | |||
); | |||
// 语言下拉框内容 | |||
const languageOptions = ref([]); | |||
async function voiceTotal() { | |||
@@ -1417,7 +1596,7 @@ async function createVideo() { | |||
sound.value, | |||
soundStyle.value | |||
); | |||
if (res4.data.code != 200) { | |||
if (res4.code != 200) { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `视频时长预估失败,无法生成视频,您可以换个声音试试` | |||
@@ -1427,14 +1606,14 @@ async function createVideo() { | |||
saveLoading.value = false; | |||
return; | |||
} | |||
if (res4.data.data > 300) { | |||
if (res4.data.time > 300) { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `预计生成的视频时长约为${formatTime( | |||
res4.data.data | |||
res4.data.time | |||
)},免费用户生成视频时长为300秒,无法生成视频` | |||
: `The video generated is expected to be about ${formatTime( | |||
res4.data.data | |||
res4.data.time | |||
)} long, and the free user-generated video is 300 seconds long and cannot be generated` | |||
); | |||
createLoading.value = false; | |||
@@ -1443,9 +1622,9 @@ async function createVideo() { | |||
} | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" | |||
? `预计生成的视频时长约为${formatTime(res4.data.data)}` | |||
? `预计生成的视频时长约为${formatTime(res4.data.time)}` | |||
: `The video generated is expected to be approximately${formatTime( | |||
res4.data.data | |||
res4.data.time | |||
)} in length` | |||
); | |||
await saveOrUpdate("isCreate"); | |||
@@ -1518,8 +1697,82 @@ function NumToFixed(num1, num2) { | |||
} | |||
//#endregion ---------------------------- | |||
//#region | |||
//#region AI文案 | |||
// 创建websocket | |||
let mySocket = null; //websocket对象 | |||
const sendLoading = ref(false); //发送状态 | |||
function createWS() { | |||
mySocket = new WebSocket("wss://gptsocket.malls.iformall.com:8010"); | |||
mySocket.onopen = () => { | |||
console.log("WebSocket 连接成功1"); | |||
sendRequirement(); | |||
}; | |||
mySocket.onmessage = (event) => { | |||
// console.log("接收到 WebSocket 消息2:", event.data); | |||
if (!event.data) { | |||
return; | |||
} | |||
if (event.data == "___talk_end___") { | |||
sendLoading.value = false; | |||
mySocket.close(); | |||
return; | |||
} | |||
answerContent.value = answerContent.value + event.data; | |||
}; | |||
mySocket.onclose = () => { | |||
console.log( | |||
"WebSocket 连接关闭3,关闭代码:", | |||
event.code, | |||
"关闭原因:", | |||
event.reason | |||
); | |||
console.log(mySocket.readyState, "链接状态3"); | |||
}; | |||
mySocket.onerror = (error) => { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `GPT服务器连接失败,请稍后重试!` | |||
: `GPT Server connection failed, please try again later` | |||
); | |||
sendLoading.value = false; | |||
mySocket.close(); | |||
console.error("WebSocket 错误4:", error); | |||
}; | |||
} | |||
const problemContent = ref(""); //问题输入框内容 | |||
const answerContent = ref(""); //回答输入框内容 | |||
// 点击发送需求 | |||
async function sendRequirement() { | |||
// loading | |||
sendLoading.value = true; | |||
// 无需求时 | |||
if (!problemContent.value) { | |||
sendLoading.value = false; | |||
mySocket.close(); | |||
return; | |||
} | |||
const sendMessage = [ | |||
{ | |||
role: "user", | |||
content: problemContent.value, | |||
}, | |||
]; | |||
// 如果处于链接状态 | |||
if (mySocket.readyState != WebSocket.OPEN) { | |||
createWS(); | |||
} else { | |||
answerContent.value = ""; | |||
mySocket.send(JSON.stringify(sendMessage)); | |||
} | |||
} | |||
// 复制到文案 | |||
function copyAnswerContent() { | |||
textareaContent.value = answerContent.value; | |||
document.getElementById("tab-0").click(); | |||
} | |||
//#endregion ---------------------------- | |||
//#region | |||
@@ -1547,6 +1800,7 @@ onMounted(async () => { | |||
if (route.query.id) { | |||
getModelDetailById(); | |||
} | |||
createWS(); | |||
}); | |||
</script> | |||
@@ -1570,6 +1824,171 @@ onMounted(async () => { | |||
width: 68%; | |||
height: 100%; | |||
padding: 20px; | |||
// 字幕盒子 | |||
.subtitlesBoxTop { | |||
z-index: 3; | |||
position: absolute; | |||
top: 50px; | |||
left: 225px; | |||
width: 700px; | |||
// height: 50px; | |||
background-color: #e9ecf1; | |||
border-radius: 20px; | |||
padding: 10px; | |||
box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
display: flex; | |||
justify-content: flex-start; | |||
align-content: flex-start; | |||
flex-wrap: wrap; | |||
.tab4Item { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 130px; | |||
background-color: rgba(71, 105, 218, 0.1); | |||
text-align: center; | |||
padding: 10px; | |||
height: 80px; | |||
border-radius: 10px; | |||
margin: auto; | |||
// margin-bottom: 10px; | |||
p { | |||
padding-bottom: 5px; | |||
} | |||
} | |||
.SubtitlesSwitch { | |||
width: 100%; | |||
.el-input-number--large { | |||
width: 100px; | |||
} | |||
.el-input-number__increase { | |||
width: none; | |||
} | |||
} | |||
.myColorBox { | |||
position: relative; | |||
width: 25px; | |||
height: 25px; | |||
margin: auto; | |||
border: #000 solid 2px; | |||
cursor: pointer; | |||
.selectColor { | |||
position: absolute; | |||
top: 150%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
display: flex; | |||
justify-content: flex-start; | |||
flex-wrap: wrap; | |||
width: 142px; | |||
background-color: #ffffff; | |||
z-index: 99; | |||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px; | |||
&::before { | |||
content: ""; | |||
display: block; | |||
position: absolute; | |||
top: -10%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
width: 0; | |||
height: 0; | |||
border-left: 15px solid transparent; | |||
border-right: 15px solid transparent; | |||
border-bottom: 15px solid white; | |||
} | |||
&-item { | |||
width: 25px; | |||
height: 25px; | |||
margin: 5px 5px; | |||
border: #000 solid 2px; | |||
border-radius: 5px; | |||
cursor: pointer; | |||
} | |||
} | |||
} | |||
} | |||
.subtitlesBoxLeft { | |||
z-index: 3; | |||
position: absolute; | |||
top: 150px; | |||
left: 150px; | |||
width: 150px; | |||
// height: 50px; | |||
background-color: #e9ecf1; | |||
border-radius: 20px; | |||
padding: 10px; | |||
box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
display: flex; | |||
justify-content: flex-start; | |||
align-content: flex-start; | |||
flex-wrap: wrap; | |||
.tab4Item { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 130px; | |||
background-color: rgba(71, 105, 218, 0.1); | |||
text-align: center; | |||
padding: 10px; | |||
height: 80px; | |||
border-radius: 10px; | |||
margin: auto; | |||
margin-bottom: 10px; | |||
p { | |||
padding-bottom: 5px; | |||
} | |||
} | |||
.SubtitlesSwitch { | |||
width: 100%; | |||
.el-input-number--large { | |||
width: 100px; | |||
} | |||
.el-input-number__increase { | |||
width: none; | |||
} | |||
} | |||
.myColorBox { | |||
position: relative; | |||
width: 25px; | |||
height: 25px; | |||
margin: auto; | |||
border: #000 solid 2px; | |||
cursor: pointer; | |||
.selectColor { | |||
position: absolute; | |||
top: 150%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
display: flex; | |||
justify-content: flex-start; | |||
flex-wrap: wrap; | |||
width: 142px; | |||
background-color: #ffffff; | |||
z-index: 99; | |||
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px; | |||
&::before { | |||
content: ""; | |||
display: block; | |||
position: absolute; | |||
top: -10%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
width: 0; | |||
height: 0; | |||
border-left: 15px solid transparent; | |||
border-right: 15px solid transparent; | |||
border-bottom: 15px solid white; | |||
} | |||
&-item { | |||
width: 25px; | |||
height: 25px; | |||
margin: 5px 5px; | |||
border: #000 solid 2px; | |||
border-radius: 5px; | |||
cursor: pointer; | |||
} | |||
} | |||
} | |||
} | |||
// 选择模版弹出框 | |||
.chooseModelBox { | |||
position: absolute; | |||
@@ -1917,10 +2336,72 @@ onMounted(async () => { | |||
} | |||
} | |||
.tab4 { | |||
display: flex; | |||
justify-content: flex-start; | |||
align-content: flex-start; | |||
flex-wrap: wrap; | |||
// display: flex; | |||
// justify-content: flex-start; | |||
// align-content: flex-start; | |||
// flex-wrap: wrap; | |||
.card4 { | |||
.text { | |||
padding: 10 px; | |||
border: 1px solid #c0c4cc; | |||
.el-button { | |||
float: right; | |||
margin-top: 10px; | |||
} | |||
:deep(.el-textarea__inner) { | |||
cursor: text; | |||
} | |||
:deep(.el-textarea__inner) { | |||
resize: none; | |||
box-shadow: none; | |||
} | |||
i { | |||
font-size: 14px; | |||
float: right; | |||
} | |||
} | |||
p { | |||
margin: 7px 0; | |||
} | |||
.card4Btn { | |||
margin-top: 10px; | |||
border-radius: 5px; | |||
height: 50px; | |||
width: 100%; | |||
color: #fff; | |||
background-color: #000; | |||
text-align: center; | |||
line-height: 50px; | |||
cursor: pointer; | |||
} | |||
.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: 26%; | |||
} | |||
:deep(.el-tabs__item:hover) { | |||
color: #909393; | |||
} | |||
:deep(.el-tabs__content) { | |||
height: calc(100% - 60px); | |||
padding: 0; | |||
} | |||
.tab4Item { | |||
display: flex; | |||
justify-content: space-between; | |||
@@ -1,22 +1,67 @@ | |||
<template> | |||
<div class="page"> | |||
<div class="title">{{ $t("API.comingSoon") }}</div> | |||
<!-- <div class="title">{{ $t("API.comingSoon") }}</div> --> | |||
<!-- 左侧名称 --> | |||
<div class="left"> | |||
<div class="scrollBox"> | |||
<p>啊实打实大</p> | |||
</div> | |||
</div> | |||
<!-- 右侧介绍 --> | |||
<div class="right"> | |||
<div class="scrollBox"></div> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
// import { ref } from 'vue' | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
padding: 30px; | |||
display: flex; | |||
width: 100%; | |||
overflow: hidden; | |||
overflow-y: scroll; | |||
background-color: #fff; | |||
background-color: #f5f5f5; | |||
border-radius: 25px 0 0 0; | |||
min-height: calc(100vh - 80px); | |||
text-align: center; | |||
// text-align: center; | |||
.title { | |||
font-size: 50px; | |||
} | |||
} | |||
.left { | |||
height: calc(100vh - 80px); | |||
width: 30%; | |||
padding: 30px 15px 30px 30px; | |||
font-size: 20px; | |||
background-color: #f5f5f5; | |||
.scrollBox { | |||
padding: 20px; | |||
height: calc(100vh - 80px - 60px); | |||
width: 100%; | |||
overflow-y: scroll; | |||
background-color: #fff; | |||
border-radius: 20px; | |||
box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
} | |||
} | |||
.right { | |||
height: calc(100vh - 80px); | |||
width: 80%; | |||
padding: 30px 30px 30px 15px; | |||
background-color: #f5f5f5; | |||
.scrollBox { | |||
padding: 20px; | |||
height: calc(100vh - 80px - 60px); | |||
width: 100%; | |||
overflow-y: scroll; | |||
background-color: #fff; | |||
border-radius: 20px; | |||
box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px; | |||
} | |||
} | |||
</style> |
@@ -481,6 +481,7 @@ const checkVideoStatus = async () => { | |||
// 如果列表中没有生成中的视频,不发送请求 | |||
const intervalId = setInterval(async () => { | |||
// && notGenerateList2.value.length == 0; | |||
console.log(""); | |||
if (notGenerateList.value.length == 0) { | |||
return; | |||
} | |||
@@ -509,7 +510,7 @@ onMounted(() => { | |||
isLoading.value = true; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
// checkVideoStatus(); | |||
checkVideoStatus(); | |||
}); | |||
//#endregion --------------------------- | |||
</script> | |||
@@ -180,33 +180,117 @@ | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 对话框 --> | |||
<el-dialog v-if="false" v-model="showPayDialog" width="60%" center> | |||
<!-- 对话框 v-if="false"--> | |||
<el-dialog v-model="showPayDialog" width="60%" center> | |||
<div class="payDialog"> | |||
<div class="left"> | |||
<div class="title">{{ $t(presentItme.value.title) }}</div> | |||
<div class="price"> | |||
<span>{{ presentItme.value.price }}</span> | |||
元/{{ presentItme.value.priceTime }} | |||
<!-- <div class="title">{{ $t(presentItme.value.title) }}</div> --> | |||
<div class="title">{{ $t(presentItme.value.typeDesc) }}</div> | |||
<div class="money"> | |||
<span class="price">{{ | |||
lanChange == "zh-cn" | |||
? presentItme.value.rmb + "¥" | |||
: presentItme.value.dollar + "$" | |||
}}</span | |||
>/{{ presentItme.value.validityDuration }}{{ $t("shop.day") }} | |||
</div> | |||
<div | |||
class="authority" | |||
v-for="item in presentItme.value.authority" | |||
:key="item" | |||
> | |||
{{ item }} | |||
<div class="time"> | |||
<span>{{ presentItme.value.credit }}</span | |||
>{{ $t("shop.score") }} | |||
</div> | |||
<!-- 套餐内容 --> | |||
<div class="authority"> | |||
<div class="authority-item"> | |||
{{ $t("shop.InviteGetscore") }}: | |||
<span> | |||
<i>{{ presentItme.value.inviteUserCredit }}</i | |||
>{{ $t("shop.score") }}</span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.createVideoPrice") }}:<span | |||
><i>{{ presentItme.value.videoPrice }}</i | |||
>{{ $t("shop.score") }}</span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratesPhotoPrices") }}:<span | |||
><i>{{ presentItme.value.photoPrice }}</i | |||
>{{ $t("shop.score") }}</span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.UnitChargeDuration") }}:<span | |||
><i>{{ presentItme.value.chargeTime }}</i | |||
>{{ $t("shop.second") }}</span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.Language") }}:<span | |||
><i>{{ | |||
presentItme.value.userPackageDetails[0].languageDesc | |||
}}</i></span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.sound") }}:<span | |||
><i>{{ | |||
presentItme.value.userPackageDetails[0].soundDesc | |||
}}</i></span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.IndividualVideoDuration") }}:<span | |||
><i>{{ presentItme.value.userPackageDetails[0].videoTime }}</i | |||
>{{ $t("shop.second") }}</span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.Watermark") }}:<span>{{ | |||
presentItme.value.userPackageDetails[0].aiPortrait == 0 | |||
? $t("shop.yes") | |||
: $t("shop.no") | |||
}}</span> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratedPortrait") }}:<span>{{ | |||
presentItme.value.userPackageDetails[0].aiPortrait == 0 | |||
? $t("shop.no") | |||
: $t("shop.yes") | |||
}}</span> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.PhotoSinging") }}:<span>{{ | |||
presentItme.value.userPackageDetails[0].photoSing == 0 | |||
? $t("shop.no") | |||
: $t("shop.yes") | |||
}}</span> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratedText") }}:<span | |||
><i>{{ | |||
presentItme.value.userPackageDetails[0].aiCreateTime | |||
}}</i></span | |||
> | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.VideoResolution") }}:<span>{{ | |||
presentItme.value.userPackageDetails[0].resolutionRatioDesc | |||
}}</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="right"> | |||
<div | |||
style="background-color: #07c160; cursor: pointer" | |||
@click="showOrderCode(1)" | |||
@click="showOrderCode(2)" | |||
> | |||
{{ $t("shop.WeChatPay") }} | |||
</div> | |||
<div | |||
style="background-color: #1378fe; cursor: pointer" | |||
@click="showOrderCode(2)" | |||
@click="showOrderCode(4)" | |||
> | |||
{{ $t("shop.Alipay") }} | |||
</div> | |||
@@ -224,15 +308,35 @@ | |||
width="30%" | |||
append-to-body | |||
destroy-on-close | |||
@closed="clearCode" | |||
:close-on-click-modal="false" | |||
> | |||
<div class="orderCodeDialog"> | |||
<div class="codeImg"> | |||
<my-Loading-Icon v-if="!orderCodeUrl"></my-Loading-Icon> | |||
<img v-if="orderCodeUrl" src="../../assets/img/false1.png" alt="" /> | |||
<my-Loading-Icon2 | |||
v-if="!payCodeUrl && !iframeBody" | |||
></my-Loading-Icon2> | |||
<!-- :callback="qrcode" --> | |||
<vue-qr v-if="payCodeUrl" :text="payCodeUrl" :size="280"></vue-qr> | |||
<iframe | |||
v-show="iframeBody" | |||
id="myIframe" | |||
width="305px" | |||
height="305px" | |||
frameborder="0" | |||
></iframe> | |||
</div> | |||
<div class="tips"> | |||
{{ | |||
lanChange == "zh-cn" | |||
? `扫描二维码进行付款` | |||
: `Scan the QR code for payment` | |||
}} | |||
</div> | |||
<div class="tips">扫描二维码进行付款</div> | |||
<div class="btnBox"> | |||
<div>刷新二维码</div> | |||
<div @click="RefreshQR"> | |||
{{ lanChange == "zh-cn" ? `刷新二维码` : `Refresh QR code` }} | |||
</div> | |||
</div> | |||
</div> | |||
</el-dialog> | |||
@@ -249,10 +353,13 @@ | |||
<script setup> | |||
//#region 导入 | |||
import { getCurrentInstance, ref, onMounted } from "vue"; | |||
// import { packageInfoApi } from "@/apis/myStore"; | |||
import { packageInfoApi } from "@/apis/myStore"; | |||
import { useI18n } from "vue-i18n"; | |||
import talkUs from "@/components/talkUs.vue"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import { createOrderApi, createPayApi, getOrderStatusApi } from "@/apis/pay"; | |||
import vueQr from "vue-qr/src/packages/vue-qr.vue"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const { locale } = useI18n(); | |||
@@ -262,220 +369,225 @@ const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登 | |||
//#endregion ------------------------------------ | |||
//#region 各个套餐的逻辑 | |||
const packageList = ref([ | |||
{ | |||
id: 1, | |||
type: 1, | |||
typeDesc: "基础版", | |||
englishName: "Trial", | |||
dollar: "0.00", | |||
rmb: "0.00", | |||
credit: 100, | |||
validityDuration: 30, | |||
inviteUserCredit: 10, | |||
videoPrice: 10, | |||
photoPrice: 10, | |||
talkPrice: 20, | |||
chargeTime: 60, | |||
createDate: 1686814258000, | |||
updateDate: 1686814258000, | |||
isDel: 0, | |||
color: "#f3af00", | |||
userPackageDetails: [ | |||
{ | |||
id: 1, | |||
detailType: 1, | |||
detailTypeDesc: "照片说话", | |||
packageId: 1, | |||
watermark: 1, | |||
watermarkDesc: "是", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 60, | |||
aiPortrait: 0, | |||
aiPortraitDesc: "否", | |||
photoSing: 0, | |||
photoSingDesc: "否", | |||
aiCreateTime: 0, | |||
resolutionRatio: 1, | |||
resolutionRatioDesc: "720p", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
{ | |||
id: 4, | |||
detailType: 2, | |||
detailTypeDesc: "口播", | |||
packageId: 1, | |||
watermark: 1, | |||
watermarkDesc: "是", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 60, | |||
aiCreateTime: 0, | |||
resolutionRatio: 1, | |||
resolutionRatioDesc: "720p", | |||
humanTemplate: 1, | |||
humanTemplateDesc: "免费", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
], | |||
}, | |||
{ | |||
id: 2, | |||
type: 2, | |||
typeDesc: "专业版", | |||
englishName: "Pro", | |||
dollar: "7.99", | |||
rmb: "49.99", | |||
credit: 200, | |||
validityDuration: 30, | |||
inviteUserCredit: 10, | |||
videoPrice: 6, | |||
photoPrice: 6, | |||
talkPrice: 16, | |||
chargeTime: 60, | |||
createDate: 1686814258000, | |||
updateDate: 1686814258000, | |||
isDel: 0, | |||
color: "#c971ff", | |||
userPackageDetails: [ | |||
{ | |||
id: 2, | |||
detailType: 1, | |||
detailTypeDesc: "照片说话", | |||
packageId: 2, | |||
watermark: 0, | |||
watermarkDesc: "否", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 300, | |||
aiPortrait: 1, | |||
aiPortraitDesc: "是", | |||
photoSing: 1, | |||
photoSingDesc: "是", | |||
aiCreateTime: 30, | |||
resolutionRatio: 2, | |||
resolutionRatioDesc: "1080p", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
{ | |||
id: 5, | |||
detailType: 2, | |||
detailTypeDesc: "口播", | |||
packageId: 2, | |||
watermark: 0, | |||
watermarkDesc: "否", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 300, | |||
aiCreateTime: 100, | |||
resolutionRatio: 2, | |||
resolutionRatioDesc: "1080p", | |||
humanTemplate: 2, | |||
humanTemplateDesc: "VIP", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
], | |||
}, | |||
{ | |||
id: 3, | |||
type: 3, | |||
typeDesc: "加强版", | |||
englishName: "Advanced", | |||
dollar: "39.99", | |||
rmb: "279.99", | |||
credit: 1200, | |||
validityDuration: 30, | |||
inviteUserCredit: 10, | |||
videoPrice: 5, | |||
photoPrice: 5, | |||
talkPrice: 15, | |||
chargeTime: 60, | |||
createDate: 1686814258000, | |||
updateDate: 1686814258000, | |||
isDel: 0, | |||
color: "#7b61ff", | |||
userPackageDetails: [ | |||
{ | |||
id: 3, | |||
detailType: 1, | |||
detailTypeDesc: "照片说话", | |||
packageId: 3, | |||
watermark: 0, | |||
watermarkDesc: "否", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 300, | |||
aiPortrait: 1, | |||
aiPortraitDesc: "是", | |||
photoSing: 1, | |||
photoSingDesc: "是", | |||
aiCreateTime: 200, | |||
resolutionRatio: 2, | |||
resolutionRatioDesc: "1080p", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
{ | |||
id: 6, | |||
detailType: 2, | |||
detailTypeDesc: "口播", | |||
packageId: 3, | |||
watermark: 0, | |||
watermarkDesc: "否", | |||
language: 1, | |||
languageDesc: "50+", | |||
sound: 1, | |||
soundDesc: "400+", | |||
videoTime: 300, | |||
aiCreateTime: 200, | |||
resolutionRatio: 2, | |||
resolutionRatioDesc: "1080p", | |||
humanTemplate: 2, | |||
humanTemplateDesc: "VIP", | |||
createDate: 1686882177000, | |||
updateDate: 1686882177000, | |||
isDel: 0, | |||
}, | |||
], | |||
}, | |||
]); | |||
// const packageList = ref([ | |||
// { | |||
// id: 1, | |||
// type: 1, | |||
// typeDesc: "基础版", | |||
// englishName: "Trial", | |||
// dollar: "0.00", | |||
// rmb: "0.00", | |||
// credit: 100, | |||
// validityDuration: 30, | |||
// inviteUserCredit: 10, | |||
// videoPrice: 10, | |||
// photoPrice: 10, | |||
// talkPrice: 20, | |||
// chargeTime: 60, | |||
// createDate: 1686814258000, | |||
// updateDate: 1686814258000, | |||
// isDel: 0, | |||
// color: "#f3af00", | |||
// userPackageDetails: [ | |||
// { | |||
// id: 1, | |||
// detailType: 1, | |||
// detailTypeDesc: "照片说话", | |||
// packageId: 1, | |||
// watermark: 1, | |||
// watermarkDesc: "是", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 60, | |||
// aiPortrait: 0, | |||
// aiPortraitDesc: "否", | |||
// photoSing: 0, | |||
// photoSingDesc: "否", | |||
// aiCreateTime: 0, | |||
// resolutionRatio: 1, | |||
// resolutionRatioDesc: "720p", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// { | |||
// id: 4, | |||
// detailType: 2, | |||
// detailTypeDesc: "口播", | |||
// packageId: 1, | |||
// watermark: 1, | |||
// watermarkDesc: "是", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 60, | |||
// aiCreateTime: 0, | |||
// resolutionRatio: 1, | |||
// resolutionRatioDesc: "720p", | |||
// humanTemplate: 1, | |||
// humanTemplateDesc: "免费", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// ], | |||
// }, | |||
// { | |||
// id: 2, | |||
// type: 2, | |||
// typeDesc: "专业版", | |||
// englishName: "Pro", | |||
// dollar: "7.99", | |||
// rmb: "49.99", | |||
// credit: 200, | |||
// validityDuration: 30, | |||
// inviteUserCredit: 10, | |||
// videoPrice: 6, | |||
// photoPrice: 6, | |||
// talkPrice: 16, | |||
// chargeTime: 60, | |||
// createDate: 1686814258000, | |||
// updateDate: 1686814258000, | |||
// isDel: 0, | |||
// color: "#c971ff", | |||
// userPackageDetails: [ | |||
// { | |||
// id: 2, | |||
// detailType: 1, | |||
// detailTypeDesc: "照片说话", | |||
// packageId: 2, | |||
// watermark: 0, | |||
// watermarkDesc: "否", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 300, | |||
// aiPortrait: 1, | |||
// aiPortraitDesc: "是", | |||
// photoSing: 1, | |||
// photoSingDesc: "是", | |||
// aiCreateTime: 30, | |||
// resolutionRatio: 2, | |||
// resolutionRatioDesc: "1080p", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// { | |||
// id: 5, | |||
// detailType: 2, | |||
// detailTypeDesc: "口播", | |||
// packageId: 2, | |||
// watermark: 0, | |||
// watermarkDesc: "否", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 300, | |||
// aiCreateTime: 100, | |||
// resolutionRatio: 2, | |||
// resolutionRatioDesc: "1080p", | |||
// humanTemplate: 2, | |||
// humanTemplateDesc: "VIP", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// ], | |||
// }, | |||
// { | |||
// id: 3, | |||
// type: 3, | |||
// typeDesc: "加强版", | |||
// englishName: "Advanced", | |||
// dollar: "39.99", | |||
// rmb: "279.99", | |||
// credit: 1200, | |||
// validityDuration: 30, | |||
// inviteUserCredit: 10, | |||
// videoPrice: 5, | |||
// photoPrice: 5, | |||
// talkPrice: 15, | |||
// chargeTime: 60, | |||
// createDate: 1686814258000, | |||
// updateDate: 1686814258000, | |||
// isDel: 0, | |||
// color: "#7b61ff", | |||
// userPackageDetails: [ | |||
// { | |||
// id: 3, | |||
// detailType: 1, | |||
// detailTypeDesc: "照片说话", | |||
// packageId: 3, | |||
// watermark: 0, | |||
// watermarkDesc: "否", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 300, | |||
// aiPortrait: 1, | |||
// aiPortraitDesc: "是", | |||
// photoSing: 1, | |||
// photoSingDesc: "是", | |||
// aiCreateTime: 200, | |||
// resolutionRatio: 2, | |||
// resolutionRatioDesc: "1080p", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// { | |||
// id: 6, | |||
// detailType: 2, | |||
// detailTypeDesc: "口播", | |||
// packageId: 3, | |||
// watermark: 0, | |||
// watermarkDesc: "否", | |||
// language: 1, | |||
// languageDesc: "50+", | |||
// sound: 1, | |||
// soundDesc: "400+", | |||
// videoTime: 300, | |||
// aiCreateTime: 200, | |||
// resolutionRatio: 2, | |||
// resolutionRatioDesc: "1080p", | |||
// humanTemplate: 2, | |||
// humanTemplateDesc: "VIP", | |||
// createDate: 1686882177000, | |||
// updateDate: 1686882177000, | |||
// isDel: 0, | |||
// }, | |||
// ], | |||
// }, | |||
// ]); | |||
const packageList = ref([]); | |||
async function getPackageList() { | |||
const res = await packageInfoApi(); | |||
packageList.value = res.data; | |||
} | |||
const showPayDialog = ref(false); //套餐信息dialog显示隐藏 | |||
const presentItme = reactive({}); //点击的套餐项 | |||
// const presentItme = ref({}); //点击的套餐项 | |||
function clickPayDialog(item) { | |||
presentItme.value = item; | |||
showPayDialog.value = true; | |||
} | |||
function showOrderCode(type) { | |||
orderCodeDialogShow.value = true; | |||
} | |||
//#endregion ------------------------------------ | |||
//#region 点击套餐内的支付 | |||
function showOrderCode(type) { | |||
orderCodeDialogShow.value = true; | |||
myPayVendor.value = type; | |||
createOrderFunc(); | |||
} | |||
const orderCodeDialogShow = ref(false); | |||
const orderCodeUrl = ref(null); | |||
//#endregion ------------------------------------ | |||
@@ -517,12 +629,127 @@ const updateShowTalkUsDialog = (newValue) => { | |||
//#region 页面初始化 | |||
onMounted(async () => { | |||
// getPackageList(); | |||
getPackageList(); | |||
// createOrderFunc(); | |||
}); | |||
//#endregion ------------------------------------ | |||
//#region | |||
//#region 支付 | |||
const myPayVendor = ref(null); // 2微信 4支付宝 | |||
const payCodeUrl = ref(null); //付款二维码地址 | |||
const payCodeImg = ref(null); //付款二维码图片 | |||
// 支付失败处理 | |||
function payErrorHandle() { | |||
orderCodeDialogShow.value = false; | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `获取订单失败,请重试` | |||
: `Failed to get the order, please try again` | |||
); | |||
} | |||
// 获取订单 | |||
const myOrderNumber = ref(null); //订单号 | |||
async function createOrderFunc() { | |||
const data = { | |||
productId: 30, | |||
}; | |||
try { | |||
const res = await createOrderApi(data); | |||
if (res.code == 200) { | |||
myOrderNumber.value = res.data; | |||
createPayFunc(res.data); | |||
} else { | |||
payErrorHandle(); | |||
} | |||
} catch (error) { | |||
payErrorHandle(); | |||
} | |||
} | |||
// 获取订单详情 | |||
let iframeBody = ref(null); | |||
const iframeDom = ref(null); | |||
async function createPayFunc(orderNumber) { | |||
const data = { | |||
orderNumber, | |||
payVendor: myPayVendor.value, | |||
}; | |||
try { | |||
const res = await createPayApi(data); | |||
if (res.code == 200) { | |||
// 支付宝获取iframe内容 | |||
if (res.data.body) { | |||
iframeBody.value = res.data.body; | |||
iframeDom.value = document.getElementById("myIframe"); | |||
iframeDom.value.srcdoc = iframeBody.value; | |||
} | |||
// 直接获取二维码 | |||
if (res.data.codeUrl) { | |||
payCodeUrl.value = res.data.codeUrl; | |||
} | |||
await getStatusOfOrderFunc(orderNumber); | |||
} else { | |||
payErrorHandle(); | |||
} | |||
} catch (error) { | |||
payErrorHandle(); | |||
} | |||
} | |||
// 获取订单支付状态 payStatus 查询支付状态 0:待支付,2:支付中,3:已支付 | |||
async function getStatusOfOrderFunc(orderNumber) { | |||
if ( | |||
route.path != "/myStore" || | |||
orderCodeDialogShow.value == false || | |||
orderNumber != myOrderNumber.value | |||
) { | |||
return; | |||
} | |||
try { | |||
let payVendor = myPayVendor.value; | |||
const res = await getOrderStatusApi(orderNumber, payVendor); | |||
if (res.code == 200) { | |||
if (res.data.orderStatus == 3) { | |||
orderCodeDialogShow.value = false; | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" ? `支付成功!` : `Payment is successful!` | |||
); | |||
return; | |||
} else { | |||
setTimeout(() => { | |||
getStatusOfOrderFunc(orderNumber); | |||
}, 3000); | |||
} | |||
} else { | |||
setTimeout(() => { | |||
getStatusOfOrderFunc(orderNumber); | |||
}, 3000); | |||
} | |||
} catch (error) { | |||
console.log(error, "error"); | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `获取订单失败,请重试` | |||
: `Failed to get the order, please try again` | |||
); | |||
} | |||
} | |||
// 生成二维码 | |||
// function qrcode() { | |||
// return; | |||
// } | |||
// 关闭二维码弹窗 | |||
function clearCode() { | |||
myPayVendor.value = null; // 2微信 4支付宝 | |||
payCodeUrl.value = null; | |||
iframeBody.value = null; | |||
} | |||
// 刷新二维码 | |||
function RefreshQR() { | |||
payCodeUrl.value = null; | |||
iframeBody.value = null; | |||
// createOrderFunc(); | |||
createPayFunc(myOrderNumber.value); | |||
} | |||
//#endregion ------------------------------------ | |||
//#region | |||
@@ -742,7 +969,8 @@ onMounted(async () => { | |||
font-size: 30px; | |||
text-align: center; | |||
} | |||
.price { | |||
.money { | |||
text-align: center; | |||
span { | |||
font-size: 30px; | |||
font-weight: 700; | |||
@@ -750,7 +978,40 @@ onMounted(async () => { | |||
} | |||
} | |||
.authority { | |||
padding: 10px 20px; | |||
margin-top: 10px; | |||
&-item { | |||
display: flex; | |||
justify-content: space-between; | |||
cursor: pointer; | |||
font-weight: 400; | |||
font-size: 14px; | |||
padding: 2px 3px; | |||
color: #7c7c7a; | |||
span { | |||
cursor: pointer; | |||
color: #7c7c7a; | |||
margin-right: 30px; | |||
} | |||
i { | |||
font-size: 20px; | |||
font-style: normal; | |||
margin-right: 5px; | |||
background-image: -webkit-linear-gradient( | |||
left, | |||
#4b61dc, | |||
#15d1b8 25%, | |||
#4b61dc 50%, | |||
#15d1b8 75%, | |||
#4b61dc | |||
) !important; | |||
-webkit-text-fill-color: transparent !important; | |||
-webkit-background-clip: text !important; | |||
background-clip: text !important; | |||
-webkit-background-size: 200% 100% !important; | |||
background-size: 200% 100% !important; | |||
} | |||
} | |||
} | |||
} | |||
.right { | |||
@@ -779,8 +1040,8 @@ onMounted(async () => { | |||
margin: auto; | |||
justify-content: space-evenly; | |||
align-items: center; | |||
width: 300px; | |||
height: 300px; | |||
width: 350px; | |||
height: 350px; | |||
border: 1px solid #ccc; | |||
border-radius: 15px; | |||
overflow: hidden; | |||
@@ -0,0 +1,944 @@ | |||
<template> | |||
<div class="page"> | |||
<!-- 搜索框 --> | |||
<div class="top"> | |||
<div class="search"> | |||
<el-input | |||
style="width: 300px" | |||
v-model="title" | |||
:placeholder="$t('myCreating.search')" | |||
@keyup.enter="searchVideoList" | |||
/> | |||
<el-icon class="icon-edit" @click="searchVideoList" | |||
><i-ep-search | |||
/></el-icon> | |||
<!-- 重置按钮 --> | |||
<div v-show="title" class="resetSearch" @click="resetSearch"> | |||
{{ $t("myCreating.reset") }} | |||
</div> | |||
</div> | |||
<!-- 更新视频提示 --> | |||
<div class="hasNewVideoTips" :class="hasNewCreate ? '' : 'hasNew'"> | |||
{{ $t("myCreating.hasNewVideo") }} | |||
</div> | |||
</div> | |||
<!-- 作品列表 --> | |||
<div v-if="!isLoading"> | |||
<div v-if="videoList.length > 0" class="workList flex"> | |||
<div class="workItem" v-for="item in videoList" :key="item.id"> | |||
<div class="workImg"> | |||
<img | |||
v-if="item.coverImg" | |||
class="coverImg inmiddle" | |||
:src="item.coverImg" | |||
alt="" | |||
/> | |||
<img | |||
v-else | |||
class="takePlace inmiddle" | |||
src="@/assets/img/left-top-logo.png" | |||
alt="" | |||
/> | |||
</div> | |||
<div :class="'statusName ' + item.statusName"> | |||
{{ $t("myCreating." + item.statusName) }} | |||
</div> | |||
<div class="workInfo flex"> | |||
<span>{{ item.title }}</span> | |||
<span>{{ dayjs(item.createDate).format("YYYY-MM-DD") }}</span> | |||
</div> | |||
<!-- 更多遮罩层 --> | |||
<div | |||
class="more" | |||
@mouseleave="mouseleave" | |||
@click="clickVideoItem(item)" | |||
> | |||
<el-icon | |||
v-if="[0].includes(item.videoStatus)" | |||
class="icon-videoPlay" | |||
><i-ep-edit | |||
/></el-icon> | |||
<el-icon | |||
v-if="[1, 2, 4, 6].includes(item.videoStatus)" | |||
class="icon-videoPlay" | |||
><i-ep-loading | |||
/></el-icon> | |||
<el-icon | |||
v-if="[3].includes(item.videoStatus)" | |||
class="icon-videoPlay" | |||
><i-ep-closeBold | |||
/></el-icon> | |||
<el-icon | |||
v-if="[5, 7, 8, 9, 10, 11, 12].includes(item.videoStatus)" | |||
class="icon-videoPlay" | |||
><i-ep-videoPlay | |||
/></el-icon> | |||
<div class="showBtn" @click.stop="mouseenter(item)">...</div> | |||
<div class="btns" v-show="showPopup"> | |||
<!-- 下载按钮 --> | |||
<div | |||
class="btns-item" | |||
@click.stop="handleDownload(item.videoPlayUrl, item.title)" | |||
> | |||
<div class="btns-item-icon"> | |||
<el-icon class="icon-delete"><i-ep-download /></el-icon> | |||
</div> | |||
<div class="text">{{ $t("myCreating.download") }}</div> | |||
</div> | |||
<!-- 删除按钮 --> | |||
<div | |||
class="btns-item" | |||
@click.stop="handelDelete(item.id, item.title)" | |||
> | |||
<div class="btns-item-icon"> | |||
<el-icon class="icon-delete"><i-ep-delete /></el-icon> | |||
</div> | |||
<div class="text">{{ $t("myCreating.delete") }}</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-if="videoList.length == 0" class="noList"> | |||
<div class="title"> | |||
{{ $t("myCreating.noList") }} | |||
</div> | |||
<div class="goCreate" @click="goCreate"> | |||
{{ $t("myCreating.goCreate") }} | |||
</div> | |||
</div> | |||
</div> | |||
<div v-if="isLoading" class="loadingIcon"> | |||
<el-icon class="is-loading"> | |||
<svg | |||
viewBox="0 0 1024 1024" | |||
xmlns="http://www.w3.org/2000/svg" | |||
data-v-ea893728="" | |||
> | |||
<path | |||
fill="currentColor" | |||
d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||
></path> | |||
</svg> | |||
</el-icon> | |||
<span class="loadingText">{{ $t("myCreating.loading") }}</span> | |||
</div> | |||
<!-- 弹出框预览作品 --> | |||
<el-dialog | |||
destroy-on-close | |||
class="elDialog" | |||
v-model="showDialog" | |||
:title="presentItem.title" | |||
width="40%" | |||
center | |||
> | |||
<div class="videoBox"> | |||
<!-- 免费用户1分钟 [5].includes(presentItem.videoStatus)--> | |||
<div | |||
v-if="presentItem.videoPlayUrl && presentItem.videoTime > 300" | |||
class="overtimeTips" | |||
> | |||
<img src="../../assets/img/tips.png" alt="" /> | |||
{{ $t("myCreating.freeUserTip") }} | |||
</div> | |||
<video | |||
v-if="presentItem.videoPlayUrl" | |||
controls="true" | |||
class="" | |||
:src="presentItem.videoPlayUrl" | |||
></video> | |||
<div v-else class="insteadVideo"> | |||
{{ $t("myCreating." + presentItem.statusName + "Text") }} | |||
<p v-if="lanChange == 'zh-cn' && presentItem.videoStatus == 3"> | |||
错误原因: {{ presentItem.videoMsg }} | |||
</p> | |||
<p v-if="lanChange == 'en' && presentItem.videoStatus == 3"> | |||
Error cause: {{ presentItem.videoMsg }} | |||
</p> | |||
<!-- <span v-if="presentItem.videoStatus == 3">{{ | |||
presentItem.videoMsg | |||
}}</span> --> | |||
</div> | |||
<!-- 有视频路径的页脚 --> | |||
<div class="footer" v-if="presentItem.videoPlayUrl"> | |||
<span class="dialog-footer"> | |||
<!-- dialog下载按钮 upGrades--> | |||
<button | |||
class="elBtn" | |||
type="primary" | |||
@click.stop=" | |||
handleDownload(presentItem.videoPlayUrl, presentItem.title) | |||
" | |||
> | |||
<!-- <el-icon class="icon-delete"><i-ep-download /></el-icon> --> | |||
{{ $t("myCreating.download") }} | |||
</button> | |||
<!-- 提升画质 v-if="presentItem.isHy == 0"--> | |||
<el-tooltip | |||
style="cursor: pointer" | |||
v-if="false" | |||
class="box-item" | |||
effect="light" | |||
:content="$t('myCreating.upSharpnessTips')" | |||
placement="top" | |||
> | |||
<button | |||
style="cursor: pointer" | |||
v-if="presentItem.isHy == 0" | |||
class="elBtn upSharpness" | |||
@click.stop="upGrades(presentItem.id)" | |||
> | |||
<div v-if="!upGradesLoading" style="cursor: pointer"> | |||
<img src="../../assets/img/Upgrades.png" alt="" /> | |||
{{ $t("myCreating.upSharpness") }} | |||
</div> | |||
<div v-if="upGradesLoading"> | |||
<!-- <my-Loading-Icon | |||
class="previewAudioLoadingBox" | |||
v-if="!upGradesLoading" | |||
></my-Loading-Icon> --> | |||
<el-icon class="is-loading" style="font-size: 16px" | |||
><i-ep-Loading | |||
/></el-icon> | |||
</div> | |||
</button> | |||
</el-tooltip> | |||
<!-- dialog删除按钮 --> | |||
<button | |||
class="elBtn" | |||
@click.stop="handelDelete(presentItem.id, presentItem.title)" | |||
> | |||
<!-- <el-icon class="icon-delete"><i-ep-delete /></el-icon> --> | |||
{{ $t("myCreating.delete") }} | |||
</button> | |||
</span> | |||
</div> | |||
<!-- 无视频路径的页脚 --> | |||
<div class="footer" v-if="!presentItem.videoPlayUrl"> | |||
<span class="dialog-footer"> | |||
<!-- dialog编辑按钮 --> | |||
<button | |||
class="elBtn" | |||
type="primary" | |||
@click.stop=" | |||
router.push({ | |||
path: '/createVideo', | |||
query: { id: presentItem.id }, | |||
}) | |||
" | |||
v-if="[0, 3].includes(presentItem.videoStatus)" | |||
> | |||
{{ $t("myCreating.edit") }} | |||
</button> | |||
</span> | |||
</div> | |||
</div> | |||
</el-dialog> | |||
<!-- 分页 --> | |||
<div v-if="!isLoading" class="pagination"> | |||
<el-pagination | |||
v-model:current-page="pageNum" | |||
v-model:page-size="pageSize" | |||
:page-sizes="[12, 24, 36]" | |||
:small="false" | |||
:disabled="false" | |||
:background="true" | |||
layout="total, sizes, prev, pager, next, jumper" | |||
:total="total" | |||
@size-change="handleSizeChange" | |||
@current-change="handleCurrentChange" | |||
/> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
//#region 导入 | |||
import { | |||
userPhotoVideoListApi, | |||
delUserPhotoVideoByIDApi, | |||
videoHyApi, | |||
checkVideoStatusApi, | |||
} from "@/apis/myCreating"; | |||
import { timestampToTime } from "@/utils/tools"; | |||
import { useI18n } from "vue-i18n"; | |||
import { getStatus } from "./videoStatus"; | |||
import { useRouter } from "vue-router"; | |||
import dayjs from "dayjs"; | |||
//#endregion ---------------------- | |||
const router = useRouter(); | |||
// 当前语言状态与国际化组件 | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
//#region 老页面逻辑 | |||
const title = ref(""); | |||
const pageNum = ref(1); | |||
const pageSize = ref(12); | |||
const total = ref(0); | |||
// 弹窗显示隐藏 | |||
const showDialog = ref(false); | |||
const isLoading = ref(true); | |||
// 当前作品 | |||
const presentItem = ref(""); | |||
// 作品列表 | |||
const videoList = ref([]); | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
}; | |||
// 点击作品 | |||
function clickVideoItem(item) { | |||
showDialog.value = true; | |||
presentItem.value = item; | |||
} | |||
// 删除框是否显示 | |||
let showPopup = ref(false); | |||
function mouseleave() { | |||
showPopup.value = false; | |||
} | |||
function mouseenter(item) { | |||
presentItem.value = item; | |||
showPopup.value = !showPopup.value; | |||
} | |||
// 下载 | |||
function handleDownload(itemVideoPlayUrl, name) { | |||
if (itemVideoPlayUrl) { | |||
console.log(1); | |||
let a = document.createElement("a"); | |||
a.download = `${name}.mp4`; | |||
a.href = itemVideoPlayUrl; | |||
// 设置下载文件名 | |||
a.style.display = "none"; | |||
document.body.appendChild(a); | |||
a.click(); | |||
a.remove(); | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" ? `下载成功` : `Download Successfully` | |||
); | |||
} else { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" ? `无法下载` : `Unable to download` | |||
); | |||
} | |||
} | |||
function goCreate() { | |||
router.push("/createVideo"); | |||
} | |||
function resetSearch(params) { | |||
title.value = ""; | |||
searchVideoList(); | |||
} | |||
// 搜索 | |||
function searchVideoList() { | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value, true); | |||
} | |||
// 删除 | |||
function handelDelete(id, title) { | |||
const msg = | |||
lanChange.value == "zh-cn" | |||
? `确定要删除这个作品吗? 作品标题:${title}` | |||
: `Are you sure to delete this video ? Title:${title};`; | |||
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(() => { | |||
delPhotoVideo(id); | |||
}); | |||
} | |||
// 升级画质 | |||
const upGradesLoading = ref(false); | |||
function upGrades(id) { | |||
if (upGradesLoading.value == true) { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `正在升级,请稍后~` | |||
: `Upgrading, please wait ~` | |||
); | |||
return; | |||
} | |||
const msg = | |||
lanChange.value == "zh-cn" | |||
? `确定要升级该作品吗?` | |||
: `Are you sure you want to upgrade this work?`; | |||
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 () => { | |||
upGradesLoading.value = true; | |||
try { | |||
const res = await videoHyApi(id); | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" | |||
? `升级中!请稍等~` | |||
: `Upgrading! Please wait a moment` | |||
); | |||
showDialog.value = false; | |||
upGradesLoading.value = false; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
} catch (error) { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `升级失败,请稍后重试` | |||
: `Upgrade failed, please try again later` | |||
); | |||
upGradesLoading.value = false; | |||
} | |||
}); | |||
} | |||
/** | |||
* @description:获取我的视频作品 | |||
* @return: data | |||
*/ | |||
function getPhotoVideoList(pageNum, pageSize, title, searchFlag) { | |||
userPhotoVideoListApi(pageNum, pageSize, title) | |||
.then((res) => { | |||
console.log(res, "res"); | |||
notGenerateList.value = []; | |||
// 找到数组中未生成的,放入列表,为了刷新 | |||
res.data.list.forEach((item) => { | |||
if ([1, 2, 4, 6, 7, 8, 10, 12].includes(item.videoStatus)) { | |||
notGenerateList.value.push(item.id); | |||
} | |||
}); | |||
res.data.list.forEach((item) => { | |||
// item.createDate = timestampToTime(item.createDate) || ""; | |||
// item.updateDate = timestampToTime(item.updateDate) || ""; | |||
// item.createVideoDate = timestampToTime(item.createVideoDate) || ""; | |||
item.statusName = getStatus(item.videoStatus); | |||
}); | |||
videoList.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
if (searchFlag) { | |||
const total = res.data.total; | |||
const msg1 = | |||
lanChange.value == "zh-cn" | |||
? `查询成功!找到${total}条符合条件的视频` | |||
: `Found! Match ${total} videos`; | |||
const msg2 = | |||
lanChange.value == "zh-cn" | |||
? `查询成功!没有符合条件的视频` | |||
: `Found! No match videos`; | |||
const msg3 = | |||
lanChange.value == "zh-cn" | |||
? `查询成功!已加载全部视频` | |||
: `Found! Present all videos`; | |||
return title | |||
? ElMessage.success(total > 0 ? msg1 : msg2) | |||
: ElMessage.success(msg3); | |||
} | |||
isLoading.value = false; | |||
}) | |||
.catch((err) => { | |||
console.log(err, "err"); | |||
}); | |||
} | |||
/** | |||
* @description:删除视频作品 | |||
* @param: videoID | |||
* @return: data | |||
*/ | |||
function delPhotoVideo(videoID) { | |||
delUserPhotoVideoByIDApi(videoID) | |||
.then((res) => { | |||
console.log(res, "res"); | |||
const msg = lanChange.value == "zh-cn" ? `删除成功!` : `Success !`; | |||
ElMessage.success(msg); | |||
showDialog.value = false; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
}) | |||
.catch((err) => { | |||
console.log(err, "err"); | |||
ElMessage.error(err.message); | |||
}); | |||
} | |||
//#endregion ---------------------- | |||
//#region 定时刷新 | |||
const hasNewCreate = ref(false); //提示框显示隐藏 | |||
const notGenerateList = ref([]); //页面上未生成的视频的id 普通视频 | |||
const notGenerateList2 = ref([]); //页面上未生成的视频的id 升级视频 | |||
const checkVideoStatus = async () => { | |||
// 如果列表中没有生成中的视频,不发送请求 | |||
const intervalId = setInterval(async () => { | |||
// && notGenerateList2.value.length == 0; | |||
console.log(""); | |||
if (notGenerateList.value.length == 0) { | |||
return; | |||
} | |||
try { | |||
const res = await checkVideoStatusApi(notGenerateList.value); | |||
// 如果有新的,则提示且更新列表 | |||
if (res.code != 2115) { | |||
hasNewCreate.value = true; | |||
const changeHasNewCreate = setTimeout(() => { | |||
hasNewCreate.value = false; | |||
}, 5000); | |||
notGenerateList.value = []; | |||
// notGenerateList2.value = []; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
} | |||
} catch (error) {} | |||
}, 3000); | |||
onUnmounted(() => { | |||
clearInterval(intervalId); | |||
}); | |||
}; | |||
//#endregion --------------------------- | |||
//#region 页面初始化 | |||
onMounted(() => { | |||
isLoading.value = true; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
// checkVideoStatus(); | |||
}); | |||
//#endregion --------------------------- | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
position: relative; | |||
height: calc(100vh - 80px); | |||
padding: 15px 130px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
width: 100%; | |||
overflow: hidden; | |||
overflow-y: auto; | |||
.top { | |||
position: relative; | |||
margin-bottom: 35px; | |||
.search { | |||
display: flex; | |||
justify-content: flex-start; | |||
.resetSearch { | |||
margin-left: 10px; | |||
padding: 0 10px; | |||
height: 30px; | |||
width: 100px; | |||
text-align: center; | |||
line-height: 30px; | |||
background-color: #000; | |||
border: 1px solid #000; | |||
border-radius: 15px; | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
color: #fff; | |||
&:hover { | |||
background-color: #fff; | |||
color: #000; | |||
} | |||
} | |||
} | |||
.hasNewVideoTips { | |||
position: absolute; | |||
top: 0; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
width: 400px; | |||
padding: 5px 30px; | |||
color: #fff; | |||
background-color: #000; | |||
text-align: center; | |||
font-size: 20px; | |||
transition: all 0.5s; | |||
opacity: 1; | |||
border-radius: 15px; | |||
} | |||
.hasNew { | |||
opacity: 0; | |||
transition: all 0.5s; | |||
} | |||
} | |||
.loadingIcon { | |||
height: 100px; | |||
line-height: 100px; | |||
text-align: center; | |||
transform: scale(2); | |||
.loadingText { | |||
position: relative; | |||
top: -2px; | |||
left: 4px; | |||
} | |||
} | |||
.workList { | |||
flex-wrap: wrap; | |||
justify-content: flex-start; | |||
width: 100%; | |||
// height: 200px; | |||
margin-top: 5px; | |||
padding-bottom: 50px; | |||
.workItem { | |||
position: relative; | |||
width: 300px; | |||
// height: 200px; | |||
margin: 0 20px 20px 0; | |||
border: 2px solid #c2c2c2; | |||
border-radius: 15px; | |||
cursor: pointer; | |||
overflow: hidden; | |||
.workImg { | |||
position: relative; | |||
width: 100%; | |||
height: 170px; | |||
cursor: pointer; | |||
padding: 10px; | |||
overflow: hidden; | |||
.coverImg { | |||
max-width: 90%; | |||
max-height: 170px; | |||
cursor: pointer; | |||
} | |||
.takePlace { | |||
position: absolute; | |||
top: 40%; | |||
width: 80%; | |||
} | |||
} | |||
.more { | |||
position: absolute; | |||
top: 0; | |||
left: 0; | |||
width: 100%; | |||
height: 170px; | |||
background-color: rgb(0 0 0 / 30%); | |||
cursor: pointer; | |||
opacity: 0; | |||
transition: all 0.2s; | |||
.icon-videoPlay { | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
width: 50px; | |||
height: 50px; | |||
font-size: 50px; | |||
color: #fff; | |||
text-align: center; | |||
transform: translate(-50%, -50%); | |||
cursor: pointer; | |||
} | |||
.showBtn { | |||
position: absolute; | |||
top: 10px; | |||
right: 10px; | |||
width: 20px; | |||
height: 20px; | |||
font-size: 20px; | |||
line-height: 10px; | |||
color: #fff; | |||
text-align: center; | |||
transition: all 0.3s; | |||
cursor: pointer; | |||
border-radius: 2px; | |||
&:hover { | |||
background-color: #00000056; | |||
} | |||
} | |||
.btns { | |||
position: absolute; | |||
top: 45px; | |||
right: 10px; | |||
// width: 70px; | |||
// height: 60px; | |||
overflow: hidden; | |||
border-radius: 10px; | |||
cursor: pointer; | |||
&-item { | |||
// width: 70px; | |||
// height: 30px; | |||
text-align: center; | |||
background-color: #fff; | |||
padding: 0 10px; | |||
transition: all 0.3s; | |||
cursor: pointer; | |||
&-icon { | |||
position: relative; | |||
display: inline-block; | |||
width: 20px; | |||
height: 20px; | |||
cursor: pointer; | |||
.icon-delete { | |||
position: absolute; | |||
top: 4px; | |||
left: 0; | |||
width: 20px; | |||
height: 20px; | |||
font-size: 16px; | |||
color: #000; | |||
text-align: center; | |||
cursor: pointer; | |||
} | |||
} | |||
.text { | |||
display: inline-block; | |||
height: 30px; | |||
padding-left: 5px; | |||
margin-top: -5px; | |||
line-height: 20px; | |||
font-size: 13px; | |||
cursor: pointer; | |||
} | |||
&:hover { | |||
color: #ffffff; | |||
background-color: #0000001a; | |||
} | |||
} | |||
} | |||
} | |||
.workInfo { | |||
justify-content: space-between; | |||
height: 40px; | |||
padding: 0 10px; | |||
line-height: 40px; | |||
border-top: 1px solid #afafaf; | |||
white-space: nowrap; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
font-size: 13px; | |||
} | |||
.statusName { | |||
position: absolute; | |||
top: 10%; | |||
left: -10%; | |||
width: 120px; | |||
text-align: center; | |||
color: #ffffff; | |||
font-size: 14px; | |||
transform: rotate(-45deg); | |||
&.manuscript { | |||
/* 草稿 */ | |||
background: linear-gradient(to right, #d7d2cc 0%, #304352 100%); | |||
} | |||
&.generating { | |||
/* 生成中 */ | |||
background: linear-gradient(270deg, #4b61dc, #15d1b8); | |||
} | |||
&.generationFailed { | |||
/* 生成失败 */ | |||
background: linear-gradient(120deg, #f093fb 0%, #f5576c 100%); | |||
} | |||
&.generationSucceed { | |||
/* 生成成功 */ | |||
background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%); | |||
} | |||
&.videoUping { | |||
/* 升级中 */ | |||
background: linear-gradient(120deg, #4512c7 0%, #4fd334 100%); | |||
} | |||
&.videoUpFailed { | |||
/* HD */ | |||
background: linear-gradient(120deg, #ff0019 0%, #ff00c3 100%); | |||
} | |||
&.videoUpSucceed { | |||
/* HD */ | |||
background: linear-gradient(120deg, #fdeb71 0%, #d37e1a 100%); | |||
} | |||
} | |||
&:hover { | |||
.more { | |||
opacity: 1; | |||
} | |||
} | |||
} | |||
} | |||
.noList { | |||
.title { | |||
font-size: 30px; | |||
text-align: center; | |||
margin-top: 100px; | |||
background-image: -webkit-linear-gradient( | |||
left, | |||
#4b61dc, | |||
#15d1b8 25%, | |||
#4b61dc 50%, | |||
#15d1b8 75%, | |||
#4b61dc | |||
) !important; | |||
-webkit-text-fill-color: transparent !important; | |||
-webkit-background-clip: text !important; | |||
background-clip: text !important; | |||
-webkit-background-size: 200% 100% !important; | |||
background-size: 200% 100% !important; | |||
} | |||
.goCreate { | |||
width: 200px; | |||
height: 40px; | |||
line-height: 40px; | |||
text-align: center; | |||
color: #ffffff; | |||
border-radius: 6px; | |||
background: linear-gradient(270deg, #4b61dc, #15d1b8); | |||
margin: 30px auto; | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
&:hover { | |||
transform: scale(1.1); | |||
} | |||
} | |||
} | |||
.pagination { | |||
position: fixed; | |||
bottom: 20px; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
background-color: #ffffff; | |||
padding: 10px 20px; | |||
border-radius: 8px; | |||
transition: all 0.3s; | |||
cursor: pointer; | |||
&:hover { | |||
background-color: #b8b8b873; | |||
} | |||
} | |||
} | |||
:deep(.el-input__wrapper) { | |||
border: none; | |||
border-bottom: 2px solid #000; | |||
border-radius: 0; | |||
box-shadow: none; | |||
} | |||
.el-icon.icon-edit { | |||
width: 30px; | |||
height: 30px; | |||
font-size: 30px; | |||
color: #8c939d; | |||
text-align: center; | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
&:hover { | |||
color: #292929; | |||
} | |||
} | |||
.elDialog { | |||
.videoBox { | |||
// display: flex; | |||
// justify-content: space-between; | |||
width: 100%; | |||
padding: 20px; | |||
.overtimeTips { | |||
// width: 60%; | |||
// display: inline-block; | |||
padding: 5px; | |||
margin-bottom: 10px; | |||
background-color: #ccc; | |||
border-radius: 5px; | |||
line-height: 20px; | |||
color: #000; | |||
text-align: center; | |||
img { | |||
width: 20px; | |||
height: 20px; | |||
vertical-align: middle; | |||
margin-right: 5px; | |||
} | |||
} | |||
video { | |||
width: 100%; | |||
max-height: 600px; | |||
margin: auto; | |||
} | |||
.insteadVideo { | |||
font-size: 20px; | |||
font-weight: 400; | |||
margin: 20px auto; | |||
text-align: center; | |||
} | |||
p { | |||
font-weight: 700; | |||
} | |||
} | |||
.dialog-footer { | |||
display: flex; | |||
justify-content: space-between; | |||
.elBtn { | |||
color: #fff; | |||
border-radius: 10px; | |||
padding: 10px 15px; | |||
cursor: pointer; | |||
background-color: #000; | |||
transition: all 0.3s; | |||
&:hover { | |||
background-color: #15d1b8; | |||
} | |||
} | |||
.upSharpness { | |||
img { | |||
width: 14px; | |||
height: 14px; | |||
} | |||
} | |||
:deep(.el-icon) { | |||
margin-right: 5px; | |||
font-weight: 700; | |||
} | |||
} | |||
} | |||
:deep(.el-dialog) { | |||
overflow: hidden; | |||
border-radius: 25px; | |||
} | |||
// :deep(.el-dialog__header) { | |||
// } | |||
:deep(.el-dialog__title) { | |||
background-image: -webkit-linear-gradient( | |||
left, | |||
#4b61dc, | |||
#15d1b8 25%, | |||
#4b61dc 50%, | |||
#15d1b8 75%, | |||
#4b61dc | |||
) !important; | |||
-webkit-text-fill-color: transparent !important; | |||
-webkit-background-clip: text !important; | |||
background-clip: text !important; | |||
-webkit-background-size: 200% 100% !important; | |||
background-size: 200% 100% !important; | |||
} | |||
:deep(.el-dialog__body) { | |||
padding: 0; | |||
} | |||
:deep(.dialog__footer) { | |||
padding: 0; | |||
} | |||
</style> |
@@ -0,0 +1,16 @@ | |||
/** | |||
* @description:根据状态返回状态名 | |||
* @param {number} status | |||
* @return: statusName | |||
*/ | |||
export const getStatus = status => { | |||
if (status == 0) { | |||
return "manuscript" | |||
} else if (status == 1 || status == 2 || status == 4 || status == 6) { | |||
return "generating" | |||
} else if (status == 3) { | |||
return "generationFailed" | |||
} else if (status == 5) { | |||
return "generationSucceed" | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
<template> | |||
<div></div> | |||
</template> | |||
<script setup> | |||
// import { ref } from 'vue' | |||
</script> | |||
<style lang="scss" scoped></style> |
@@ -2289,6 +2289,13 @@ decode-uri-component@^0.2.0: | |||
resolved "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz" | |||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== | |||
decompress-response@^6.0.0: | |||
version "6.0.0" | |||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" | |||
integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== | |||
dependencies: | |||
mimic-response "^3.1.0" | |||
dedent@0.7.0: | |||
version "0.7.0" | |||
resolved "https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz" | |||
@@ -3182,6 +3189,17 @@ glob@7.2.3, glob@^7.1.3: | |||
once "^1.3.0" | |||
path-is-absolute "^1.0.0" | |||
glob@^8.0.1: | |||
version "8.1.0" | |||
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" | |||
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== | |||
dependencies: | |||
fs.realpath "^1.0.0" | |||
inflight "^1.0.4" | |||
inherits "2" | |||
minimatch "^5.0.1" | |||
once "^1.3.0" | |||
global-dirs@^0.1.1: | |||
version "0.1.1" | |||
resolved "https://registry.npmmirror.com/global-dirs/-/global-dirs-0.1.1.tgz" | |||
@@ -3759,6 +3777,11 @@ js-base64@^2.1.9: | |||
resolved "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz" | |||
integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== | |||
js-binary-schema-parser@^2.0.2: | |||
version "2.0.3" | |||
resolved "https://registry.yarnpkg.com/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz#3d7848748e8586e63b34e8911b643f59cfb6396e" | |||
integrity sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg== | |||
js-sdsl@^4.1.4: | |||
version "4.4.0" | |||
resolved "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.4.0.tgz" | |||
@@ -4299,6 +4322,11 @@ mimic-fn@^4.0.0: | |||
resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz" | |||
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== | |||
mimic-response@^3.1.0: | |||
version "3.1.0" | |||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" | |||
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== | |||
min-indent@^1.0.0: | |||
version "1.0.1" | |||
resolved "https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz" | |||
@@ -4311,6 +4339,13 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: | |||
dependencies: | |||
brace-expansion "^1.1.7" | |||
minimatch@^5.0.1: | |||
version "5.1.6" | |||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" | |||
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== | |||
dependencies: | |||
brace-expansion "^2.0.1" | |||
minimatch@^6.1.6: | |||
version "6.2.0" | |||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz" | |||
@@ -4565,7 +4600,7 @@ ohash@^1.1.1: | |||
resolved "https://registry.npmjs.org/ohash/-/ohash-1.1.2.tgz" | |||
integrity sha512-9CIOSq5945rI045GFtcO3uudyOkYVY1nyfFxVQp+9BRgslr8jPNiSSrsFGg/BNTUFOLqx0P5tng6G32brIPw0w== | |||
once@^1.3.0: | |||
once@^1.3.0, once@^1.3.1: | |||
version "1.4.0" | |||
resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz" | |||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== | |||
@@ -4665,6 +4700,11 @@ parent-module@^1.0.0: | |||
dependencies: | |||
callsites "^3.0.0" | |||
parenthesis@^3.1.5: | |||
version "3.1.8" | |||
resolved "https://registry.yarnpkg.com/parenthesis/-/parenthesis-3.1.8.tgz#3457fccb8f05db27572b841dad9d2630b912f125" | |||
integrity sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw== | |||
parse-json@^5.0.0: | |||
version "5.2.0" | |||
resolved "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz" | |||
@@ -5271,6 +5311,20 @@ signal-exit@^4.0.1: | |||
resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.0.2.tgz" | |||
integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== | |||
simple-concat@^1.0.0: | |||
version "1.0.1" | |||
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" | |||
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== | |||
simple-get@^4.0.1: | |||
version "4.0.1" | |||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" | |||
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== | |||
dependencies: | |||
decompress-response "^6.0.0" | |||
once "^1.3.1" | |||
simple-concat "^1.0.0" | |||
sirv@^2.0.2: | |||
version "2.0.3" | |||
resolved "https://registry.npmmirror.com/sirv/-/sirv-2.0.3.tgz" | |||
@@ -5471,6 +5525,13 @@ string-argv@^0.3.1: | |||
resolved "https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz" | |||
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== | |||
string-split-by@^1.0.0: | |||
version "1.0.0" | |||
resolved "https://registry.yarnpkg.com/string-split-by/-/string-split-by-1.0.0.tgz#53895fb3397ebc60adab1f1e3a131f5372586812" | |||
integrity sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A== | |||
dependencies: | |||
parenthesis "^3.1.5" | |||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: | |||
version "4.2.3" | |||
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz" | |||
@@ -6268,6 +6329,16 @@ vue-i18n@9: | |||
"@intlify/vue-devtools" "9.2.2" | |||
"@vue/devtools-api" "^6.2.1" | |||
vue-qr@^4.0.9: | |||
version "4.0.9" | |||
resolved "https://registry.yarnpkg.com/vue-qr/-/vue-qr-4.0.9.tgz#6cb965dd0c5a0dff947e6ef582ef149b0780b986" | |||
integrity sha512-pAISV94T0MNEYA3NGjykUpsXRE2QfaNxlu9ZhEL6CERgqNc21hJYuP3hRVzAWfBQlgO18DPmZTbrFerJC3+Ikw== | |||
dependencies: | |||
glob "^8.0.1" | |||
js-binary-schema-parser "^2.0.2" | |||
simple-get "^4.0.1" | |||
string-split-by "^1.0.0" | |||
vue-router@^4.0.13: | |||
version "4.0.13" | |||
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.0.13.tgz" | |||