@@ -67,10 +67,11 @@ export default { | |||
saveVideo:'Save Manuscript', | |||
select:'Please Select', | |||
music:'Music', | |||
Aipicture:'AI-generated pictures', | |||
Aipicture:'AI-generated Pictures', | |||
AipictureTip:'Please customize your picture', | |||
chooseMusic:'Choose Music', | |||
searchMusic:'Search Music' | |||
searchMusic:'Search Music', | |||
comingSoon:'coming soon', | |||
}, | |||
// 我的视频 | |||
@@ -115,7 +116,7 @@ export default { | |||
msg1: "Obtain one video production time", | |||
inputCode:'Please enter the invitation code', | |||
submit:'Submit', | |||
noListOrder: "没有数据哦,快去邀请更多人加入我们吧~", | |||
noListOrder: "No data available", | |||
noListInvite: "No data, please invite more people to join us", | |||
}, | |||
@@ -130,6 +131,23 @@ export default { | |||
selectPlan: "SELECT PLAN", | |||
WeChatPay: "WeChatPay", | |||
Alipay: "Alipay", | |||
score:'score', | |||
day:'day', | |||
second:'second', | |||
yes:'yes', | |||
no:'no', | |||
InviteGetscore:'Invite users to get score', | |||
createVideoPrice:'Create video prices', | |||
AIGeneratesPhotoPrices:'AI generates photo unit prices', | |||
UnitChargeDuration:'Unit charge duration', | |||
Language:'Language', | |||
sound:'sound', | |||
IndividualVideoDuration:'Individual video duration', | |||
AIGeneratedPortrait:'AI generated portrait', | |||
PhotoSinging:'Photo singing', | |||
AIGeneratedText:'The number of times AI generated text', | |||
VideoResolution:'Video resolution', | |||
DigitalPersonTemplate:'Digital person template', | |||
}, | |||
signSucceed: { | |||
title: "Confirm your email", | |||
@@ -67,10 +67,11 @@ export default { | |||
saveVideo:'保存草稿', | |||
select:'请选择', | |||
music:'音乐', | |||
Aipicture:'Ai生成图片', | |||
Aipicture:'AI生成图片', | |||
AipictureTip:'请自定义您的图片', | |||
chooseMusic:'选择音乐', | |||
searchMusic:'搜索音乐', | |||
comingSoon:'敬请期待', | |||
}, | |||
// 我的视频 | |||
@@ -115,7 +116,7 @@ export default { | |||
msg1: "获得视频制作次数一次", | |||
inputCode:'请输入邀请码', | |||
submit:'提交', | |||
noListOrder: "没有数据哦,快去邀请更多人加入我们吧~", | |||
noListOrder: "暂无数据", | |||
noListInvite: "没有数据哦,快去邀请更多人加入我们吧~", | |||
}, | |||
@@ -130,6 +131,23 @@ export default { | |||
selectPlan: "方案选择", | |||
WeChatPay: "微信支付", | |||
Alipay: "支付宝支付", | |||
score:'积分', | |||
day:'天', | |||
second:'秒', | |||
yes:'是', | |||
no:'否', | |||
InviteGetscore:'邀请用户得到的积分', | |||
createVideoPrice:'创建视频单价', | |||
AIGeneratesPhotoPrices:'AI生成照片单价', | |||
UnitChargeDuration:'单价收费时长', | |||
Language:'语言', | |||
sound:'声音', | |||
IndividualVideoDuration:'单个视频时长', | |||
AIGeneratedPortrait:'AI生成人像', | |||
PhotoSinging:'照片唱歌', | |||
AIGeneratedText:'AI生成脚本次数', | |||
VideoResolution:'视频分辨率', | |||
DigitalPersonTemplate:'数字人模版', | |||
}, | |||
signSucceed: { | |||
title: "确认邮箱", | |||
@@ -16,7 +16,7 @@ | |||
<!--语言选择--> | |||
<lang-select class="navItem" style="color: #ffffff" /> | |||
<div | |||
<!-- <div | |||
class="avatar" | |||
v-if="userInfoPinia.userInfo.avatarUrl" | |||
@click="routerTo" | |||
@@ -29,7 +29,8 @@ | |||
" | |||
alt="" | |||
/> | |||
</div> | |||
</div> --> | |||
<div class="navItem" v-if="AccessToken" @click="routerTo"> | |||
{{ $t("navbar.account") }} | |||
</div> | |||
@@ -33,5 +33,9 @@ import ElementPlus from "element-plus"; | |||
app.use(ElementPlus); | |||
app.use(router).use(i18n).mount("#app"); | |||
// 路由加载完成后挂载 | |||
// router.isReady().then(() => { | |||
// app.use(router).use(i18n).use(store).mount('#app') | |||
// }); | |||
// 注册全局组件 | |||
app.component('myLoading',myLoading).component('myLoadingIcon',myLoadingIcon) |
@@ -6,6 +6,7 @@ const store = createPinia(); | |||
store.use(piniaPluginPersistedstate ) | |||
// 全局注册 store | |||
export function setupStore(app: App<Element>) { | |||
app.use(store); | |||
@@ -3,16 +3,16 @@ import { store } from "@/store"; | |||
import { | |||
getUserInfoApi, | |||
} from "../../apis/myAccount"; | |||
export const userInfoModules = defineStore("userInfo", () => { | |||
export const userInfoModules = defineStore("userInfoState", () => { | |||
// state | |||
const userInfo = ref({ | |||
avatarUrl: null | |||
}) | |||
const userInfo = ref({}) | |||
// 登录获取用户信息 | |||
async function getUserInfo() { | |||
const res = await getUserInfoApi() | |||
console.log(res.data); | |||
userInfo.value = res.data | |||
console.log(userInfo); | |||
} | |||
// 退出清除用户信息 | |||
function loginOut(params) { | |||
@@ -58,6 +58,7 @@ declare module '@vue/runtime-core' { | |||
IEpGoods: typeof import('~icons/ep/goods')['default'] | |||
IEpHeadset: typeof import('~icons/ep/headset')['default'] | |||
IEpLoading: typeof import('~icons/ep/loading')['default'] | |||
IEpLock: typeof import('~icons/ep/lock')['default'] | |||
IEpMenu: typeof import('~icons/ep/menu')['default'] | |||
IEpMic: typeof import('~icons/ep/mic')['default'] | |||
IEpPlus: typeof import('~icons/ep/plus')['default'] | |||
@@ -145,7 +145,7 @@ | |||
<div | |||
class="pointer" | |||
:class="showFace == 0 ? 'tabAvtive' : ''" | |||
@click="showFace = 0" | |||
@click="chooSystemImg" | |||
> | |||
{{ $t("createVideo.availableMould") }} | |||
</div> | |||
@@ -153,7 +153,7 @@ | |||
v-if="AccessToken" | |||
class="pointer" | |||
:class="showFace == 1 ? 'tabAvtive' : ''" | |||
@click="showFace = 1" | |||
@click="chooseMyImg" | |||
> | |||
{{ $t("createVideo.personalWarehouse") }} | |||
</div> | |||
@@ -236,7 +236,7 @@ | |||
:infinite-scroll-disabled="overLoadUser" | |||
> | |||
<div class="title"> | |||
{{ $t("createVideo.AipictureTip") }} | |||
{{ $t("createVideo.comingSoon") }} | |||
</div> | |||
</div> | |||
</div> | |||
@@ -429,7 +429,7 @@ | |||
{{ $t("createVideo.chooseMusic") }} | |||
</p> | |||
<!-- 搜索框 --> | |||
<div class="flex justify-between" style="width: 99%"> | |||
<!-- <div class="flex justify-between" style="width: 99%"> | |||
<el-input | |||
v-model="searchInput" | |||
:placeholder="$t('createVideo.searchMusic')" | |||
@@ -438,7 +438,7 @@ | |||
<el-icon class="icon-edit" @click="searchMusicList" | |||
><i-ep-search | |||
/></el-icon> | |||
</div> | |||
</div> --> | |||
<!-- 音乐列表展示 --> | |||
<div class="musicList"> | |||
<div | |||
@@ -481,7 +481,7 @@ | |||
</div> | |||
</el-tab-pane> | |||
<!-- ----------------------- 4 --> | |||
<el-tab-pane :label="$t('createVideo.aiScript')"> | |||
<el-tab-pane v-if="AccessToken" :label="$t('createVideo.aiScript')"> | |||
<div class="card4"> | |||
<div class="text"> | |||
<!-- 文本域 --> | |||
@@ -697,9 +697,9 @@ const faceItemActive = ref(); //高亮处理和当前选择图片的ID | |||
// 点击aifece | |||
function setImgUrl(url, id) { | |||
faceItemActive.value = id; | |||
imgUrl.value = url; | |||
showUploadBtn.value = 1; | |||
submitImgBtn.value = false; | |||
imgUrl.value = url; | |||
} | |||
// 删除个人相册照片 | |||
async function deleteFaceImg(id) { | |||
@@ -750,6 +750,7 @@ async function lookImg(e) { | |||
showUploadBtn.value = 4; | |||
submitImgBtn.value = true; | |||
compressionImgLoad.value = false; | |||
await changeFile(); | |||
} else { | |||
return; | |||
} | |||
@@ -765,10 +766,10 @@ const imgUrl = ref(""); //图片回显路径 | |||
const imgData = ref(""); // 上传图片文件 | |||
const showUploadBtn = ref(1); //上传图片+号的显示隐藏 | |||
const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏 | |||
// 点击AI头像区的+号 | |||
function clickAddBtn() { | |||
faceItemActive.value = null; | |||
showUploadBtn.value = 2; | |||
// 点击系统仓库tab | |||
function chooSystemImg(params) { | |||
showFace.value = 0; | |||
showUploadBtn.value = 1; | |||
} | |||
// 上传图片 | |||
async function changeFile() { | |||
@@ -799,16 +800,28 @@ async function changeFile() { | |||
lanChange.value == "zh-cn" ? `上传失败` : `Upload failure` | |||
); | |||
} | |||
faceItemActive.value = res2.data.id; | |||
imgUrl.value = res2.data.material; | |||
} catch (error) { | |||
ElMessage.error(error); | |||
} | |||
} | |||
// 点击个人仓库tab | |||
function chooseMyImg() { | |||
showFace.value = 1; | |||
showUploadBtn.value = 2; | |||
} | |||
// 点击AI头像区的+号 | |||
function clickAddBtn() { | |||
faceItemActive.value = null; | |||
showUploadBtn.value = 2; | |||
} | |||
//#endregion --------------------------- | |||
//#region AI生成图片 | |||
function chooseAiPic() { | |||
showFace.value = 2; | |||
showUploadBtn.value = 5; | |||
// showUploadBtn.value = 5; | |||
} | |||
//#endregion -------------------------- | |||
@@ -1246,7 +1259,8 @@ onMounted(async () => { | |||
<style lang="scss" scoped> | |||
.page { | |||
height: 900px; | |||
height: 1200px; | |||
// height: calc(100vh - 80px); | |||
// padding: 20px 0 0 40px; | |||
background-color: #fff; | |||
@@ -1255,7 +1269,7 @@ onMounted(async () => { | |||
.left { | |||
width: 68%; | |||
// height: 90%; | |||
height: 90%; | |||
padding: 20px; | |||
:deep(.el-input__wrapper) { | |||
border: none; | |||
@@ -1276,7 +1290,8 @@ onMounted(async () => { | |||
position: relative; | |||
width: 100%; | |||
// height: 65%; | |||
height: 580px; | |||
// height: 580px; | |||
height: 65%; | |||
.uploadBtn { | |||
position: relative; | |||
@@ -35,21 +35,19 @@ | |||
<!-- 剩余次数 --> | |||
<div class="left-two border"> | |||
<div v-if="lanChange == 'en'" class="number"> | |||
3 Videos Generation Left | |||
Free for a limited time | |||
</div> | |||
<div v-if="lanChange == 'zh-cn'" class="number"> | |||
剩余生成视频次数:3条 | |||
</div> | |||
<div class="time">{{ $t("account.until") }} 2023/12/31</div> | |||
<div v-if="lanChange == 'zh-cn'" class="number">限时免费</div> | |||
<div class="time">{{ $t("account.until") }} 2023/7/31</div> | |||
<div class="getMore pointer" @click="routerTo('/myStore')"> | |||
{{ $t("account.getMore") }} | |||
</div> | |||
</div> | |||
<!-- 我的邀请码 --> | |||
<div class="left-three border flex justify-between"> | |||
<div class="codeImg"> | |||
<!-- <div class="codeImg"> | |||
<img ref="codeImgRef" :src="defaultAvater" alt="" /> | |||
</div> | |||
</div> --> | |||
<div class="other"> | |||
<div v-if="lanChange == 'en'"> | |||
<span>Invite friends to get</span> | |||
@@ -76,14 +74,14 @@ | |||
<span class="myBtn" @click="copyInviteCode">{{ | |||
$t("account.copyCode") | |||
}}</span> | |||
<span class="myBtn" @click="DownloadCodeImg">{{ | |||
<!-- <span class="myBtn" @click="DownloadCodeImg">{{ | |||
$t("account.saveCode") | |||
}}</span> | |||
}}</span> --> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 输入邀请码 --> | |||
<div class="left-four border" v-if="!isUseState"> | |||
<!-- 输入邀请码 !isUseState--> | |||
<div class="left-four border" v-if="false"> | |||
<el-input | |||
class="w-50 m-2" | |||
v-model="inputCode" | |||
@@ -100,7 +98,7 @@ | |||
<!-- ----------------------------- 1 --> | |||
<el-tab-pane :label="$t('account.buyHistory')"> | |||
<div class="card scrolly"> | |||
<div class="orderItem" v-for="item in 9" :key="item"> | |||
<div class="orderItem" v-for="item in 0" :key="item"> | |||
<p>{{ $t("account.orderID") }}:123456</p> | |||
<div class="orderItem-content"> | |||
<div class="orderCode"><img :src="defaultAvater" alt="" /></div> | |||
@@ -112,6 +110,12 @@ | |||
<div class="state">{{ $t("account.successed") }}</div> | |||
</div> | |||
</div> | |||
<!-- 无数据时 --> | |||
<div v-if="InviteList.length == 0" class="noList"> | |||
<div class="title"> | |||
{{ $t("account.noListOrder") }} | |||
</div> | |||
</div> | |||
</div> | |||
</el-tab-pane> | |||
<!-- ------------------------ 2 --> | |||
@@ -307,22 +311,33 @@ const inputCode = ref(""); // 邀请码输入框内容 | |||
const isUseState = ref(false); //用户是否填写过过邀请码 | |||
// 提交邀请码 | |||
async function submitUseCode() { | |||
console.log(inputCode.value); | |||
const res = await useCodeApi(inputCode.value); | |||
if (res.code == 200) { | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" | |||
? `提交邀请码成功` | |||
: `The invitation code was submitted successfully` | |||
); | |||
} else { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `提交邀请码成失败` | |||
: `Failed to submit the invitation code` | |||
); | |||
try { | |||
const res = await useCodeApi(inputCode.value); | |||
console.log(res.code); | |||
if (res.code == 200) { | |||
ElMessage.success( | |||
lanChange.value == "zh-cn" | |||
? `提交邀请码成功` | |||
: `The invitation code was submitted successfully` | |||
); | |||
} | |||
if (res.code == 1001) { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `不能使用自己的邀请码` | |||
: `You cannot use your own invitation code` | |||
); | |||
} else { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" | |||
? `提交邀请码成失败` | |||
: `Failed to submit the invitation code` | |||
); | |||
} | |||
await getIsUseState(); | |||
} catch (error) { | |||
console.log(error); | |||
} | |||
getIsUseState(); | |||
} | |||
// 查询是否使用过邀请码 | |||
async function getIsUseState() { | |||
@@ -346,6 +361,8 @@ onMounted(() => { | |||
getMyInviteCode(); // 查询用户的邀请码 | |||
getIsUseState(); //查询是否使用过邀请码 | |||
getInviteList(); | |||
console.log(userInfoPinia.userInfo); | |||
console.log(localStorage.userInfo); | |||
userNameinput.value = userInfoPinia.userInfo.name; | |||
dialogAvatarUrl.value = userInfoPinia.userInfo.avatarUrl; | |||
}); | |||
@@ -0,0 +1,431 @@ | |||
<template> | |||
<div class="page"> | |||
<div class="commoditylIst"> | |||
<div class="item" v-for="item in packageList" :key="item.title"> | |||
<div @click="clickPayDialog(item)"> | |||
<div class="line" :style="`background-color:${item.color} ;`"></div> | |||
<div class="info"> | |||
<!-- 商品信息 --> | |||
<div class="content"> | |||
<div class="title"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
{{ $t(item.title) }} | |||
</div> | |||
<div class="money"> | |||
<span class="price">{{ item.price }}元</span>/{{ | |||
item.priceTime | |||
}} | |||
</div> | |||
<div class="time"> | |||
<span>{{ item.time }}</span | |||
>分钟/月 | |||
</div> | |||
<div class="button" :style="`background-color:${item.color} ;`"> | |||
{{ $t("shop.selectPlan") }} | |||
</div> | |||
</div> | |||
<!-- 商品权益 --> | |||
<div class="authority"> | |||
<div | |||
class="authority-item" | |||
v-for="items in item.authority" | |||
:key="items" | |||
> | |||
<span>✔</span>{{ items }} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 对话框 --> | |||
<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> | |||
<div | |||
class="authority" | |||
v-for="item in presentItme.value.authority" | |||
:key="item" | |||
> | |||
{{ item }} | |||
</div> | |||
</div> | |||
<div class="right"> | |||
<div | |||
style="background-color: #07c160; cursor: pointer" | |||
@click="showOrderCode(1)" | |||
> | |||
{{ $t("shop.WeChatPay") }} | |||
</div> | |||
<div | |||
style="background-color: #1378fe; cursor: pointer" | |||
@click="showOrderCode(2)" | |||
> | |||
{{ $t("shop.Alipay") }} | |||
</div> | |||
<div | |||
style="background-color: #0070ba; cursor: pointer" | |||
@click="showOrderCode(3)" | |||
> | |||
Paypal | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 二维码弹出框 --> | |||
<el-dialog | |||
v-model="orderCodeDialogShow" | |||
width="30%" | |||
append-to-body | |||
destroy-on-close | |||
> | |||
<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="" /> | |||
</div> | |||
<div class="tips">扫描二维码进行付款</div> | |||
<div class="btnBox"> | |||
<div>刷新二维码</div> | |||
</div> | |||
</div> | |||
</el-dialog> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<script setup> | |||
//#region 导入 | |||
import { getCurrentInstance } from "vue"; | |||
import { packageInfoApi } from "@/apis/myStore"; | |||
import { useI18n } from "vue-i18n"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | |||
//#endregion ------------------------------------ | |||
//#region 各个套餐的逻辑 | |||
const packageList = ref([ | |||
{ | |||
color: "#f3af00", | |||
title: "shop.Lite", | |||
icon: "", | |||
price: "0", | |||
priceTime: "14天", | |||
time: "5", | |||
authority: [ | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
], | |||
}, | |||
{ | |||
color: "#c971ff", | |||
title: "shop.Pro", | |||
icon: "", | |||
price: "10", | |||
priceTime: "30天", | |||
time: "10", | |||
authority: [ | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
"API访问", | |||
], | |||
}, | |||
{ | |||
color: "#7b61ff", | |||
title: "shop.Adv", | |||
icon: "", | |||
price: "20", | |||
priceTime: "30天", | |||
time: "15", | |||
authority: [ | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
"API访问", | |||
"商业用途", | |||
], | |||
}, | |||
{ | |||
color: "#000", | |||
title: "shop.Ent", | |||
icon: "", | |||
price: "50", | |||
priceTime: "30天", | |||
time: "40", | |||
authority: [ | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
"API访问", | |||
"商业用途", | |||
"PowerPoint 插件", | |||
], | |||
}, | |||
]); | |||
async function getPackageList() { | |||
const res = await packageInfoApi(); | |||
} | |||
const showPayDialog = ref(false); //套餐信息dialog显示隐藏 | |||
const presentItme = reactive({}); //点击的套餐项 | |||
function clickPayDialog(item) { | |||
presentItme.value = item; | |||
showPayDialog.value = true; | |||
} | |||
function showOrderCode(type) { | |||
orderCodeDialogShow.value = true; | |||
} | |||
//#endregion ------------------------------------ | |||
//#region 点击套餐内的支付 | |||
const orderCodeDialogShow = ref(false); | |||
const orderCodeUrl = ref(null); | |||
//#endregion ------------------------------------ | |||
//#region $t在script中的使用 | |||
// const { | |||
// appContext: { | |||
// config: { globalProperties }, | |||
// }, | |||
// } = getCurrentInstance(); | |||
// const string = "createVideo.typeScript"; | |||
// const t = globalProperties.$t(string); | |||
//#endregion ------------------------------------ | |||
//#region 页面初始化 | |||
onMounted(async () => { | |||
getPackageList(); | |||
}); | |||
//#endregion ------------------------------------ | |||
//#region | |||
//#endregion ------------------------------------ | |||
//#region | |||
//#endregion ------------------------------------ | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
min-width: calc(100vw - 210px); | |||
height: calc(100vh - 80px); | |||
padding: 20px 20px 0 20px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
padding: 20px; | |||
} | |||
.commoditylIst { | |||
display: flex; | |||
justify-content: flex-start; | |||
// overflow-x: auto; | |||
padding: 20px 20px 20px 50px; | |||
// width: 100%; | |||
// height: 75%; | |||
overflow: hidden; | |||
overflow-x: scroll; | |||
// scrollbar-width: none; /* 隐藏滚动条(Chrome、Firefox) */ | |||
// -ms-overflow-style: none; /* 隐藏滚动条(IE、Edge) */ | |||
// &::-webkit-scrollbar { | |||
// display: none; /* 隐藏滚动条(Safari、Chrome) */ | |||
// } | |||
.item { | |||
width: 350px; | |||
height: 780px; | |||
margin-right: 50px; | |||
background-color: #fffefd; | |||
flex-shrink: 0; /* 防止缩小宽度 */ | |||
border: 1px solid #c0bfbd; | |||
border-radius: 20px; | |||
overflow: hidden; | |||
transition: all 0.2s; | |||
cursor: pointer; | |||
.line { | |||
height: 20px; | |||
background-color: pink; | |||
cursor: pointer; | |||
} | |||
.info { | |||
padding: 20px; | |||
cursor: pointer; | |||
.content { | |||
height: 300px; | |||
padding: 20px; | |||
border-bottom: 1px solid #c0bfbd; | |||
cursor: pointer; | |||
.title { | |||
font-size: 30px; | |||
font-weight: 700; | |||
line-height: 25px; | |||
margin-bottom: 30px; | |||
cursor: pointer; | |||
.el-icon { | |||
line-height: 30px; | |||
width: 40px; | |||
height: 40px; | |||
font-size: 40px; | |||
color: #000; | |||
text-align: center; | |||
vertical-align: sub; | |||
cursor: pointer; | |||
} | |||
} | |||
.money { | |||
margin-bottom: 30px; | |||
font-size: 20px; | |||
color: #7c7c7a; | |||
cursor: pointer; | |||
.price { | |||
font-size: 30px; | |||
font-weight: 700; | |||
color: #242625; | |||
cursor: pointer; | |||
} | |||
} | |||
.time { | |||
margin-bottom: 30px; | |||
font-size: 20px; | |||
color: #7c7c7a; | |||
cursor: pointer; | |||
span { | |||
font-weight: 700; | |||
color: #242625; | |||
cursor: pointer; | |||
} | |||
} | |||
.button { | |||
width: 100%; | |||
height: 40px; | |||
border-radius: 10px; | |||
text-align: center; | |||
line-height: 40px; | |||
color: #fff; | |||
font-weight: 700; | |||
background-color: yellow; | |||
cursor: pointer; | |||
} | |||
} | |||
.authority { | |||
cursor: pointer; | |||
&-item { | |||
cursor: pointer; | |||
padding: 20px 10px; | |||
span { | |||
cursor: pointer; | |||
color: #7c7c7a; | |||
margin-right: 30px; | |||
} | |||
} | |||
} | |||
} | |||
&:hover { | |||
cursor: pointer; | |||
transform: translateY(-20px); | |||
box-shadow: #00000026 2px 2px 2px 2px; | |||
} | |||
} | |||
} | |||
.payDialog { | |||
display: flex; | |||
position: relative; | |||
min-height: 500px; | |||
.left { | |||
width: 35%; | |||
border-right: 1px solid #7c7c7a; | |||
.title { | |||
color: #242625; | |||
font-weight: 700; | |||
font-size: 30px; | |||
text-align: center; | |||
} | |||
.price { | |||
span { | |||
font-size: 30px; | |||
font-weight: 700; | |||
color: #242625; | |||
} | |||
} | |||
.authority { | |||
padding: 10px 20px; | |||
} | |||
} | |||
.right { | |||
width: 65%; | |||
position: absolute; | |||
top: 20%; | |||
right: 0%; | |||
padding-left: 20%; | |||
> div { | |||
width: 200px; | |||
height: 40px; | |||
// border: 1px solid #242625; | |||
border-radius: 10px; | |||
text-align: center; | |||
line-height: 40px; | |||
margin: 30px; | |||
color: #fff; | |||
} | |||
} | |||
} | |||
.orderCodeDialog { | |||
width: 100%; | |||
.codeImg { | |||
display: flex; | |||
margin: auto; | |||
justify-content: space-evenly; | |||
align-items: center; | |||
width: 300px; | |||
height: 300px; | |||
border: 1px solid #ccc; | |||
border-radius: 15px; | |||
overflow: hidden; | |||
padding: 10px; | |||
img { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
.tips { | |||
padding-top: 10px; | |||
text-align: center; | |||
} | |||
.btnBox { | |||
padding: 15px 40px; | |||
display: flex; | |||
justify-content: space-evenly; | |||
> div { | |||
padding: 10px 20px; | |||
color: #000; | |||
background-color: #fff; | |||
border: #000 solid 1px; | |||
border-radius: 10px; | |||
transition: all 0.3s; | |||
cursor: pointer; | |||
&:hover { | |||
color: #fff; | |||
background-color: #000; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@@ -1,46 +1,121 @@ | |||
<template> | |||
<div class="page"> | |||
<div class="commoditylIst"> | |||
<div class="item" v-for="item in packageList" :key="item.title"> | |||
<div @click="clickPayDialog(item)"> | |||
<div class="item" v-for="item in packageList" :key="item.typeDesc"> | |||
<!-- 遮罩层 --> | |||
<div class="mask" v-if="item.type != 1"> | |||
<el-icon><i-ep-Lock /></el-icon> | |||
</div> | |||
<div @click="clickPayDialog(item)" v-if="item.typeDesc"> | |||
<div class="line" :style="`background-color:${item.color} ;`"></div> | |||
<div class="info"> | |||
<!-- 商品信息 --> | |||
<div class="content"> | |||
<div class="title"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
{{ $t(item.title) }} | |||
{{ $t(item.typeDesc) }} | |||
</div> | |||
<div class="money"> | |||
<span class="price">{{ item.price }}元</span>/{{ | |||
item.priceTime | |||
}} | |||
<span class="price">{{ | |||
lanChange == "zh-cn" ? item.rmb + "¥" : item.dollar + "$" | |||
}}</span | |||
>/{{ item.validityDuration }}{{ $t("shop.day") }} | |||
</div> | |||
<div class="time"> | |||
<span>{{ item.time }}</span | |||
>分钟/月 | |||
<span>{{ item.credit }}</span | |||
>{{ $t("shop.score") }} | |||
</div> | |||
<div | |||
v-if="item.type != 1" | |||
class="button" | |||
:style="`background-color:${item.color} ;`" | |||
> | |||
{{ $t("createVideo.comingSoon") }} | |||
</div> | |||
<div class="button" :style="`background-color:${item.color} ;`"> | |||
<div | |||
v-else | |||
class="button" | |||
:style="`background-color:${item.color} ;`" | |||
> | |||
{{ $t("shop.selectPlan") }} | |||
</div> | |||
</div> | |||
<!-- 商品权益 --> | |||
<div class="authority"> | |||
<div | |||
<div class="authority-item"> | |||
{{ $t("shop.InviteGetscore") }}:{{ item.inviteUserCredit | |||
}}{{ $t("shop.score") }} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.createVideoPrice") }}:{{ item.videoPrice | |||
}}{{ $t("shop.score") }} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratesPhotoPrices") }}:{{ item.photoPrice | |||
}}{{ $t("shop.score") }} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.UnitChargeDuration") }}:{{ item.chargeTime | |||
}}{{ $t("shop.second") }} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.Language") }}:{{ | |||
item.userPackageDetails[0].languageDesc | |||
}} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.sound") }}:{{ | |||
item.userPackageDetails[0].soundDesc | |||
}} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.IndividualVideoDuration") }}:{{ | |||
item.userPackageDetails[0].videoTime | |||
}}{{ $t("shop.second") }} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratedPortrait") }}:{{ | |||
item.userPackageDetails[0].aiPortrait == 0 | |||
? $t("shop.yes") | |||
: $t("shop.no") | |||
}} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.PhotoSinging") }}:{{ | |||
item.userPackageDetails[0].photoSing == 0 | |||
? $t("shop.yes") | |||
: $t("shop.no") | |||
}} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.AIGeneratedText") }}:{{ | |||
item.userPackageDetails[0].aiCreateTime | |||
}} | |||
</div> | |||
<div class="authority-item"> | |||
{{ $t("shop.VideoResolution") }}:{{ | |||
item.userPackageDetails[0].resolutionRatioDesc | |||
}} | |||
</div> | |||
<!-- <div class="authority-item"> | |||
{{ $t("shop.DigitalPersonTemplate") }}:{{ | |||
item.userPackageDetails[0].humanTemplateDesc | |||
}} | |||
</div> --> | |||
<!-- <div | |||
class="authority-item" | |||
v-for="items in item.authority" | |||
:key="items" | |||
> | |||
<span>✔</span>{{ items }} | |||
</div> | |||
</div> --> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- 对话框 --> | |||
<el-dialog v-model="showPayDialog" width="60%" center> | |||
<el-dialog v-if="false" v-model="showPayDialog" width="60%" center> | |||
<div class="payDialog"> | |||
<div class="left"> | |||
<div class="title">{{ $t(presentItme.value.title) }}</div> | |||
@@ -182,6 +257,7 @@ const packageList = ref([ | |||
async function getPackageList() { | |||
const res = await packageInfoApi(); | |||
packageList.value = res.data; | |||
} | |||
const showPayDialog = ref(false); //套餐信息dialog显示隐藏 | |||
const presentItme = reactive({}); //点击的套餐项 | |||
@@ -234,24 +310,26 @@ onMounted(async () => { | |||
border-radius: 25px 0 0; | |||
padding: 20px; | |||
} | |||
// 方案列表 | |||
.commoditylIst { | |||
display: flex; | |||
justify-content: flex-start; | |||
// overflow-x: auto; | |||
padding: 20px 20px 20px 50px; | |||
// width: 100%; | |||
padding: 20px 20px 20px 150px; | |||
width: 100%; | |||
// height: 75%; | |||
overflow: hidden; | |||
overflow-x: scroll; | |||
// overflow: hidden; | |||
// overflow-x: scroll; | |||
// scrollbar-width: none; /* 隐藏滚动条(Chrome、Firefox) */ | |||
// -ms-overflow-style: none; /* 隐藏滚动条(IE、Edge) */ | |||
// &::-webkit-scrollbar { | |||
// display: none; /* 隐藏滚动条(Safari、Chrome) */ | |||
// } | |||
.item { | |||
position: relative; | |||
width: 350px; | |||
height: 780px; | |||
margin-right: 50px; | |||
margin-right: 150px; | |||
background-color: #fffefd; | |||
flex-shrink: 0; /* 防止缩小宽度 */ | |||
border: 1px solid #c0bfbd; | |||
@@ -259,6 +337,26 @@ onMounted(async () => { | |||
overflow: hidden; | |||
transition: all 0.2s; | |||
cursor: pointer; | |||
&:hover { | |||
.mask { | |||
display: block; | |||
} | |||
} | |||
// 遮罩层 | |||
.mask { | |||
position: absolute; | |||
top: 0; | |||
left: 0; | |||
display: none; | |||
width: 100%; | |||
height: 100%; | |||
line-height: 780px; | |||
font-size: 200px; | |||
font-weight: 900; | |||
text-align: center; | |||
background-color: rgba(0, 0, 0, 0.2); | |||
cursor: pointer; | |||
} | |||
.line { | |||
height: 20px; | |||
background-color: pink; | |||
@@ -268,7 +366,7 @@ onMounted(async () => { | |||
padding: 20px; | |||
cursor: pointer; | |||
.content { | |||
height: 300px; | |||
height: 220px; | |||
padding: 20px; | |||
border-bottom: 1px solid #c0bfbd; | |||
cursor: pointer; | |||
@@ -276,7 +374,7 @@ onMounted(async () => { | |||
font-size: 30px; | |||
font-weight: 700; | |||
line-height: 25px; | |||
margin-bottom: 30px; | |||
margin-bottom: 10px; | |||
cursor: pointer; | |||
.el-icon { | |||
line-height: 30px; | |||
@@ -290,7 +388,7 @@ onMounted(async () => { | |||
} | |||
} | |||
.money { | |||
margin-bottom: 30px; | |||
margin-bottom: 10px; | |||
font-size: 20px; | |||
color: #7c7c7a; | |||
cursor: pointer; | |||
@@ -302,7 +400,7 @@ onMounted(async () => { | |||
} | |||
} | |||
.time { | |||
margin-bottom: 30px; | |||
margin-bottom: 10px; | |||
font-size: 20px; | |||
color: #7c7c7a; | |||
cursor: pointer; | |||
@@ -325,10 +423,12 @@ onMounted(async () => { | |||
} | |||
} | |||
.authority { | |||
cursor: pointer; | |||
margin-top: 10px; | |||
&-item { | |||
cursor: pointer; | |||
padding: 20px 10px; | |||
font-weight: 700; | |||
font-size: 18px; | |||
padding: 5px 10px; | |||
span { | |||
cursor: pointer; | |||
color: #7c7c7a; | |||
@@ -344,7 +444,7 @@ onMounted(async () => { | |||
} | |||
} | |||
} | |||
// 支付弹窗 | |||
.payDialog { | |||
display: flex; | |||
position: relative; | |||
@@ -387,6 +487,7 @@ onMounted(async () => { | |||
} | |||
} | |||
} | |||
// 二维码弹窗 | |||
.orderCodeDialog { | |||
width: 100%; | |||
.codeImg { | |||
@@ -18,7 +18,7 @@ | |||
"types": ["vite/client", "element-plus/global", "unplugin-icons/types/vue"], | |||
"skipLibCheck": true /* Skip type checking all .d.ts files. */, | |||
"allowSyntheticDefaultImports": true /* 允许默认导入 */, | |||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */ | |||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, | |||
}, | |||
"include": ["src/**/*.ts", "src/**/*.vue", "src/types/**/*.d.ts"], | |||
"exclude": ["node_modules", "dist", "**/*.js"], | |||
@@ -22,6 +22,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { | |||
resolve: { | |||
alias: { | |||
"@": pathSrc, | |||
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js' | |||
}, | |||
}, | |||
css: { | |||