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:
File diff suppressed because it is too large
Load Diff
@@ -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 />;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user