|
|
@@ -2,21 +2,7 @@
|
|
|
<div class="login">
|
|
|
<!-- 语言切换 -->
|
|
|
<div class="login__lang">
|
|
|
- <el-dropdown @command="handleLanguage">
|
|
|
- <span class="lang-trigger">
|
|
|
- <Icon icon="mdi:translate" width="18" height="18" />
|
|
|
- {{ currentLangLabel }}
|
|
|
- <el-icon><ArrowDown /></el-icon>
|
|
|
- </span>
|
|
|
- <template #dropdown>
|
|
|
- <el-dropdown-menu>
|
|
|
- <el-dropdown-item command="zh-cn" :class="{ active: appStore.language === 'zh-cn' }">
|
|
|
- 简体中文
|
|
|
- </el-dropdown-item>
|
|
|
- <el-dropdown-item command="en" :class="{ active: appStore.language === 'en' }">English</el-dropdown-item>
|
|
|
- </el-dropdown-menu>
|
|
|
- </template>
|
|
|
- </el-dropdown>
|
|
|
+ <LangDropdown />
|
|
|
</div>
|
|
|
|
|
|
<div class="login__card">
|
|
|
@@ -66,29 +52,19 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive, onMounted, watch, computed } from 'vue'
|
|
|
+import { ref, reactive, onMounted, watch } from 'vue'
|
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
|
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
|
|
-import { User, Lock, ArrowDown } from '@element-plus/icons-vue'
|
|
|
-import { Icon } from '@iconify/vue'
|
|
|
+import { User, Lock } from '@element-plus/icons-vue'
|
|
|
+import LangDropdown from '@/components/LangDropdown.vue'
|
|
|
import { useUserStore } from '@/store/user'
|
|
|
-import { useAppStore } from '@/store/app'
|
|
|
import type { LoginParams } from '@/types'
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const route = useRoute()
|
|
|
const userStore = useUserStore()
|
|
|
-const appStore = useAppStore()
|
|
|
const { t } = useI18n()
|
|
|
-// 语言切换
|
|
|
-const currentLangLabel = computed(() => {
|
|
|
- return appStore.language === 'zh-cn' ? '简体中文' : 'English'
|
|
|
-})
|
|
|
-
|
|
|
-function handleLanguage(lang: string) {
|
|
|
- appStore.changeLanguage(lang)
|
|
|
-}
|
|
|
|
|
|
const version = __APP_VERSION__
|
|
|
|
|
|
@@ -131,17 +107,12 @@ async function handleLogin() {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 记住我 - 保存/读取登录信息
|
|
|
+// 记住我 - 只保存用户名
|
|
|
const REMEMBER_KEY = 'login_remember'
|
|
|
|
|
|
function saveLoginInfo() {
|
|
|
if (rememberMe.value) {
|
|
|
- const data = {
|
|
|
- username: loginForm.username,
|
|
|
- password: btoa(loginForm.password),
|
|
|
- remember: true
|
|
|
- }
|
|
|
- localStorage.setItem(REMEMBER_KEY, JSON.stringify(data))
|
|
|
+ localStorage.setItem(REMEMBER_KEY, loginForm.username)
|
|
|
} else {
|
|
|
localStorage.removeItem(REMEMBER_KEY)
|
|
|
}
|
|
|
@@ -150,14 +121,8 @@ function saveLoginInfo() {
|
|
|
function loadLoginInfo() {
|
|
|
const saved = localStorage.getItem(REMEMBER_KEY)
|
|
|
if (saved) {
|
|
|
- try {
|
|
|
- const data = JSON.parse(saved)
|
|
|
- loginForm.username = data.username || ''
|
|
|
- loginForm.password = data.password ? atob(data.password) : ''
|
|
|
- rememberMe.value = data.remember ?? true
|
|
|
- } catch {
|
|
|
- localStorage.removeItem(REMEMBER_KEY)
|
|
|
- }
|
|
|
+ loginForm.username = saved
|
|
|
+ rememberMe.value = true
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -195,21 +160,15 @@ function goHelp() {
|
|
|
right: 24px;
|
|
|
z-index: 10;
|
|
|
|
|
|
- .lang-trigger {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 6px;
|
|
|
+ // 覆盖 LangDropdown 组件的 CSS 变量 (深色主题)
|
|
|
+ --lang-color: #e5e7eb;
|
|
|
+ --lang-hover-bg: rgba(255, 255, 255, 0.18);
|
|
|
+ --lang-hover-color: #fff;
|
|
|
+
|
|
|
+ :deep(.lang-trigger) {
|
|
|
+ background: rgba(255, 255, 255, 0.1);
|
|
|
padding: 8px 12px;
|
|
|
border-radius: 8px;
|
|
|
- background: rgba(255, 255, 255, 0.1);
|
|
|
- color: #e5e7eb;
|
|
|
- font-size: 13px;
|
|
|
- cursor: pointer;
|
|
|
- transition: background 0.2s;
|
|
|
-
|
|
|
- &:hover {
|
|
|
- background: rgba(255, 255, 255, 0.18);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|