<template>
|
<div class="login">
|
<div class="login-inner">
|
<!-- Logo:紫色渐变圆角方框 -->
|
<div class="login-logo-wrap">
|
<img :src="LOGO" alt="" class="login-logo" />
|
</div>
|
<h1 class="login-title">{{ $t('Welcome Back') }}</h1>
|
<p class="login-signup">
|
{{ $t('noAccount') }}
|
<router-link to="/register" class="login-signup-link">{{ $t('Sign up') }}</router-link>
|
</p>
|
<p class="login-lang" @click="onRoute('/language')">{{ currentLocaleLabel }}</p>
|
|
<!-- 邮箱 -->
|
<div class="login-field">
|
<input
|
v-model="username"
|
type="text"
|
class="login-input"
|
:placeholder="$t('entryEmail')"
|
autocomplete="email"
|
@keyup.enter="verifyLogin"
|
/>
|
</div>
|
<!-- 密码 + 眼睛 -->
|
<div class="login-field login-field-pwd">
|
<input
|
v-model="password"
|
:type="passwordVisible ? 'text' : 'password'"
|
class="login-input"
|
:placeholder="$t('请输入登录密码')"
|
autocomplete="current-password"
|
@keyup.enter="verifyLogin"
|
/>
|
<span class="login-eye" @click="passwordVisible = !passwordVisible">
|
<van-icon :name="passwordVisible ? 'eye-o' : 'closed-eye'" size="20" />
|
</span>
|
</div>
|
|
<div class="login-options">
|
<label class="login-remember" @click.prevent="rememberMe = !rememberMe">
|
<img :src="rememberMe ? checkImgChecked : checkImg" alt="" class="login-remember-icon" />
|
<span>{{ $t('Remember me') }}</span>
|
</label>
|
<span class="login-forgot" @click="onRoute('/forget')">{{ $t('forgetPassword') }}</span>
|
</div>
|
|
<button class="login-btn" @click="verifyLogin">{{ $t('login') }}</button>
|
|
<p class="login-version">{{ versionText }}</p>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { _loginUser } from "@/service/login.api";
|
import { GET_USERINFO } from '@/store/types.store';
|
import { useUserStore } from '@/store/user';
|
import { useI18n } from 'vue-i18n';
|
import { ref, computed } from 'vue';
|
import { useRouter } from 'vue-router';
|
import { showToast } from "vant";
|
import store from '@/store/store';
|
import { LOGO } from "@/config";
|
import checkImg from '@/assets/imgs/new/check.png';
|
import checkImgChecked from '@/assets/imgs/new/checked.png';
|
|
const { t, locale } = useI18n();
|
const router = useRouter();
|
const userStore = useUserStore();
|
|
const versionText = 'Version: 198';
|
|
const localeLabels = { en: 'English', cn: '中文', Korean: '한국인', Japanese: 'やまと', de: 'Deutsch', French: 'Français', Italy: 'Italiano' };
|
const currentLocaleLabel = computed(() => localeLabels[locale.value] || locale.value || 'English');
|
|
const username = ref('');
|
const password = ref('');
|
const rememberMe = ref(false);
|
const passwordVisible = ref(false);
|
const onRoute = (path) => {
|
router.push(path);
|
};
|
|
const verifyLogin = () => {
|
if (!username.value) {
|
showToast(t('entryEmail'));
|
return;
|
}
|
if (!password.value) {
|
showToast(t('请输入登录密码'));
|
return;
|
}
|
loginUser();
|
};
|
|
const loginUser = () => {
|
_loginUser({
|
userName: username.value,
|
passWord: password.value,
|
type: '3'
|
}).then((res) => {
|
userStore[GET_USERINFO](res);
|
store.commit('user/SET_USERINFO', res);
|
router.push('/');
|
}).catch((res) => {
|
console.log(res);
|
});
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.login {
|
min-height: 100vh;
|
background: #fff;
|
padding: 40px 24px 24px;
|
box-sizing: border-box;
|
}
|
|
.login-inner {
|
max-width: 400px;
|
margin: 0 auto;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
}
|
|
/* Logo:紫色渐变圆角方框 */
|
.login-logo-wrap {
|
width: 72px;
|
height: 72px;
|
border-radius: 18px;
|
background: linear-gradient(135deg, #2c1a5c 0%, #5a37a5 100%);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-bottom: 24px;
|
}
|
.login-logo {
|
width: 44px;
|
height: 44px;
|
object-fit: contain;
|
}
|
|
.login-title {
|
font-size: 26px;
|
font-weight: 700;
|
color: #000;
|
margin: 0 0 8px;
|
}
|
|
.login-signup {
|
font-size: 14px;
|
color: #4a4a4a;
|
margin: 0 0 6px;
|
}
|
.login-signup-link {
|
color: #8a2be2;
|
cursor: pointer;
|
text-decoration: none;
|
}
|
.login-signup-link:hover {
|
color: #7b2be2;
|
}
|
|
.login-lang {
|
font-size: 13px;
|
color: #9b9b9b;
|
margin: 0 0 32px;
|
cursor: pointer;
|
}
|
|
/* 输入框 */
|
.login-field {
|
width: 100%;
|
margin-bottom: 16px;
|
position: relative;
|
}
|
.login-field-pwd {
|
margin-bottom: 20px;
|
}
|
.login-input {
|
width: 100%;
|
height: 48px;
|
padding: 0 16px;
|
box-sizing: border-box;
|
font-size: 15px;
|
color: #333;
|
background: #f6f5fa;
|
border: none;
|
border-radius: 10px;
|
outline: none;
|
}
|
.login-input::placeholder {
|
color: #9b9b9b;
|
}
|
.login-eye {
|
position: absolute;
|
right: 16px;
|
top: 50%;
|
transform: translateY(-50%);
|
color: #6e6e6e;
|
cursor: pointer;
|
}
|
|
/* Remember me + Forgot password */
|
.login-options {
|
width: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 32px;
|
}
|
.login-remember {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
font-size: 14px;
|
color: #4a4a4a;
|
cursor: pointer;
|
}
|
.login-remember-icon {
|
width: 18px;
|
height: 18px;
|
flex-shrink: 0;
|
}
|
.login-forgot {
|
font-size: 14px;
|
color: #4a4a4a;
|
cursor: pointer;
|
}
|
|
/* Log In 按钮:紫色渐变 */
|
.login-btn {
|
width: 100%;
|
height: 48px;
|
border: none;
|
border-radius: 6px;
|
background: linear-gradient(90deg, #a443cf, #5e2bc8);
|
color: #fff;
|
font-size: 16px;
|
font-weight: 700;
|
cursor: pointer;
|
}
|
|
/* Version */
|
.login-version {
|
margin-top: 48px;
|
font-size: 12px;
|
color: #9b9b9b;
|
}
|
</style>
|