feat(navigation): add profile stack navigator and fix API endpoints

- Add ProfileStackNavigatorComponent with full navigation stack (Profile, Settings, EditProfile, AccountSecurity, MyPosts, Bookmarks, NotificationSettings, BlockedUsers)
- Add null checks for response data in authService login, register, and refreshToken methods
- Fix postService API routes to use correct endpoints (/posts instead of /posts/cursor)
- Remove completed cursor pagination design document
This commit is contained in:
lafay
2026-03-21 01:36:40 +08:00
parent 8a0aea1c59
commit 97c7762f2b
5 changed files with 118 additions and 1153 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -40,8 +40,21 @@ export type ScheduleStackParamList = {
CourseDetail: { course: any; relatedCourses?: any[] };
};
// Profile Stack 类型定义
export type ProfileStackParamList = {
Profile: undefined;
Settings: undefined;
EditProfile: undefined;
AccountSecurity: undefined;
MyPosts: undefined;
Bookmarks: undefined;
NotificationSettings: undefined;
BlockedUsers: undefined;
};
// ==================== Stack Navigators ====================
const ScheduleStack = createNativeStackNavigator<ScheduleStackParamList>();
const ProfileStack = createNativeStackNavigator<ProfileStackParamList>();
// ==================== 常量 ====================
const TAB_BAR_HEIGHT = 64;
@@ -80,6 +93,84 @@ function ScheduleStackNavigatorComponent() {
);
}
/**
* Profile Stack Navigator 组件
*/
function ProfileStackNavigatorComponent() {
return (
<ProfileStack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: colors.background.paper,
},
headerTintColor: colors.text.primary,
headerTitleStyle: {
fontWeight: '600',
},
headerBackTitle: '',
headerShadowVisible: false,
}}
>
<ProfileStack.Screen
name="Profile"
component={ProfileScreen}
options={{
headerShown: false,
}}
/>
<ProfileStack.Screen
name="Settings"
component={SettingsScreen}
options={{
title: '设置',
}}
/>
<ProfileStack.Screen
name="EditProfile"
component={EditProfileScreen}
options={{
title: '编辑资料',
}}
/>
<ProfileStack.Screen
name="AccountSecurity"
component={AccountSecurityScreen}
options={{
title: '账号安全',
}}
/>
<ProfileStack.Screen
name="MyPosts"
component={ProfileScreen}
options={{
title: '我的帖子',
}}
/>
<ProfileStack.Screen
name="Bookmarks"
component={ProfileScreen}
options={{
title: '收藏',
}}
/>
<ProfileStack.Screen
name="NotificationSettings"
component={NotificationSettingsScreen}
options={{
title: '通知设置',
}}
/>
<ProfileStack.Screen
name="BlockedUsers"
component={BlockedUsersScreen}
options={{
title: '黑名单',
}}
/>
</ProfileStack.Navigator>
);
}
/**
* 主组件SimpleMobileTabNavigator
*/
@@ -108,7 +199,7 @@ export function SimpleMobileTabNavigator() {
case 'ScheduleTab':
return <ScheduleStackNavigatorComponent />;
case 'ProfileTab':
return <ProfileScreen />;
return <ProfileStackNavigatorComponent />;
default:
return <HomeScreen />;
}

View File

@@ -150,6 +150,9 @@ class AuthService {
async login(data: LoginRequest): Promise<AuthResponse> {
const response = await api.post<AuthResponse>('/auth/login', data);
if (!response.data) {
throw new Error('登录响应数据为空');
}
if (response.data.token) {
await api.setToken(response.data.token);
}
@@ -165,6 +168,9 @@ class AuthService {
async register(data: RegisterRequest): Promise<AuthResponse> {
const response = await api.post<AuthResponse>('/auth/register', data);
if (!response.data) {
throw new Error('注册响应数据为空');
}
if (response.data.token) {
await api.setToken(response.data.token);
}
@@ -233,6 +239,9 @@ class AuthService {
try {
const response = await api.post<RefreshTokenResponse>('/auth/refresh');
if (!response.data) {
return null;
}
if (response.data.token) {
await api.setToken(response.data.token);
}

View File

@@ -287,19 +287,17 @@ class PostService {
/**
* 获取帖子列表(游标分页)
* GET /api/v1/posts/cursor
* GET /api/v1/posts
* @param params 游标分页请求参数(包含 post_type 可选recommend, follow, hot, latest
*/
async getPostsCursor(
params: CursorPaginationRequest = {}
): Promise<CursorPaginationResponse<Post>> {
try {
const response = await api.get<CursorPaginationResponse<Post>>('/posts/cursor', {
params: {
const response = await api.get<CursorPaginationResponse<Post>>('/posts', {
cursor: params.cursor,
page_size: params.page_size,
post_type: params.post_type,
},
});
return response.data;
} catch (error) {
@@ -315,7 +313,7 @@ class PostService {
/**
* 搜索帖子(游标分页)
* GET /api/v1/posts/search/cursor
* GET /api/v1/posts/search
* @param query 搜索关键词
* @param params 游标分页请求参数
*/
@@ -324,11 +322,9 @@ class PostService {
params: CursorPaginationRequest = {}
): Promise<CursorPaginationResponse<Post>> {
try {
const response = await api.get<CursorPaginationResponse<Post>>('/posts/search/cursor', {
params: {
const response = await api.get<CursorPaginationResponse<Post>>('/posts/search', {
...params,
keyword: query,
},
});
return response.data;
} catch (error) {
@@ -344,7 +340,7 @@ class PostService {
/**
* 获取用户帖子列表(游标分页)
* GET /api/v1/users/:id/posts/cursor
* GET /api/v1/users/:id/posts
* @param userId 用户ID
* @param params 游标分页请求参数
*/
@@ -354,8 +350,8 @@ class PostService {
): Promise<CursorPaginationResponse<Post>> {
try {
const response = await api.get<CursorPaginationResponse<Post>>(
`/users/${userId}/posts/cursor`,
{ params }
`/users/${userId}/posts`,
params
);
return response.data;
} catch (error) {