style(frontend): 统一核心模块代码风格
- Composables: 优化 OAuth 相关 hooks 代码格式 - Stores: 规范状态管理模块格式 - Types: 统一类型定义格式 - Utils: 优化工具函数格式 - App.vue & style.css: 调整全局样式和主组件格式
This commit is contained in:
@@ -9,13 +9,16 @@ This directory contains all Pinia stores for the Sub2API frontend application.
|
||||
Manages user authentication state, login/logout, and token persistence.
|
||||
|
||||
**State:**
|
||||
|
||||
- `user: User | null` - Current authenticated user
|
||||
- `token: string | null` - JWT authentication token
|
||||
|
||||
**Computed:**
|
||||
|
||||
- `isAuthenticated: boolean` - Whether user is currently authenticated
|
||||
|
||||
**Actions:**
|
||||
|
||||
- `login(credentials)` - Authenticate user with username/password
|
||||
- `register(userData)` - Register new user account
|
||||
- `logout()` - Clear authentication and logout
|
||||
@@ -27,14 +30,17 @@ Manages user authentication state, login/logout, and token persistence.
|
||||
Manages global UI state including sidebar, loading indicators, and toast notifications.
|
||||
|
||||
**State:**
|
||||
|
||||
- `sidebarCollapsed: boolean` - Sidebar collapsed state
|
||||
- `loading: boolean` - Global loading state
|
||||
- `toasts: Toast[]` - Active toast notifications
|
||||
|
||||
**Computed:**
|
||||
|
||||
- `hasActiveToasts: boolean` - Whether any toasts are active
|
||||
|
||||
**Actions:**
|
||||
|
||||
- `toggleSidebar()` - Toggle sidebar state
|
||||
- `setSidebarCollapsed(collapsed)` - Set sidebar state explicitly
|
||||
- `setLoading(isLoading)` - Set loading state
|
||||
@@ -54,106 +60,104 @@ Manages global UI state including sidebar, loading indicators, and toast notific
|
||||
### Auth Store
|
||||
|
||||
```typescript
|
||||
import { useAuthStore } from '@/stores';
|
||||
import { useAuthStore } from '@/stores'
|
||||
|
||||
// In component setup
|
||||
const authStore = useAuthStore();
|
||||
const authStore = useAuthStore()
|
||||
|
||||
// Initialize on app startup
|
||||
authStore.checkAuth();
|
||||
authStore.checkAuth()
|
||||
|
||||
// Login
|
||||
try {
|
||||
await authStore.login({ username: 'user', password: 'pass' });
|
||||
console.log('Logged in:', authStore.user);
|
||||
await authStore.login({ username: 'user', password: 'pass' })
|
||||
console.log('Logged in:', authStore.user)
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error);
|
||||
console.error('Login failed:', error)
|
||||
}
|
||||
|
||||
// Check authentication
|
||||
if (authStore.isAuthenticated) {
|
||||
console.log('User is logged in:', authStore.user?.username);
|
||||
console.log('User is logged in:', authStore.user?.username)
|
||||
}
|
||||
|
||||
// Logout
|
||||
authStore.logout();
|
||||
authStore.logout()
|
||||
```
|
||||
|
||||
### App Store
|
||||
|
||||
```typescript
|
||||
import { useAppStore } from '@/stores';
|
||||
import { useAppStore } from '@/stores'
|
||||
|
||||
// In component setup
|
||||
const appStore = useAppStore();
|
||||
const appStore = useAppStore()
|
||||
|
||||
// Sidebar control
|
||||
appStore.toggleSidebar();
|
||||
appStore.setSidebarCollapsed(true);
|
||||
appStore.toggleSidebar()
|
||||
appStore.setSidebarCollapsed(true)
|
||||
|
||||
// Loading state
|
||||
appStore.setLoading(true);
|
||||
appStore.setLoading(true)
|
||||
// ... do work
|
||||
appStore.setLoading(false);
|
||||
appStore.setLoading(false)
|
||||
|
||||
// Or use helper
|
||||
await appStore.withLoading(async () => {
|
||||
const data = await fetchData();
|
||||
return data;
|
||||
});
|
||||
const data = await fetchData()
|
||||
return data
|
||||
})
|
||||
|
||||
// Toast notifications
|
||||
appStore.showSuccess('Operation completed!');
|
||||
appStore.showError('Something went wrong!', 5000);
|
||||
appStore.showInfo('FYI: This is informational');
|
||||
appStore.showWarning('Be careful!');
|
||||
appStore.showSuccess('Operation completed!')
|
||||
appStore.showError('Something went wrong!', 5000)
|
||||
appStore.showInfo('FYI: This is informational')
|
||||
appStore.showWarning('Be careful!')
|
||||
|
||||
// Custom toast
|
||||
const toastId = appStore.showToast('info', 'Custom message', undefined); // No auto-dismiss
|
||||
const toastId = appStore.showToast('info', 'Custom message', undefined) // No auto-dismiss
|
||||
// Later...
|
||||
appStore.hideToast(toastId);
|
||||
appStore.hideToast(toastId)
|
||||
```
|
||||
|
||||
### Combined Usage in Vue Component
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore, useAppStore } from '@/stores';
|
||||
import { onMounted } from 'vue';
|
||||
import { useAuthStore, useAppStore } from '@/stores'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const appStore = useAppStore();
|
||||
const authStore = useAuthStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
onMounted(() => {
|
||||
// Check for existing session
|
||||
authStore.checkAuth();
|
||||
});
|
||||
authStore.checkAuth()
|
||||
})
|
||||
|
||||
async function handleLogin(username: string, password: string) {
|
||||
try {
|
||||
await appStore.withLoading(async () => {
|
||||
await authStore.login({ username, password });
|
||||
});
|
||||
appStore.showSuccess('Welcome back!');
|
||||
await authStore.login({ username, password })
|
||||
})
|
||||
appStore.showSuccess('Welcome back!')
|
||||
} catch (error) {
|
||||
appStore.showError('Login failed. Please check your credentials.');
|
||||
appStore.showError('Login failed. Please check your credentials.')
|
||||
}
|
||||
}
|
||||
|
||||
async function handleLogout() {
|
||||
authStore.logout();
|
||||
appStore.showInfo('You have been logged out.');
|
||||
authStore.logout()
|
||||
appStore.showInfo('You have been logged out.')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<button @click="appStore.toggleSidebar">
|
||||
Toggle Sidebar
|
||||
</button>
|
||||
|
||||
<button @click="appStore.toggleSidebar">Toggle Sidebar</button>
|
||||
|
||||
<div v-if="appStore.loading">Loading...</div>
|
||||
|
||||
|
||||
<div v-if="authStore.isAuthenticated">
|
||||
Welcome, {{ authStore.user?.username }}!
|
||||
<button @click="handleLogout">Logout</button>
|
||||
@@ -170,7 +174,6 @@ async function handleLogout() {
|
||||
- **Auth Store**: Token and user data are automatically persisted to `localStorage`
|
||||
- Keys: `auth_token`, `auth_user`
|
||||
- Restored on `checkAuth()` call
|
||||
|
||||
- **App Store**: No persistence (UI state resets on page reload)
|
||||
|
||||
## TypeScript Support
|
||||
@@ -178,7 +181,7 @@ async function handleLogout() {
|
||||
All stores are fully typed with TypeScript. Import types from `@/types`:
|
||||
|
||||
```typescript
|
||||
import type { User, Toast, ToastType } from '@/types';
|
||||
import type { User, Toast, ToastType } from '@/types'
|
||||
```
|
||||
|
||||
## Testing
|
||||
@@ -187,8 +190,8 @@ Stores can be reset to initial state:
|
||||
|
||||
```typescript
|
||||
// Auth store
|
||||
authStore.logout(); // Clears all auth state
|
||||
authStore.logout() // Clears all auth state
|
||||
|
||||
// App store
|
||||
appStore.reset(); // Resets to defaults
|
||||
appStore.reset() // Resets to defaults
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user