🔐 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

@@ -1,4 +1,4 @@
import { Tabs, Redirect } from 'expo-router';
import { Tabs } from 'expo-router';
import React from 'react';
import { HapticTab } from '@/components/haptic-tab';
@@ -15,10 +15,6 @@ export default function TabLayout() {
return null;
}
if (!isAuthenticated) {
return <Redirect href="/(auth)/login" />;
}
return (
<Tabs
screenOptions={{

View File

@@ -1,5 +1,5 @@
import { useMemo, useState } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import { ScrollView, StyleSheet, View, TouchableOpacity, Text } from 'react-native';
import {
CategoryTabs,
@@ -12,6 +12,8 @@ import {
type CommunityItem,
type FeatureItem,
} from '@/components/bestai';
import { useAuth } from '@/hooks/use-auth';
import { useAuthGuard } from '@/hooks/use-auth-guard';
const categories = [
{ id: 'visual-effects', label: 'Visual Effects' },
@@ -73,6 +75,8 @@ const baseCommunityItems: CommunityItem[] = [
];
export default function ExploreScreen() {
const { isAuthenticated } = useAuth();
const { requireAuth } = useAuthGuard();
const [activeCategory, setActiveCategory] = useState(categories[0]?.id ?? 'visual-effects');
const featureItems = useMemo(() => {
@@ -89,6 +93,44 @@ export default function ExploreScreen() {
}));
}, [activeCategory]);
const handleGeneratePress = () => {
requireAuth(() => {
console.log('用户已登录,执行生成操作');
});
};
if (!isAuthenticated) {
return (
<PageLayout backgroundColor="#050505">
<ScrollView
style={styles.scroll}
contentContainerStyle={styles.contentContainer}
showsVerticalScrollIndicator={false}
>
<StatusBarSpacer />
<Header />
<View style={styles.loginPrompt}>
<View style={styles.lockIconContainer}>
<Text style={styles.lockIcon}>🔒</Text>
</View>
<Text style={styles.loginTitle}></Text>
<Text style={styles.loginSubtitle}>
使
</Text>
<TouchableOpacity
style={styles.loginButton}
onPress={() => requireAuth()}
activeOpacity={0.8}
>
<Text style={styles.loginButtonText}></Text>
</TouchableOpacity>
</View>
<View style={styles.bottomSpacer} />
</ScrollView>
</PageLayout>
);
}
return (
<PageLayout backgroundColor="#050505">
<ScrollView
@@ -119,4 +161,45 @@ const styles = StyleSheet.create({
bottomSpacer: {
height: 32,
},
loginPrompt: {
alignItems: 'center',
paddingVertical: 60,
paddingHorizontal: 32,
},
lockIconContainer: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: 'rgba(255, 255, 255, 0.1)',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
},
lockIcon: {
fontSize: 40,
},
loginTitle: {
fontSize: 24,
fontWeight: '700',
color: '#ffffff',
marginBottom: 12,
},
loginSubtitle: {
fontSize: 16,
color: 'rgba(255, 255, 255, 0.6)',
textAlign: 'center',
lineHeight: 24,
marginBottom: 32,
},
loginButton: {
backgroundColor: '#d7ff1f',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 12,
},
loginButtonText: {
color: '#050505',
fontSize: 16,
fontWeight: '700',
},
});