@@ -5,13 +5,8 @@ | |||
"type": "module", | |||
"scripts": { | |||
"dev": "vite serve --mode development", | |||
"build:prod": "vite build --mode production &&vue-tsc --noEmit", | |||
"prepare": "husky install", | |||
"lint:eslint": "eslint --fix --ext .ts,.js,.vue ./src ", | |||
"lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"", | |||
"lint:stylelint": "stylelint \"**/*.{css,scss,vue}\" --fix", | |||
"lint:lint-staged": "lint-staged", | |||
"commit": "git-cz" | |||
"build:dev": "vite build --mode development &&vue-tsc --noEmit", | |||
"build:prod": "vite build --mode production &&vue-tsc --noEmit" | |||
}, | |||
"config": { | |||
"commitizen": { | |||
@@ -1,22 +1,3 @@ | |||
<script setup lang="ts"> | |||
import { useI18n } from "vue-i18n"; | |||
import SvgIcon from "@/components/SvgIcon/index.vue"; | |||
import { useAppStore } from "@/store/modules/app"; | |||
const appStore = useAppStore(); | |||
const { locale } = useI18n(); | |||
function handleLanguageChange(lang: string) { | |||
locale.value = lang; | |||
appStore.changeLanguage(lang); | |||
if (lang == "en") { | |||
ElMessage.success("Switch Language Successful!"); | |||
} else { | |||
ElMessage.success("切换语言成功!"); | |||
} | |||
} | |||
</script> | |||
<template> | |||
<el-dropdown class="outSide" trigger="click" @command="handleLanguageChange"> | |||
<div> | |||
@@ -38,6 +19,25 @@ function handleLanguageChange(lang: string) { | |||
</el-dropdown> | |||
</template> | |||
<script setup lang="ts"> | |||
import { useI18n } from "vue-i18n"; | |||
import SvgIcon from "@/components/SvgIcon/index.vue"; | |||
import { useAppStore } from "@/store/modules/app"; | |||
const appStore = useAppStore(); | |||
const { locale } = useI18n(); | |||
function handleLanguageChange(lang: string) { | |||
locale.value = lang; | |||
appStore.changeLanguage(lang); | |||
if (lang == "en") { | |||
ElMessage.success("Switch Language Successful!"); | |||
} else { | |||
ElMessage.success("切换语言成功!"); | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.outSide { | |||
cursor: pointer; | |||
@@ -7,11 +7,13 @@ export default { | |||
// 登录页面国际化 | |||
login: { | |||
title: "Metavatar-PC", | |||
title: "Metavatar-PC Sign in", | |||
username: "Username", | |||
password: "Password", | |||
login: "Login", | |||
login: "Sign in", | |||
verifyCode: "Verify Code", | |||
signUp: "Don't have an account? Sign up here", | |||
forgetPwd: "I forgot my password", | |||
}, | |||
// 导航栏国际化 | |||
@@ -51,6 +53,7 @@ export default { | |||
account: { | |||
title: "My Account", | |||
reSetPwd: "Reset Password", | |||
until: "until", | |||
getMore: "UPGRADE", | |||
copyCode: "Copy invitation code", | |||
saveCode: "Save QR code", | |||
@@ -67,5 +70,13 @@ export default { | |||
// 商店 | |||
shop: { | |||
title: "Shop", | |||
Trial: "Trial", | |||
Lite: "Lite", | |||
Pro: "Pro", | |||
Adv: "Advanced", | |||
Ent: "Enterprise", | |||
selectPlan: "SELECT PLAN", | |||
WeChatPay: "WeChatPay", | |||
Alipay: "Alipay", | |||
}, | |||
}; |
@@ -7,11 +7,13 @@ export default { | |||
// 登录页面国际化 | |||
login: { | |||
title: "Metavatar-PC", | |||
title: "Metavatar-PC 登录", | |||
username: "用户名", | |||
password: "密码", | |||
login: "登 录", | |||
verifyCode: "验证码", | |||
signUp: "没有账号?现在加入!", | |||
forgetPwd: "忘记密码", | |||
}, | |||
// 导航栏国际化 | |||
@@ -51,6 +53,7 @@ export default { | |||
account: { | |||
title: "个人账户", | |||
reSetPwd: "修改密码", | |||
until: "有效期至", | |||
getMore: "升级套餐", | |||
copyCode: "复制邀请码", | |||
saveCode: "保存二维码", | |||
@@ -67,5 +70,13 @@ export default { | |||
// 商店 | |||
shop: { | |||
title: "商店", | |||
Trial: "尝鲜版", | |||
Lite: "基础版", | |||
Pro: "专业版", | |||
Adv: "加强版", | |||
Ent: "企业版", | |||
selectPlan: "方案选择", | |||
WeChatPay: "微信支付", | |||
Alipay: "支付宝支付", | |||
}, | |||
}; |
@@ -79,8 +79,14 @@ import { RouteLocationRaw, useRoute, useRouter } from "vue-router"; | |||
import { useAppStore } from "@/store/modules/app"; | |||
import { useTagsViewStore } from "@/store/modules/tagsView"; | |||
import { useUserStore } from "@/store/modules/user"; | |||
import { useI18n } from "vue-i18n"; | |||
import LangSelect from "@/components/LangSelect/index.vue"; | |||
const { locale } = useI18n(); | |||
// 当前语言状态与国际化组件 | |||
const lanChange = ref(locale); | |||
const appStore = useAppStore(); | |||
const tagsViewStore = useTagsViewStore(); | |||
const userStore = useUserStore(); | |||
@@ -106,10 +112,16 @@ const { isFullscreen, toggle } = useFullscreen(); | |||
* 注销 | |||
*/ | |||
function logout() { | |||
ElMessageBox.confirm("确定注销并退出系统吗?", "提示", { | |||
confirmButtonText: "确定", | |||
cancelButtonText: "取消", | |||
type: "warning", | |||
const msg = | |||
(lanChange.value as string) == "zh-cn" | |||
? "确定退出登录吗?" | |||
: "Are you sure to log out?"; | |||
const notice = (lanChange.value as string) == "zh-cn" ? "提示" : "Notice"; | |||
const confirm = (lanChange.value as string) == "zh-cn" ? "确定" : "Confirm"; | |||
const cancel = (lanChange.value as string) == "zh-cn" ? "取消" : "Cancel"; | |||
ElMessageBox.confirm(msg, notice, { | |||
confirmButtonText: confirm, | |||
cancelButtonText: cancel, | |||
}).then(() => { | |||
userStore | |||
.logout() | |||
@@ -186,10 +198,9 @@ watch( | |||
height: 80px; | |||
padding: 0 20px; | |||
color: #fff; | |||
background-color: #fff; | |||
background-color: #000; | |||
box-shadow: 0 0 1px #0003; | |||
padding-right: 50px; | |||
.avatar { | |||
width: 30px; | |||
height: 30px; | |||
@@ -1,3 +1,60 @@ | |||
<template> | |||
<div v-if="false" class="tags-container"> | |||
<scroll-pane ref="scrollPaneRef" @scroll="handleScroll"> | |||
<router-link | |||
:class="'tags-item ' + (isActive(tag) ? 'active' : '')" | |||
v-for="tag in visitedViews" | |||
:key="tag.path" | |||
:data-path="tag.path" | |||
:to="{ path: tag.path, query: tag.query }" | |||
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" | |||
@contextmenu.prevent="openTagMenu(tag, $event)" | |||
> | |||
{{ translateRouteTitleI18n(tag.meta?.title) }} | |||
<span | |||
v-if="!isAffix(tag)" | |||
class="tags-item-close" | |||
@click.prevent.stop="closeSelectedTag(tag)" | |||
> | |||
<i-ep-close class="text-[10px]" /> | |||
</span> | |||
</router-link> | |||
</scroll-pane> | |||
<!-- tag标签操作菜单 --> | |||
<ul | |||
v-show="tagMenuVisible" | |||
class="tag-menu" | |||
:style="{ left: left + 'px', top: top + 'px' }" | |||
> | |||
<li @click="refreshSelectedTag(selectedTag)"> | |||
<svg-icon icon-class="refresh" /> | |||
刷新 | |||
</li> | |||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"> | |||
<svg-icon icon-class="close" /> | |||
关闭 | |||
</li> | |||
<li @click="closeOtherTags"> | |||
<svg-icon icon-class="close_other" /> | |||
关闭其它 | |||
</li> | |||
<li v-if="!isFirstView()" @click="closeLeftTags"> | |||
<svg-icon icon-class="close_left" /> | |||
关闭左侧 | |||
</li> | |||
<li v-if="!isLastView()" @click="closeRightTags"> | |||
<svg-icon icon-class="close_right" /> | |||
关闭右侧 | |||
</li> | |||
<li @click="closeAllTags(selectedTag)"> | |||
<svg-icon icon-class="close_all" /> | |||
关闭所有 | |||
</li> | |||
</ul> | |||
</div> | |||
</template> | |||
<script setup lang="ts"> | |||
import { | |||
getCurrentInstance, | |||
@@ -241,63 +298,6 @@ onMounted(() => { | |||
}); | |||
</script> | |||
<template> | |||
<div v-if="false" class="tags-container"> | |||
<scroll-pane ref="scrollPaneRef" @scroll="handleScroll"> | |||
<router-link | |||
:class="'tags-item ' + (isActive(tag) ? 'active' : '')" | |||
v-for="tag in visitedViews" | |||
:key="tag.path" | |||
:data-path="tag.path" | |||
:to="{ path: tag.path, query: tag.query }" | |||
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" | |||
@contextmenu.prevent="openTagMenu(tag, $event)" | |||
> | |||
{{ translateRouteTitleI18n(tag.meta?.title) }} | |||
<span | |||
v-if="!isAffix(tag)" | |||
class="tags-item-close" | |||
@click.prevent.stop="closeSelectedTag(tag)" | |||
> | |||
<i-ep-close class="text-[10px]" /> | |||
</span> | |||
</router-link> | |||
</scroll-pane> | |||
<!-- tag标签操作菜单 --> | |||
<ul | |||
v-show="tagMenuVisible" | |||
class="tag-menu" | |||
:style="{ left: left + 'px', top: top + 'px' }" | |||
> | |||
<li @click="refreshSelectedTag(selectedTag)"> | |||
<svg-icon icon-class="refresh" /> | |||
刷新 | |||
</li> | |||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"> | |||
<svg-icon icon-class="close" /> | |||
关闭 | |||
</li> | |||
<li @click="closeOtherTags"> | |||
<svg-icon icon-class="close_other" /> | |||
关闭其它 | |||
</li> | |||
<li v-if="!isFirstView()" @click="closeLeftTags"> | |||
<svg-icon icon-class="close_left" /> | |||
关闭左侧 | |||
</li> | |||
<li v-if="!isLastView()" @click="closeRightTags"> | |||
<svg-icon icon-class="close_right" /> | |||
关闭右侧 | |||
</li> | |||
<li @click="closeAllTags(selectedTag)"> | |||
<svg-icon icon-class="close_all" /> | |||
关闭所有 | |||
</li> | |||
</ul> | |||
</div> | |||
</template> | |||
<style lang="scss" scoped> | |||
.tags-container { | |||
width: 100%; | |||
@@ -2,8 +2,10 @@ | |||
export {} | |||
declare global { | |||
const EffectScope: typeof import('vue')['EffectScope'] | |||
const ElForm: typeof import('element-plus/es')['ElForm'] | |||
const ElMessage: typeof import('element-plus/es')['ElMessage'] | |||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | |||
const ElTree: typeof import('element-plus/es')['ElTree'] | |||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | |||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | |||
const computed: typeof import('vue')['computed'] | |||
@@ -270,8 +272,10 @@ import { UnwrapRef } from 'vue' | |||
declare module 'vue' { | |||
interface ComponentCustomProperties { | |||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | |||
readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> | |||
readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | |||
readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | |||
readonly ElTree: UnwrapRef<typeof import('element-plus/es')['ElTree']> | |||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | |||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | |||
readonly computed: UnwrapRef<typeof import('vue')['computed']> | |||
@@ -141,6 +141,7 @@ | |||
</template> | |||
<script setup> | |||
import { ref } from "vue"; | |||
import { getCurrentInstance } from "vue"; | |||
// 标题 | |||
let title = ref(""); | |||
// 上传图片 | |||
@@ -150,7 +151,7 @@ function changeFile(e) { | |||
} | |||
// $t在script中的使用 | |||
import { getCurrentInstance } from "vue"; | |||
const { | |||
appContext: { | |||
config: { globalProperties }, | |||
@@ -9,10 +9,9 @@ | |||
></video> | |||
</div> | |||
<el-form | |||
v-if="true" | |||
v-if="isLogin" | |||
ref="loginFormRef" | |||
:model="loginData" | |||
:rules="loginRules" | |||
class="login-form" | |||
> | |||
<div class="flex text-white items-center py-4"> | |||
@@ -84,15 +83,108 @@ | |||
size="default" | |||
:loading="loading" | |||
type="primary" | |||
class="w-full" | |||
class="loginBtn" | |||
@click.prevent="handleLogin" | |||
>{{ $t("login.login") }} | |||
</el-button> | |||
<!-- 账号密码提示 --> | |||
<div class="mt-4 text-white text-sm"> | |||
<span>{{ $t("login.username") }}: admin</span> | |||
<span class="ml-4"> {{ $t("login.password") }}: 123456</span> | |||
<div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | |||
<div style="margin-bottom: 5px"> | |||
<span class="join">{{ $t("login.signUp") }}</span> | |||
</div> | |||
<div> | |||
<span class="join">{{ $t("login.forgetPwd") }}</span> | |||
</div> | |||
</div> | |||
</el-form> | |||
<el-form | |||
v-if="!isLogin" | |||
ref="loginFormRef" | |||
:model="loginData" | |||
class="login-form" | |||
> | |||
<div class="flex text-white items-center py-4"> | |||
<span class="text-2xl flex-1 text-center">{{ $t("login.title") }}</span> | |||
<lang-select style="color: #fff" /> | |||
</div> | |||
<el-form-item prop="username"> | |||
<div class="p-2 text-white"> | |||
<svg-icon icon-class="user" /> | |||
</div> | |||
<el-input | |||
class="flex-1" | |||
ref="username" | |||
size="large" | |||
v-model="loginData.username" | |||
:placeholder="$t('login.username')" | |||
name="username" | |||
/> | |||
</el-form-item> | |||
<el-tooltip | |||
:disabled="isCapslock === false" | |||
content="Caps lock is On" | |||
placement="right" | |||
> | |||
<el-form-item prop="password"> | |||
<span class="p-2 text-white"> | |||
<svg-icon icon-class="password" /> | |||
</span> | |||
<el-input | |||
class="flex-1" | |||
v-model="loginData.password" | |||
placeholder="密码" | |||
:type="passwordVisible === false ? 'password' : 'input'" | |||
size="large" | |||
name="password" | |||
@keyup="checkCapslock" | |||
@keyup.enter="handleLogin" | |||
/> | |||
<span class="mr-2" @click="passwordVisible = !passwordVisible"> | |||
<svg-icon | |||
:icon-class="passwordVisible === false ? 'eye' : 'eye-open'" | |||
class="text-white cursor-pointer" | |||
/> | |||
</span> | |||
</el-form-item> | |||
</el-tooltip> | |||
<!-- 验证码 --> | |||
<el-form-item prop="verifyCode"> | |||
<span class="p-2 text-white"> | |||
<svg-icon icon-class="verify_code" /> | |||
</span> | |||
<el-input | |||
v-model="loginData.verifyCode" | |||
auto-complete="off" | |||
:placeholder="$t('login.verifyCode')" | |||
class="w-[60%]" | |||
@keyup.enter="handleLogin" | |||
/> | |||
<div class="captcha"> | |||
<img :src="captchaBase64" @click="getCaptcha" /> | |||
</div> | |||
</el-form-item> | |||
<el-button | |||
size="default" | |||
:loading="loading" | |||
type="primary" | |||
class="loginBtn" | |||
@click.prevent="handleLogin" | |||
>{{ $t("login.login") }} | |||
</el-button> | |||
<div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | |||
<div style="margin-bottom: 5px" @click="loginFlag"> | |||
<span class="join">{{ $t("login.signUp") }}</span> | |||
</div> | |||
<div> | |||
<span class="join">{{ $t("login.forgetPwd") }}</span> | |||
</div> | |||
</div> | |||
</el-form> | |||
</div> | |||
@@ -111,6 +203,11 @@ import { LocationQuery, LocationQueryValue, useRoute } from "vue-router"; | |||
import { getCaptchaApi } from "@/api/auth"; | |||
import { LoginData } from "@/api/auth/types"; | |||
import { useI18n } from "vue-i18n"; | |||
const { locale } = useI18n(); | |||
const currentLan = ref(locale); | |||
const userStore = useUserStore(); | |||
const route = useRoute(); | |||
@@ -118,19 +215,27 @@ const route = useRoute(); | |||
* 按钮loading | |||
*/ | |||
const loading = ref(false); | |||
/** | |||
* 是否大写锁定 | |||
*/ | |||
const isCapslock = ref(false); | |||
/** | |||
* 密码是否可见 | |||
*/ | |||
const passwordVisible = ref(false); | |||
/** | |||
* 验证码图片Base64字符串 | |||
*/ | |||
const captchaBase64 = ref(); | |||
/** | |||
* 登录/注册 | |||
*/ | |||
const isLogin = ref(true); | |||
/** | |||
* 登录表单引用 | |||
*/ | |||
@@ -147,6 +252,14 @@ const loginRules = { | |||
verifyCode: [{ required: true, trigger: "blur" }], | |||
}; | |||
/** | |||
* @description: 切换登录/注册状态 | |||
*/ | |||
function loginFlag() { | |||
isLogin.value = !isLogin; | |||
console.log(isLogin.value, "isLogin.value"); | |||
} | |||
/** | |||
* 密码校验器 | |||
*/ | |||
@@ -235,13 +348,15 @@ onMounted(() => { | |||
max-width: 100%; | |||
padding: 20px; | |||
overflow: hidden; | |||
backdrop-filter: blur(5px); | |||
background: linear-gradient( | |||
225deg, | |||
rgb(81 217 202 / 100%), | |||
rgb(114 100 245 / 100%) | |||
123.64deg, | |||
rgba(188, 193, 196, 0.1) -22.71%, | |||
rgba(255, 255, 255, 0.039) 70.04% | |||
); | |||
border-radius: 20px; | |||
transform: translateY(-50%); | |||
border: 1px solid #cacaca; | |||
.captcha { | |||
position: absolute; | |||
@@ -257,6 +372,54 @@ onMounted(() => { | |||
} | |||
} | |||
.loginBtn { | |||
width: 100%; | |||
height: 40px; | |||
background: linear-gradient(270deg, #4b61dc, #15d1b8); | |||
transition: all 0.3s; | |||
&:hover { | |||
transform: scale(1.02); | |||
} | |||
} | |||
.bottomBtnCN { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
padding: 0 10px; | |||
color: #fff; | |||
text-align: center; | |||
margin-top: 20px; | |||
.join { | |||
cursor: pointer; | |||
border-bottom: 2px solid #ffffff00; | |||
padding: 0 3px; | |||
padding-bottom: 2px; | |||
transition: all 0.3s; | |||
&:hover { | |||
border-bottom: 2px solid #ffffff; | |||
} | |||
} | |||
} | |||
.bottomBtnEN { | |||
padding: 0 10px; | |||
color: #fff; | |||
text-align: center; | |||
margin-top: 20px; | |||
.join { | |||
cursor: pointer; | |||
border-bottom: 2px solid #ffffff00; | |||
padding: 0 3px; | |||
padding-bottom: 2px; | |||
transition: all 0.3s; | |||
&:hover { | |||
border-bottom: 2px solid #ffffff; | |||
} | |||
} | |||
} | |||
.videoBox { | |||
position: absolute; | |||
top: 0; | |||
@@ -268,13 +431,12 @@ onMounted(() => { | |||
.el-form-item { | |||
background: rgb(0 0 0 / 10%); | |||
border: 1px solid rgb(255 255 255 / 10%); | |||
border: 1px solid #ffffff2d; | |||
border-radius: 5px; | |||
} | |||
.el-input { | |||
background: transparent; | |||
// 子组件 scoped 无效,使用 :deep | |||
:deep(.el-input__wrapper) { | |||
padding: 0; | |||
@@ -17,8 +17,13 @@ | |||
</div> | |||
<!-- 剩余次数 --> | |||
<div class="left-two border"> | |||
<div class="number">3 Videos Generation Left</div> | |||
<div class="time">Until 2023/12/31</div> | |||
<div v-if="currentLan == 'en'" class="number"> | |||
3 Videos Generation Left | |||
</div> | |||
<div v-if="currentLan == 'zh-cn'" class="number"> | |||
剩余生成视频次数:3条 | |||
</div> | |||
<div class="time">{{ $t("account.until") }} 2023/12/31</div> | |||
<div class="getMore pointer" @click="routerTo('/myStore')"> | |||
{{ $t("account.getMore") }} | |||
</div> | |||
@@ -27,12 +32,19 @@ | |||
<div class="left-three border flex justify-between"> | |||
<div class="codeImg"></div> | |||
<div class="other"> | |||
<div> | |||
Invite friends to get | |||
<div v-if="currentLan == 'en'"> | |||
<span>Invite friends to get</span> | |||
<span class="bigWord">free</span> | |||
video | |||
<span class="bigWord">Generation</span> | |||
<span>video</span> | |||
<span class="bigWord">Generation!</span> | |||
</div> | |||
<div v-if="currentLan == 'zh-cn'"> | |||
<span>邀请更多好友</span> | |||
<span class="bigWord">免费</span> | |||
<span>生成视频!</span> | |||
</div> | |||
<div class="btns"> | |||
<span class="myBtn">{{ $t("account.copyCode") }}</span> | |||
<span class="myBtn">{{ $t("account.saveCode") }}</span> | |||
@@ -80,13 +92,20 @@ | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { useI18n } from "vue-i18n"; | |||
import { useRouter } from "vue-router"; | |||
const { locale } = useI18n(); | |||
const currentLan = ref(locale); | |||
const router = useRouter(); | |||
function routerTo(url) { | |||
router.push(url); | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
height: 887px; | |||
@@ -128,7 +147,7 @@ function routerTo(url) { | |||
.password { | |||
display: inline-block; | |||
float: right; | |||
// float: right; | |||
padding: 2px 8px; | |||
border: 1px solid #000; | |||
border-radius: 5px; | |||
@@ -299,5 +318,6 @@ function routerTo(url) { | |||
.bigWord { | |||
font-size: 30px; | |||
font-weight: 700; | |||
margin: 0 10px; | |||
} | |||
</style> |
@@ -9,7 +9,7 @@ | |||
<div class="content"> | |||
<div class="title"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
{{ item.title }} | |||
{{ $t(item.title) }} | |||
</div> | |||
<div class="money"> | |||
<span class="price">{{ item.price }}元</span>/{{ | |||
@@ -21,7 +21,7 @@ | |||
>分钟/月 | |||
</div> | |||
<div class="button" :style="`background-color:${item.color} ;`"> | |||
选择方案 | |||
{{ $t("shop.selectPlan") }} | |||
</div> | |||
</div> | |||
<!-- 商品权益 --> | |||
@@ -43,7 +43,7 @@ | |||
<el-dialog v-model="showPayDialog" width="60%" center> | |||
<div class="payDialog"> | |||
<div class="left"> | |||
<div class="title">{{ presentItme.value.title }}</div> | |||
<div class="title">{{ $t(presentItme.value.title) }}</div> | |||
<div class="price"> | |||
<span>{{ presentItme.value.price }}</span> | |||
元/{{ presentItme.value.priceTime }} | |||
@@ -57,8 +57,10 @@ | |||
</div> | |||
</div> | |||
<div class="right"> | |||
<div style="background-color: #07c160">微信支付</div> | |||
<div style="background-color: #1378fe">支付宝支付</div> | |||
<div style="background-color: #07c160"> | |||
{{ $t("shop.WeChatPay") }} | |||
</div> | |||
<div style="background-color: #1378fe">{{ $t("shop.Alipay") }}</div> | |||
<div style="background-color: #0070ba">Paypal</div> | |||
</div> | |||
</div> | |||
@@ -70,13 +72,13 @@ const title = ref(""); | |||
const list = reactive([ | |||
{ | |||
color: "#f3af00", | |||
title: "基础款", | |||
title: "shop.Lite", | |||
icon: "", | |||
price: "0", | |||
priceTime: "14天", | |||
time: "5", | |||
authority: [ | |||
"D-ID 水印", | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
@@ -84,13 +86,13 @@ const list = reactive([ | |||
}, | |||
{ | |||
color: "#c971ff", | |||
title: "升级款", | |||
title: "shop.Pro", | |||
icon: "", | |||
price: "10", | |||
priceTime: "30天", | |||
time: "10", | |||
authority: [ | |||
"D-ID 水印", | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
@@ -99,13 +101,13 @@ const list = reactive([ | |||
}, | |||
{ | |||
color: "#7b61ff", | |||
title: "豪华款", | |||
title: "shop.Adv", | |||
icon: "", | |||
price: "20", | |||
priceTime: "30天", | |||
time: "15", | |||
authority: [ | |||
"D-ID 水印", | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||
@@ -115,13 +117,13 @@ const list = reactive([ | |||
}, | |||
{ | |||
color: "#000", | |||
title: "探索款", | |||
title: "shop.Ent", | |||
icon: "", | |||
price: "50", | |||
priceTime: "30天", | |||
time: "40", | |||
authority: [ | |||
"D-ID 水印", | |||
"Metavatar 水印", | |||
"高级和标准演示器", | |||
"15 个 AI 演示提示", | |||
"AI 脚本世代", | |||