feat: connect admin session and public config endpoints
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
export { useAdminFiles } from './useAdminFiles'
|
export { useAdminFiles } from './useAdminFiles'
|
||||||
export { useAdminLogin } from './useAdminLogin'
|
export { useAdminLogin } from './useAdminLogin'
|
||||||
|
export { useAdminSession } from './useAdminSession'
|
||||||
export { useAppShell } from './useAppShell'
|
export { useAppShell } from './useAppShell'
|
||||||
export { useDashboardStats } from './useDashboardStats'
|
export { useDashboardStats } from './useDashboardStats'
|
||||||
export { useInjectedDarkMode } from './useInjectedDarkMode'
|
export { useInjectedDarkMode } from './useInjectedDarkMode'
|
||||||
|
|||||||
@@ -35,7 +35,13 @@ export function useAdminLogin() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
adminStore.setToken(response.detail.token)
|
adminStore.login({
|
||||||
|
id: response.detail.id || 'admin',
|
||||||
|
username: response.detail.username || 'admin',
|
||||||
|
token: response.detail.token,
|
||||||
|
token_type: response.detail.token_type,
|
||||||
|
expires_at: response.detail.expires_at
|
||||||
|
})
|
||||||
return true
|
return true
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
alertStore.showAlert(getErrorMessage(error, '登录失败'), 'error')
|
alertStore.showAlert(getErrorMessage(error, '登录失败'), 'error')
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { AuthService } from '@/services'
|
||||||
|
import { useAdminStore } from '@/stores/adminStore'
|
||||||
|
|
||||||
|
export function useAdminSession() {
|
||||||
|
const adminStore = useAdminStore()
|
||||||
|
|
||||||
|
const verifySession = async () => {
|
||||||
|
if (!adminStore.hasToken) return false
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await AuthService.verifyToken()
|
||||||
|
if (response.code === 200 && response.detail?.token) {
|
||||||
|
adminStore.login(response.detail)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
adminStore.logout()
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
try {
|
||||||
|
await AuthService.logout()
|
||||||
|
} finally {
|
||||||
|
adminStore.logout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
verifySession,
|
||||||
|
logout
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -120,7 +120,7 @@ import {
|
|||||||
import { RouterLink, useRoute, useRouter } from 'vue-router'
|
import { RouterLink, useRoute, useRouter } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { ROUTE_NAMES, ROUTES } from '@/constants'
|
import { ROUTE_NAMES, ROUTES } from '@/constants'
|
||||||
import { useAdminStore } from '@/stores/adminStore'
|
import { useAdminSession } from '@/composables'
|
||||||
|
|
||||||
interface MenuItem {
|
interface MenuItem {
|
||||||
id: string
|
id: string
|
||||||
@@ -133,7 +133,7 @@ const router = useRouter()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const isDarkMode = inject('isDarkMode')
|
const isDarkMode = inject('isDarkMode')
|
||||||
const adminStore = useAdminStore()
|
const { verifySession, logout } = useAdminSession()
|
||||||
const menuItems: MenuItem[] = [
|
const menuItems: MenuItem[] = [
|
||||||
{
|
{
|
||||||
id: ROUTE_NAMES.DASHBOARD,
|
id: ROUTE_NAMES.DASHBOARD,
|
||||||
@@ -172,6 +172,11 @@ const handleResize = () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleResize()
|
handleResize()
|
||||||
window.addEventListener('resize', handleResize)
|
window.addEventListener('resize', handleResize)
|
||||||
|
void verifySession().then((isValid) => {
|
||||||
|
if (!isValid) {
|
||||||
|
void router.push(ROUTES.LOGIN)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@@ -179,9 +184,9 @@ onUnmounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 登出处理
|
// 登出处理
|
||||||
const handleLogout = () => {
|
const handleLogout = async () => {
|
||||||
adminStore.logout()
|
await logout()
|
||||||
router.push(ROUTES.LOGIN)
|
await router.push(ROUTES.LOGIN)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,40 @@
|
|||||||
import api from './client'
|
import api from './client'
|
||||||
import type { ApiResponse, ConfigState } from '@/types'
|
import type { ApiResponse, ConfigState } from '@/types'
|
||||||
|
|
||||||
|
type PublicConfigEnvelope = {
|
||||||
|
config?: Partial<ConfigState>
|
||||||
|
meta?: unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPublicConfigEnvelope = (
|
||||||
|
detail: ConfigState | PublicConfigEnvelope | null | undefined
|
||||||
|
): detail is PublicConfigEnvelope => {
|
||||||
|
return !!detail && typeof detail === 'object' && 'config' in detail
|
||||||
|
}
|
||||||
|
|
||||||
export class ConfigService {
|
export class ConfigService {
|
||||||
static async getConfig(): Promise<ApiResponse<ConfigState>> {
|
static async getConfig(): Promise<ApiResponse<ConfigState>> {
|
||||||
return api.get('/admin/config/get')
|
return api.get('/admin/config/get')
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getUserConfig(): Promise<ApiResponse<ConfigState>> {
|
static async getUserConfig(): Promise<ApiResponse<ConfigState>> {
|
||||||
|
try {
|
||||||
|
const response = (await api.get('/api/v1/config')) as ApiResponse<
|
||||||
|
ConfigState | PublicConfigEnvelope
|
||||||
|
>
|
||||||
|
|
||||||
|
if (isPublicConfigEnvelope(response.detail) && response.detail.config) {
|
||||||
|
return {
|
||||||
|
...response,
|
||||||
|
detail: response.detail.config as ConfigState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response as ApiResponse<ConfigState>
|
||||||
|
} catch {
|
||||||
return api.post('/')
|
return api.post('/')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async updateConfig(config: Partial<ConfigState>): Promise<ApiResponse> {
|
static async updateConfig(config: Partial<ConfigState>): Promise<ApiResponse> {
|
||||||
return api.patch('/admin/config/update', config)
|
return api.patch('/admin/config/update', config)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export interface ApiResponse<T = unknown> {
|
export interface ApiResponse<T = unknown> {
|
||||||
code: number
|
code: number
|
||||||
message?: string
|
message?: string
|
||||||
|
msg?: string
|
||||||
detail?: T
|
detail?: T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,6 @@ export interface AdminUser {
|
|||||||
id: string
|
id: string
|
||||||
username: string
|
username: string
|
||||||
token: string
|
token: string
|
||||||
|
token_type?: string
|
||||||
|
expires_at?: number
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user