优化
This commit is contained in:
@@ -9,7 +9,12 @@
|
|||||||
"mcp__server-mysql__execute",
|
"mcp__server-mysql__execute",
|
||||||
"Bash(git rm:*)",
|
"Bash(git rm:*)",
|
||||||
"Bash(git add:*)",
|
"Bash(git add:*)",
|
||||||
"Bash(npx tsc:*)"
|
"Bash(npx tsc:*)",
|
||||||
|
"Bash(pnpm vue-tsc:*)",
|
||||||
|
"Bash(find node_modules/.pnpm -name *.mjs -path *vue-router*)",
|
||||||
|
"Bash(grep -r \"routeMeta\\\\|definePage\\\\|<route\" node_modules/.pnpm/vue-router*/node_modules/vue-router/dist/*.mjs)",
|
||||||
|
"Bash(grep -r \"route block\\\\|customBlock\\\\|defineCustomBlock\" node_modules/.pnpm/vue-router*/dist/*.mjs)",
|
||||||
|
"Bash(find node_modules/.pnpm -path *vue-router* -name *.mjs)"
|
||||||
],
|
],
|
||||||
"additionalDirectories": [
|
"additionalDirectories": [
|
||||||
"/Users/sion/Desktop/projects/monisuo/monisuo-admin/.git"
|
"/Users/sion/Desktop/projects/monisuo/monisuo-admin/.git"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function useAuth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toHome() {
|
function toHome() {
|
||||||
router.push({ path: '/dashboard' })
|
router.push({ path: '/monisuo/dashboard' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login(username: string, password: string) {
|
async function login(username: string, password: string) {
|
||||||
|
|||||||
8
monisuo-admin/src/pages/auth.vue
Normal file
8
monisuo-admin/src/pages/auth.vue
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<template>
|
||||||
|
<router-view />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
meta:
|
||||||
|
layout: false
|
||||||
|
</route>
|
||||||
97
monisuo-admin/src/pages/auth/sign-in.vue
Normal file
97
monisuo-admin/src/pages/auth/sign-in.vue
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Eye, EyeOff, Lock, User } from 'lucide-vue-next'
|
||||||
|
|
||||||
|
import { useAuth } from '@/composables/use-auth'
|
||||||
|
|
||||||
|
const username = ref('')
|
||||||
|
const password = ref('')
|
||||||
|
const showPassword = ref(false)
|
||||||
|
|
||||||
|
const { login, loading, error, isLogin } = useAuth()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
// 已登录则跳转首页
|
||||||
|
watchEffect(() => {
|
||||||
|
if (unref(isLogin)) {
|
||||||
|
router.push('/dashboard')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
if (!username.value || !password.value)
|
||||||
|
return
|
||||||
|
await login(username.value, password.value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-muted p-4">
|
||||||
|
<UiCard class="w-full max-w-md">
|
||||||
|
<UiCardHeader class="space-y-1 text-center">
|
||||||
|
<div class="flex justify-center mb-4">
|
||||||
|
<div class="size-12 rounded-xl bg-primary flex items-center justify-center">
|
||||||
|
<Lock class="size-6 text-primary-foreground" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<UiCardTitle class="text-2xl font-bold">
|
||||||
|
Monisuo Admin
|
||||||
|
</UiCardTitle>
|
||||||
|
<UiCardDescription>
|
||||||
|
管理员登录
|
||||||
|
</UiCardDescription>
|
||||||
|
</UiCardHeader>
|
||||||
|
<UiCardContent>
|
||||||
|
<form @submit.prevent="handleSubmit" class="space-y-4">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<UiLabel for="username">用户名</UiLabel>
|
||||||
|
<div class="relative">
|
||||||
|
<User class="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
|
||||||
|
<UiInput
|
||||||
|
id="username"
|
||||||
|
v-model="username"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入用户名"
|
||||||
|
class="pl-9"
|
||||||
|
:disabled="loading"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<UiLabel for="password">密码</UiLabel>
|
||||||
|
<div class="relative">
|
||||||
|
<Lock class="absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
|
||||||
|
<UiInput
|
||||||
|
id="password"
|
||||||
|
v-model="password"
|
||||||
|
:type="showPassword ? 'text' : 'password'"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
class="pl-9 pr-9"
|
||||||
|
:disabled="loading"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
|
||||||
|
@click="showPassword = !showPassword"
|
||||||
|
>
|
||||||
|
<Eye v-if="!showPassword" class="size-4" />
|
||||||
|
<EyeOff v-else class="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<UiAlert v-if="error" variant="destructive">
|
||||||
|
<UiAlertDescription>{{ error }}</UiAlertDescription>
|
||||||
|
</UiAlert>
|
||||||
|
<UiButton type="submit" class="w-full" :disabled="loading">
|
||||||
|
<UiSpinner v-if="loading" class="size-4 mr-2" />
|
||||||
|
{{ loading ? '登录中...' : '登录' }}
|
||||||
|
</UiButton>
|
||||||
|
</form>
|
||||||
|
</UiCardContent>
|
||||||
|
</UiCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<route lang="yaml">
|
||||||
|
meta:
|
||||||
|
layout: blank
|
||||||
|
</route>
|
||||||
@@ -5,33 +5,22 @@ import { storeToRefs } from 'pinia'
|
|||||||
import pinia from '@/plugins/pinia/setup'
|
import pinia from '@/plugins/pinia/setup'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
|
||||||
// 需要认证的 Monisuo 路由前缀
|
// 需要认证的路由前缀
|
||||||
const MONISUO_AUTH_ROUTES = ['/monisuo/']
|
const AUTH_ROUTES = ['/monisuo/', '/dashboard', '/users', '/tasks', '/settings']
|
||||||
|
|
||||||
export function authGuard(router: Router) {
|
export function authGuard(router: Router) {
|
||||||
router.beforeEach((to, _from) => {
|
router.beforeEach((to, _from) => {
|
||||||
const authStore = useAuthStore(pinia)
|
const authStore = useAuthStore(pinia)
|
||||||
const { isLogin } = storeToRefs(authStore)
|
const { isLogin } = storeToRefs(authStore)
|
||||||
|
|
||||||
// 检查是否是需要认证的 Monisuo 路由
|
// 检查是否是需要认证的路由
|
||||||
const isMonisuoRoute = MONISUO_AUTH_ROUTES.some(prefix => to.path.startsWith(prefix))
|
const needsAuth = to.meta.auth || AUTH_ROUTES.some(prefix => to.path.startsWith(prefix))
|
||||||
|
|
||||||
// 如果页面需要登录但用户未登录,重定向到登录页并记录原始目标页面
|
// 如果页面需要登录但用户未登录,重定向到登录页并记录原始目标页面
|
||||||
if ((to.meta.auth || isMonisuoRoute) && !unref(isLogin)) {
|
if (needsAuth && !unref(isLogin) && to.name !== '/auth/sign-in') {
|
||||||
// Monisuo 路由重定向到 Monisuo 登录页
|
return {
|
||||||
if (isMonisuoRoute && to.name !== '/auth/monisuo-sign-in') {
|
name: '/auth/sign-in',
|
||||||
return {
|
query: { redirect: to.fullPath },
|
||||||
name: '/auth/monisuo-sign-in',
|
|
||||||
query: { redirect: to.fullPath },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他需要认证的路由重定向到默认登录页
|
|
||||||
if (to.meta.auth && to.name !== '/auth/sign-in') {
|
|
||||||
return {
|
|
||||||
name: '/auth/sign-in',
|
|
||||||
query: { redirect: to.fullPath },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
27
monisuo-admin/src/types/route-map.d.ts
vendored
27
monisuo-admin/src/types/route-map.d.ts
vendored
@@ -40,6 +40,20 @@ declare module 'vue-router/auto-routes' {
|
|||||||
{ path: ParamValue<false> },
|
{ path: ParamValue<false> },
|
||||||
| never
|
| never
|
||||||
>,
|
>,
|
||||||
|
'/auth': RouteRecordInfo<
|
||||||
|
'/auth',
|
||||||
|
'/auth',
|
||||||
|
Record<never, never>,
|
||||||
|
Record<never, never>,
|
||||||
|
| '/auth/sign-in'
|
||||||
|
>,
|
||||||
|
'/auth/sign-in': RouteRecordInfo<
|
||||||
|
'/auth/sign-in',
|
||||||
|
'/auth/sign-in',
|
||||||
|
Record<never, never>,
|
||||||
|
Record<never, never>,
|
||||||
|
| never
|
||||||
|
>,
|
||||||
'/dashboard/': RouteRecordInfo<
|
'/dashboard/': RouteRecordInfo<
|
||||||
'/dashboard/',
|
'/dashboard/',
|
||||||
'/dashboard',
|
'/dashboard',
|
||||||
@@ -128,6 +142,19 @@ declare module 'vue-router/auto-routes' {
|
|||||||
views:
|
views:
|
||||||
| never
|
| never
|
||||||
}
|
}
|
||||||
|
'src/pages/auth.vue': {
|
||||||
|
routes:
|
||||||
|
| '/auth'
|
||||||
|
| '/auth/sign-in'
|
||||||
|
views:
|
||||||
|
| 'default'
|
||||||
|
}
|
||||||
|
'src/pages/auth/sign-in.vue': {
|
||||||
|
routes:
|
||||||
|
| '/auth/sign-in'
|
||||||
|
views:
|
||||||
|
| never
|
||||||
|
}
|
||||||
'src/pages/dashboard/index.vue': {
|
'src/pages/dashboard/index.vue': {
|
||||||
routes:
|
routes:
|
||||||
| '/dashboard/'
|
| '/dashboard/'
|
||||||
|
|||||||
Reference in New Issue
Block a user