* feat(frontend): 前端界面优化与使用统计功能增强
主要改动:
1. 表格布局统一优化
- 新增 TablePageLayout 通用布局组件
- 统一所有管理页面的表格样式和交互
- 优化 DataTable、Pagination、Select 等通用组件
2. 使用统计功能增强
- 管理端: 添加完整的筛选和显示功能
- 用户端: 完善 API Key 列显示
- 后端: 优化使用统计数据结构和查询
3. 账户组件优化
- 优化 AccountStatsModal、AccountUsageCell 等组件
- 统一进度条和统计显示样式
4. 其他改进
- 完善中英文国际化
- 统一页面样式和交互体验
- 优化各视图页面的响应式布局
* fix(test): 修复 stubUsageLogRepo.ListWithFilters 测试 stub
测试用例 GET /api/v1/usage 返回 500 是因为 stub 方法未实现,
现在正确返回基于 UserID 过滤的日志数据。
* feat(frontend): 统一日期时间显示格式
**主要改动**:
1. 增强 utils/format.ts:
- 新增 formatDateOnly() - 格式: YYYY-MM-DD
- 新增 formatDateTime() - 格式: YYYY-MM-DD HH:mm:ss
2. 全局替换视图中的格式化函数:
- 移除各视图中的自定义 formatDate 函数
- 统一导入使用 @/utils/format 中的函数
- created_at/updated_at 使用 formatDateTime
- expires_at 使用 formatDateOnly
3. 受影响的视图 (8个):
- frontend/src/views/user/KeysView.vue
- frontend/src/views/user/DashboardView.vue
- frontend/src/views/user/UsageView.vue
- frontend/src/views/user/RedeemView.vue
- frontend/src/views/admin/UsersView.vue
- frontend/src/views/admin/UsageView.vue
- frontend/src/views/admin/RedeemView.vue
- frontend/src/views/admin/SubscriptionsView.vue
**效果**:
- 日期统一显示为 YYYY-MM-DD
- 时间统一显示为 YYYY-MM-DD HH:mm:ss
- 提升可维护性,避免格式不一致
* fix(frontend): 补充遗漏的时间格式化统一
**补充修复**(基于 code review 发现的遗漏):
1. 增强 utils/format.ts:
- 新增 formatTime() - 格式: HH:mm
2. 修复 4 个遗漏的文件:
- src/views/admin/UsersView.vue
* 删除 formatExpiresAt(),改用 formatDateTime()
* 修复订阅过期时间 tooltip 显示格式不一致问题
- src/views/user/ProfileView.vue
* 删除 formatMemberSince(),改用 formatDate(date, 'YYYY-MM')
* 统一会员起始时间显示格式
- src/views/user/SubscriptionsView.vue
* 修改 formatExpirationDate() 使用 formatDateOnly()
* 保留天数计算逻辑
- src/components/account/AccountStatusIndicator.vue
* 删除本地 formatTime(),改用 utils/format 中的统一函数
* 修复 rate limit 和 overload 重置时间显示
**验证**:
- TypeScript 类型检查通过 ✓
- 前端构建成功 ✓
- 所有剩余的 toLocaleString() 都是数字格式化,属于正确用法 ✓
**效果**:
- 订阅过期时间统一为 YYYY-MM-DD HH:mm:ss
- 会员起始时间统一为 YYYY-MM
- 重置时间统一为 HH:mm
- 消除所有不规范的原生 locale 方法调用
Authentication Views
This directory contains Vue 3 authentication views for the Sub2API frontend application.
Components
LoginView.vue
Login page for existing users to authenticate.
Features:
- Username and password inputs with validation
- Remember me checkbox for persistent sessions
- Form validation with real-time error display
- Loading state during authentication
- Error message display for failed login attempts
- Redirect to dashboard on successful login
- Link to registration page for new users
Usage:
<template>
<LoginView />
</template>
<script setup lang="ts">
import { LoginView } from '@/views/auth'
</script>
Route:
- Path:
/login - Name:
Login - Meta:
{ requiresAuth: false }
Validation Rules:
- Username: Required, minimum 3 characters
- Password: Required, minimum 6 characters
Behavior:
- Calls
authStore.login()with credentials - Shows success toast on successful login
- Shows error toast and inline error message on failure
- Redirects to
/dashboardor intended route from query parameter - Redirects authenticated users away from login page
RegisterView.vue
Registration page for new users to create accounts.
Features:
- Username, email, password, and confirm password inputs
- Comprehensive form validation
- Password strength requirements (8+ characters, letters + numbers)
- Email format validation with regex
- Password match validation
- Loading state during registration
- Error message display for failed registration
- Redirect to dashboard on success
- Link to login page for existing users
Usage:
<template>
<RegisterView />
</template>
<script setup lang="ts">
import { RegisterView } from '@/views/auth'
</script>
Route:
- Path:
/register - Name:
Register - Meta:
{ requiresAuth: false }
Validation Rules:
- Username:
- Required
- 3-50 characters
- Only letters, numbers, underscores, and hyphens
- Email:
- Required
- Valid email format (RFC 5322 regex)
- Password:
- Required
- Minimum 8 characters
- Must contain at least one letter and one number
- Confirm Password:
- Required
- Must match password
Behavior:
- Calls
authStore.register()with user data - Shows success toast on successful registration
- Shows error toast and inline error message on failure
- Redirects to
/dashboardafter successful registration - Redirects authenticated users away from register page
Architecture
Component Structure
Both views follow a consistent structure:
<template>
<AuthLayout>
<div class="space-y-6">
<!-- Title -->
<!-- Form -->
<!-- Error Message -->
<!-- Submit Button -->
</div>
<template #footer>
<!-- Footer Links -->
</template>
</AuthLayout>
</template>
<script setup lang="ts">
// Imports
// State
// Validation
// Form Handlers
</script>
State Management
Both views use:
useAuthStore()- For authentication actions (login, register)useAppStore()- For toast notifications and UI feedbackuseRouter()- For navigation and redirects
Validation Strategy
Client-side Validation:
- Real-time validation on form submission
- Field-level error messages
- Comprehensive validation rules
- TypeScript type safety
Server-side Validation:
- Backend API validates all inputs
- Error responses handled gracefully
- User-friendly error messages displayed
Styling
Design System:
- TailwindCSS utility classes
- Consistent color scheme (indigo primary)
- Responsive design
- Accessible form controls
- Loading states with spinner animations
Visual Feedback:
- Red border on invalid fields
- Error messages below inputs
- Global error banner for API errors
- Success toasts on completion
- Loading spinner on submit button
Dependencies
Components
AuthLayout- Layout wrapper for auth pages from@/components/layout
Stores
authStore- Authentication state management from@/stores/authappStore- Application state and toasts from@/stores/app
Libraries
- Vue 3 Composition API
- Vue Router for navigation
- Pinia for state management
- TypeScript for type safety
Usage Examples
Basic Login Flow
// User enters credentials
formData.username = 'john_doe'
formData.password = 'SecurePass123'
// Submit form
await handleLogin()
// On success:
// - authStore.login() called
// - Token and user stored
// - Success toast shown
// - Redirected to /dashboard
// On error:
// - Error message displayed
// - Error toast shown
// - Form remains editable
Basic Registration Flow
// User enters registration data
formData.username = 'jane_smith'
formData.email = 'jane@example.com'
formData.password = 'SecurePass123'
formData.confirmPassword = 'SecurePass123'
// Submit form
await handleRegister()
// On success:
// - authStore.register() called
// - Token and user stored
// - Success toast shown
// - Redirected to /dashboard
// On error:
// - Error message displayed
// - Error toast shown
// - Form remains editable
Error Handling
Client-side Errors
// Validation errors
errors.username = 'Username must be at least 3 characters'
errors.email = 'Please enter a valid email address'
errors.password = 'Password must be at least 8 characters with letters and numbers'
errors.confirmPassword = 'Passwords do not match'
Server-side Errors
// API error responses
{
response: {
data: {
detail: 'Username already exists'
}
}
}
// Displayed as:
errorMessage.value = 'Username already exists'
appStore.showError('Username already exists')
Accessibility
- Semantic HTML elements (
<label>,<input>,<button>) - Proper
forattributes on labels - ARIA attributes for loading states
- Keyboard navigation support
- Focus management
- Error announcements
- Sufficient color contrast
Testing Considerations
Unit Tests
- Form validation logic
- Error handling
- State management
- Router navigation
Integration Tests
- Full login flow
- Full registration flow
- Error scenarios
- Redirect behavior
E2E Tests
- Complete user journeys
- Form interactions
- API integration
- Success/error states
Future Enhancements
Potential improvements:
- OAuth/SSO integration (Google, GitHub)
- Two-factor authentication (2FA)
- Password strength meter
- Email verification flow
- Forgot password functionality
- Social login buttons
- CAPTCHA integration
- Session timeout warnings
- Password visibility toggle
- Autofill support enhancement
Security Considerations
- Passwords are never logged or displayed
- HTTPS required in production
- JWT tokens stored securely in localStorage
- CORS protection on API
- XSS protection with Vue's automatic escaping
- CSRF protection with token-based auth
- Rate limiting on backend API
- Input sanitization
- Secure password requirements
Performance
- Lazy-loaded routes
- Minimal bundle size
- Fast initial render
- Optimized re-renders with reactive refs
- No unnecessary watchers
- Efficient form validation
Browser Support
- Modern browsers (Chrome, Firefox, Safari, Edge)
- ES2015+ required
- Flexbox and CSS Grid
- Tailwind CSS utilities
- Vue 3 runtime