152 lines
5.6 KiB
Vue
152 lines
5.6 KiB
Vue
<template>
|
||
<div class="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||
<div class="max-w-md w-full space-y-8">
|
||
<div>
|
||
<div class="mx-auto h-12 w-12 flex items-center justify-center rounded-full bg-blue-100">
|
||
<svg class="h-8 w-8 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 002 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
|
||
</svg>
|
||
</div>
|
||
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||
管理员登录
|
||
</h2>
|
||
<p class="mt-2 text-center text-sm text-gray-600">
|
||
请使用管理员账户登录系统
|
||
</p>
|
||
</div>
|
||
|
||
<form class="mt-8 space-y-6" @submit.prevent="handleLogin">
|
||
<input type="hidden" name="remember" value="true">
|
||
<div class="rounded-md shadow-sm -space-y-px">
|
||
<div>
|
||
<label for="username" class="sr-only">用户名</label>
|
||
<input
|
||
id="username"
|
||
name="username"
|
||
type="text"
|
||
autocomplete="username"
|
||
required
|
||
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
|
||
placeholder="用户名/邮箱"
|
||
v-model="loginForm.username"
|
||
>
|
||
</div>
|
||
<div>
|
||
<label for="password" class="sr-only">密码</label>
|
||
<input
|
||
id="password"
|
||
name="password"
|
||
type="password"
|
||
autocomplete="current-password"
|
||
required
|
||
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
|
||
placeholder="密码"
|
||
v-model="loginForm.password"
|
||
>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 错误提示 -->
|
||
<div v-if="errorMessage" class="rounded-md bg-red-50 p-4">
|
||
<div class="flex">
|
||
<div class="flex-shrink-0">
|
||
<svg class="h-5 w-5 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||
</svg>
|
||
</div>
|
||
<div class="ml-3">
|
||
<h3 class="text-sm font-medium text-red-800">
|
||
登录失败
|
||
</h3>
|
||
<div class="mt-2 text-sm text-red-700">
|
||
<p>{{ errorMessage }}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<button
|
||
type="submit"
|
||
:disabled="loading"
|
||
class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||
>
|
||
<span class="absolute left-0 inset-y-0 flex items-center pl-3">
|
||
<svg class="h-5 w-5 text-blue-500 group-hover:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-6 6c-3 0-5.5-1-5.5-1s2.5-1 5.5-1a6 6 0 016-6zM9 7a2 2 0 012 2m4 0a6 6 0 01-6 6c-3 0-5.5-1-5.5-1s2.5-1 5.5-1a6 6 0 016-6z"></path>
|
||
</svg>
|
||
</span>
|
||
{{ loading ? '登录中...' : '登录' }}
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 测试账户信息 -->
|
||
<div class="mt-6 bg-blue-50 border border-blue-200 rounded-md p-4">
|
||
<h4 class="text-sm font-medium text-blue-900 mb-2">测试账户信息</h4>
|
||
<div class="text-xs text-blue-800 space-y-1">
|
||
<p><strong>管理员账户:</strong>admin@example.com</p>
|
||
<p><strong>密码:</strong>admin123</p>
|
||
<p class="text-blue-600 mt-2">* 如果数据库中没有管理员账户,系统将自动创建</p>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
// 设置页面元数据,禁用默认布局
|
||
definePageMeta({
|
||
layout: false
|
||
})
|
||
|
||
// 页面标题
|
||
useHead({
|
||
title: '管理员登录 - 翻译管理系统'
|
||
})
|
||
|
||
// 导入认证函数
|
||
const { login } = useAuth()
|
||
|
||
// 响应式数据
|
||
const loginForm = ref({
|
||
username: '',
|
||
password: ''
|
||
})
|
||
|
||
const loading = ref(false)
|
||
const errorMessage = ref('')
|
||
|
||
// 登录处理函数
|
||
const handleLogin = async () => {
|
||
// 清空之前的提示
|
||
errorMessage.value = ''
|
||
|
||
// 验证输入
|
||
if (!loginForm.value.username || !loginForm.value.password) {
|
||
errorMessage.value = '请输入用户名和密码'
|
||
return
|
||
}
|
||
|
||
loading.value = true
|
||
|
||
try {
|
||
// 使用真正的Supabase认证
|
||
const user = await login(loginForm.value.username, loginForm.value.password)
|
||
|
||
if (user) {
|
||
console.log('登录成功,用户信息:', user)
|
||
// 跳转到仪表板
|
||
await navigateTo('/dashboard', { replace: true })
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('登录失败:', error)
|
||
errorMessage.value = error.message || '登录失败,请检查用户名和密码'
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|