style(frontend): 统一核心模块代码风格

- Composables: 优化 OAuth 相关 hooks 代码格式
- Stores: 规范状态管理模块格式
- Types: 统一类型定义格式
- Utils: 优化工具函数格式
- App.vue & style.css: 调整全局样式和主组件格式
This commit is contained in:
ianshaw
2025-12-25 08:41:43 -08:00
parent 5763f5ced3
commit 01f990a5c9
10 changed files with 775 additions and 755 deletions

View File

@@ -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
```