🔐 feat: 认证系统升级 - 从重定向到底部Modal的完整改造

## 核心功能

### 1. 全局认证架构
- 新增 AuthProvider:全局认证上下文,管理登录状态和Modal
- 新增 useAuthGuard Hook:提供 requireAuth 认证拦截功能
- 新增 AuthGuard 组件:包装需要认证的组件
- 新增 AuthPrompt 组件:多种样式的登录引导组件

### 2. 登录体验优化
- LoginModal 已优化为底部抽屉式设计
- 登录成功后自动关闭Modal并恢复用户操作
- 支持队列机制,多个认证检查依次执行

### 3. 页面架构调整
- 根布局集成 AuthProvider
- 移除 Tabs 布局的重定向逻辑
- Explore 页面添加认证保护,显示登录提示

### 4. API安全增强
- 新增 TokenManager:完整的Token生命周期管理
- 新增 SecureClient:安全API客户端,自动处理认证
- 更新 API 客户端:支持认证头和自动Token刷新

### 5. 文档完善
- AUTH_SYSTEM.md:完整的认证系统使用指南
- AUTH_UPGRADE_SUMMARY.md:升级总结文档

## 技术亮点

 TypeScript 完整支持,编译时类型检查
 React 最佳实践,合理使用 Hooks 和 Context
 优雅的错误处理,友好的用户提示
 流畅的动画效果,原生级用户体验

## 核心优势

- 流畅:无需页面跳转,Modal即用即走
- 智能:自动检测登录需求,无需手动判断
- 安全:完整Token管理和自动刷新机制
- 灵活:多种认证组件满足不同场景
- 易用:详细文档和示例,快速上手

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
imeepos
2025-10-31 11:18:20 +08:00
parent add140dbda
commit 668caaa91f
13 changed files with 1604 additions and 30 deletions

View File

@@ -0,0 +1,111 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { useAuth } from '@/hooks/use-auth';
import { useAuthGuard } from '@/hooks/use-auth-guard';
import { ThemedText } from '@/components/themed-text';
interface AuthGuardProps {
children: React.ReactNode;
fallback?: React.ReactNode;
showLoginPrompt?: boolean;
title?: string;
subtitle?: string;
}
/**
* 认证守卫组件
* 用于包装需要登录才能访问的内容
*
* @param children - 需要保护的内容
* @param fallback - 未登录时显示的自定义内容(可选)
* @param showLoginPrompt - 是否显示默认的登录提示默认true
* @param title - 自定义提示标题
* @param subtitle - 自定义提示副标题
*
* @example
* ```typescript
* <AuthGuard>
* <ProtectedComponent />
* </AuthGuard>
*
* // 自定义提示
* <AuthGuard
* title="需要登录"
* subtitle="登录后即可使用此功能"
* >
* <ProtectedComponent />
* </AuthGuard>
* ```
*/
export function AuthGuard({
children,
fallback,
showLoginPrompt = true,
title = '需要登录',
subtitle = '请先登录以继续使用',
}: AuthGuardProps) {
const { isAuthenticated, isLoading } = useAuth();
const { requireAuth } = useAuthGuard();
if (isLoading) {
return <View style={styles.loadingContainer} />;
}
if (!isAuthenticated) {
if (fallback) {
return <>{fallback}</>;
}
if (showLoginPrompt) {
return (
<View style={styles.promptContainer}>
<View style={styles.iconContainer}>
<ThemedText style={styles.lockIcon}>🔒</ThemedText>
</View>
<ThemedText style={styles.title}>{title}</ThemedText>
<ThemedText style={styles.subtitle}>{subtitle}</ThemedText>
</View>
);
}
return null;
}
return <>{children}</>;
}
const styles = StyleSheet.create({
loadingContainer: {
flex: 1,
},
promptContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 32,
},
iconContainer: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: 'rgba(0, 122, 255, 0.1)',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
},
lockIcon: {
fontSize: 40,
},
title: {
fontSize: 24,
fontWeight: '700',
marginBottom: 12,
textAlign: 'center',
},
subtitle: {
fontSize: 16,
opacity: 0.7,
textAlign: 'center',
lineHeight: 24,
},
});