|
|
@@ -31,18 +31,6 @@
|
|
|
autocomplete="current-password"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
- <el-form-item v-if="captchaEnabled" prop="code">
|
|
|
- <div class="login__captcha">
|
|
|
- <el-input
|
|
|
- v-model="loginForm.code"
|
|
|
- placeholder="请输入验证码"
|
|
|
- size="large"
|
|
|
- :prefix-icon="Key"
|
|
|
- @keyup.enter="handleLogin"
|
|
|
- />
|
|
|
- <img :src="codeUrl" class="login__captcha-img" @click="getCode" alt="captcha" />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
<div class="login__actions">
|
|
|
<el-checkbox v-model="rememberMe">记住我</el-checkbox>
|
|
|
<span class="login__forgot" @click="goHelp">忘记密码?</span>
|
|
|
@@ -62,8 +50,9 @@
|
|
|
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, Key } from '@element-plus/icons-vue'
|
|
|
+import { User, Lock } from '@element-plus/icons-vue'
|
|
|
import { useUserStore } from '@/store/user'
|
|
|
+import type { LoginParams } from '@/types'
|
|
|
|
|
|
const router = useRouter()
|
|
|
const route = useRoute()
|
|
|
@@ -73,26 +62,16 @@ const version = __APP_VERSION__
|
|
|
|
|
|
const loginFormRef = ref<FormInstance>()
|
|
|
const loading = ref(false)
|
|
|
-const captchaEnabled = ref(false)
|
|
|
-const codeUrl = ref('')
|
|
|
const rememberMe = ref(true)
|
|
|
|
|
|
-const loginForm = reactive({
|
|
|
+const loginForm = reactive<LoginParams>({
|
|
|
username: '',
|
|
|
- password: '',
|
|
|
- code: '',
|
|
|
- uuid: ''
|
|
|
+ password: ''
|
|
|
})
|
|
|
|
|
|
const loginRules: FormRules = {
|
|
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
|
|
- password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
|
|
- code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
|
|
|
-}
|
|
|
-
|
|
|
-// Hono API 不支持验证码,禁用验证码功能
|
|
|
-function getCode() {
|
|
|
- captchaEnabled.value = false
|
|
|
+ password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
|
|
}
|
|
|
|
|
|
async function handleLogin() {
|
|
|
@@ -104,20 +83,15 @@ async function handleLogin() {
|
|
|
try {
|
|
|
const res = await userStore.loginAction(loginForm)
|
|
|
if (res.code === 200) {
|
|
|
- saveLoginInfo() // 保存登录信息
|
|
|
+ saveLoginInfo()
|
|
|
ElMessage.success('登录成功')
|
|
|
const redirect = (route.query.redirect as string) || '/'
|
|
|
router.push(redirect)
|
|
|
} else {
|
|
|
ElMessage.error(res.message || '登录失败')
|
|
|
- if (captchaEnabled.value) {
|
|
|
- getCode()
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- if (captchaEnabled.value) {
|
|
|
- getCode()
|
|
|
}
|
|
|
+ } catch (error: any) {
|
|
|
+ ElMessage.error(error.message || '登录失败,请检查网络')
|
|
|
} finally {
|
|
|
loading.value = false
|
|
|
}
|
|
|
@@ -132,7 +106,7 @@ function saveLoginInfo() {
|
|
|
if (rememberMe.value) {
|
|
|
const data = {
|
|
|
username: loginForm.username,
|
|
|
- password: btoa(loginForm.password), // base64 编码
|
|
|
+ password: btoa(loginForm.password),
|
|
|
remember: true
|
|
|
}
|
|
|
localStorage.setItem(REMEMBER_KEY, JSON.stringify(data))
|
|
|
@@ -147,7 +121,7 @@ function loadLoginInfo() {
|
|
|
try {
|
|
|
const data = JSON.parse(saved)
|
|
|
loginForm.username = data.username || ''
|
|
|
- loginForm.password = data.password ? atob(data.password) : '' // base64 解码
|
|
|
+ loginForm.password = data.password ? atob(data.password) : ''
|
|
|
rememberMe.value = data.remember ?? true
|
|
|
} catch {
|
|
|
localStorage.removeItem(REMEMBER_KEY)
|
|
|
@@ -156,11 +130,9 @@ function loadLoginInfo() {
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- getCode()
|
|
|
loadLoginInfo()
|
|
|
})
|
|
|
|
|
|
-// 取消勾选时清除保存的信息
|
|
|
watch(rememberMe, (val) => {
|
|
|
if (!val) {
|
|
|
localStorage.removeItem(REMEMBER_KEY)
|
|
|
@@ -179,8 +151,7 @@ function goHelp() {
|
|
|
display: grid;
|
|
|
grid-template-columns: 1fr;
|
|
|
place-items: center;
|
|
|
- background:
|
|
|
- radial-gradient(1200px 600px at 100% 0%, rgba(102, 126, 234, 0.25), transparent 60%),
|
|
|
+ background: radial-gradient(1200px 600px at 100% 0%, rgba(102, 126, 234, 0.25), transparent 60%),
|
|
|
radial-gradient(1000px 500px at 0% 100%, rgba(118, 75, 162, 0.25), transparent 60%),
|
|
|
linear-gradient(135deg, #0f172a 0%, #111827 60%, #0b1220 100%);
|
|
|
padding: 24px;
|
|
|
@@ -190,8 +161,7 @@ function goHelp() {
|
|
|
.login__bg {
|
|
|
position: absolute;
|
|
|
inset: -10% -10% -10% -10%;
|
|
|
- background:
|
|
|
- radial-gradient(800px 400px at 50% -10%, rgba(59, 130, 246, 0.15), transparent 60%),
|
|
|
+ background: radial-gradient(800px 400px at 50% -10%, rgba(59, 130, 246, 0.15), transparent 60%),
|
|
|
radial-gradient(700px 350px at 100% 100%, rgba(236, 72, 153, 0.12), transparent 60%);
|
|
|
filter: blur(40px);
|
|
|
pointer-events: none;
|
|
|
@@ -245,23 +215,6 @@ function goHelp() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.login__captcha {
|
|
|
- display: flex;
|
|
|
- width: 100%;
|
|
|
- gap: 10px;
|
|
|
- .el-input {
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
-}
|
|
|
-.login__captcha-img {
|
|
|
- width: 108px;
|
|
|
- height: 44px;
|
|
|
- border-radius: 8px;
|
|
|
- border: 1px solid #e5e7eb;
|
|
|
- background: #fff;
|
|
|
- cursor: pointer;
|
|
|
-}
|
|
|
-
|
|
|
.login__actions {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|