diff --git a/.gitignore b/.gitignore index c5451e2..786d689 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules # 测试与打包 coverage/ +dist/ # 编辑器 .vscode/* diff --git a/README.md b/README.md index 06bf5c7..e50f15a 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,18 @@ API模块负责处理所有与后端通信相关的逻辑,提供统一的HTTP #### 核心功能 - **请求工厂**:使用工厂模式创建API实例,统一配置请求参数 - **拦截器系统**:支持请求/响应拦截器,实现统一的错误处理、日志记录和认证 -- **模块化API服务**:按功能域划分API服务,如用户API、内容API等 +- **模块化API服务**:按功能域划分API服务,如用户API、帖子API等 - **响应标准化**:统一处理API响应格式,提供一致的错误处理机制 +- **内容发现**:提供热门帖子、帖子榜单和热门作者功能,支持多种排序和统计周期 + +#### 新增功能 +##### 帖子相关 +- **热门帖子**:通过`getHotPosts()`获取指定时间内的热门帖子 +- **帖子榜单**:通过`getPostRanking()`获取不同周期(日/周/月)的帖子排行榜,支持按浏览量、点赞数、评论数排序 + +##### 用户相关 +- **热门作者**:通过`getHotAuthors()`获取指定时间内的热门作者 +- **作者榜单**:通过`getAuthorRanking()`获取不同周期(日/周/月)的作者排行榜,支持按发帖量、浏览量、点赞数排序 #### 架构特点 - 基于axios构建,支持请求/响应转换 @@ -113,4 +123,14 @@ knowai-core/ ### 2025-11-11 - 因服务器性能原因去除CI pipeline -- 重新整理所有逻辑模块架构,完成对应README撰写 \ No newline at end of file +- 重新整理所有逻辑模块架构,完成对应README撰写 + +### 2025-11-12 +- 实现帖子相关新功能:热门帖子、帖子榜单 +- 实现用户相关新功能:热门作者、作者榜单 +- 更新README文档,添加新功能说明 + +### 2025-11-18 +- 添加热门帖子、榜单、热门作者接口 +- 完成api-documentation.md文档,详细描述所有接口的功能、参数、响应格式等 +- 修复类型未导出问题 \ No newline at end of file diff --git a/api-documentation.md b/api-documentation.md new file mode 100644 index 0000000..b1afa68 --- /dev/null +++ b/api-documentation.md @@ -0,0 +1,909 @@ +# KnowAI Core API 文档 + +本文档详细介绍了 KnowAI Core 库提供的 API 接口和类型定义,供 Page 层项目使用。 + +## 1. 库概述 + +KnowAI Core 是一个通用的前端核心库,提供了 API 调用、认证管理、工具函数等基础功能。 + +```typescript +// 导入方式 +export * from './types'; // 类型定义 +export * from './api'; // API客户端和模块 +export * from './auth'; // 鉴权相关功能 +export * from './utils'; // 工具函数 +``` + +## 2. API 客户端 + +### 2.1 初始化 API 客户端 + +```typescript +import { createApi } from 'knowai-core'; + +// 创建默认 API 客户端 +const api = createApi(); + +// 或使用自定义配置 +const api = createApi({ + baseURL: '/api', // 默认值 + timeout: 10000, + headers: { + 'Content-Type': 'application/json' + }, + withCredentials: true +}); +``` + +### 2.2 API 客户端功能 + +```typescript +// API 客户端接口 +export interface ApiClient { + request(config: AxiosRequestConfig): Promise; + get(url: string, config?: AxiosRequestConfig): Promise; + post(url: string, data?: unknown, config?: AxiosRequestConfig): Promise; + put(url: string, data?: unknown, config?: AxiosRequestConfig): Promise; + delete(url: string, config?: AxiosRequestConfig): Promise; + patch(url: string, data?: unknown, config?: AxiosRequestConfig): Promise; + setDefaults(config: Partial): void; + setBaseURL(baseURL: string): void; + createInstance(config?: Partial): ApiClient; + addRequestInterceptor( + onFulfilled?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise, + onRejected?: (error: unknown) => unknown + ): number; + addResponseInterceptor( + onFulfilled?: (response: AxiosResponse) => AxiosResponse | Promise, + onRejected?: (error: unknown) => unknown + ): number; + removeRequestInterceptor(handler: number): void; + removeResponseInterceptor(handler: number): void; +} +``` + +## 3. 帖子模块 (Post) + +### 3.1 API 接口 + +```typescript +// 获取帖子API服务 +const postApiService = api.post; +// 或 const postApiService = api.modules.post; + +// 创建帖子 +createPost(data: CreatePostRequest): Promise; + +// 获取帖子列表 +getPosts(params: GetPostsRequest): Promise; + +// 获取帖子详情 +getPost({ postId }: GetPostRequest): Promise; + +// 点赞帖子 +likePost({ postId }: LikePostRequest): Promise; + +// 收藏帖子 +bookmarkPost({ postId }: BookmarkPostRequest): Promise; + +// 创建评论 +createComment(data: CreateCommentRequest): Promise; + +// 获取评论列表 +getComments(params: GetCommentsRequest): Promise; + +// 点赞评论 +likeComment({ commentId }: LikeCommentRequest): Promise; + +// 获取热门帖子 +getHotPosts(params?: GetHotPostsRequest): Promise; + +// 获取帖子榜单 +getPostRanking(params?: GetPostRankingRequest): Promise; +``` + +### 3.2 数据类型定义 + +#### 创建帖子请求 +```typescript +export interface CreatePostRequest extends BaseEntityContent { + type: PostType; // 帖子类型:提问或文章 + images?: string[]; // 图片 + publishedAt?: Date; // 发布时间 +} +``` + +#### 获取帖子列表请求 +```typescript +export interface GetPostsRequest { + page?: number; // 页码 + limit?: number; // 每页数量 + sortBy?: PostSortBy; // 帖子排序方式 + type?: PostType; // 帖子类型:提问或文章 + sortOrder?: SortOrder; // 排序方向 + authorId?: string; + search?: string; +} +``` + +#### 获取帖子列表响应 +```typescript +export interface GetPostsResponse { + data: Post[]; // 数据列表 + total: number; // 总数 + page: number; // 当前页码 + limit: number; // 每页数量 + hasMore: boolean; // 是否有更多数据 + sortBy?: PostSortBy; // 帖子排序方式 +} +``` + +#### 帖子接口 +```typescript +export interface Post extends BaseEntity, BaseEntityContent { + type: PostType; // 帖子类型:提问或文章 + authorId: string; // 作者ID + author: BaseUser; // 作者信息 + images?: string[]; // 图片数组 + publishedAt?: Date; // 发布时间 +} +``` + +#### 基础实体内容接口 +```typescript +export interface BaseEntityContent { + title?: string; // 标题 + excerpt: string; // 摘要 + tags?: string[]; // 标签数组 + metadata?: Record; // 元数据 + stars: number; // 收藏数 + likes: number; // 点赞数 + comments: number; // 评论数 +} +``` + +#### 获取热门帖子请求 +```typescript +export interface GetHotPostsRequest { + limit?: number; // 限制数量 + days?: number; // 时间范围(天) +} +``` + +#### 获取热门帖子响应 +```typescript +export interface GetHotPostsResponse { + data: Post[]; // 热门帖子列表 + total: number; // 总数 +} +``` + +#### 获取帖子榜单请求 +```typescript +export interface GetPostRankingRequest { + limit?: number; // 限制数量 + period?: 'day' | 'week' | 'month'; // 时间周期 + type?: 'views' | 'likes' | 'comments'; // 榜单类型 +} +``` + +#### 获取帖子榜单响应 +```typescript +export interface GetPostRankingResponse { + data: Post[]; // 帖子榜单列表 + total: number; // 总数 + period: 'day' | 'week' | 'month'; // 时间周期 + type: 'views' | 'likes' | 'comments'; // 榜单类型 +} +``` + +## 4. 用户模块 (User) + +### 4.1 API 接口 + +```typescript +// 获取用户API服务 +const userApiService = api.user; +// 或 const userApiService = api.modules.user; + +// 用户登录 +login(data: LoginRequest): Promise; + +// 用户注册 +register(data: RegisterRequest): Promise; + +// 系统使用服务器端session管理,无需手动刷新令牌 + +// 获取用户档案 +getProfile(): Promise; + +// 更新用户档案 +updateProfile(data: UserProfileUpdateRequest): Promise; + +// 关注用户 +followUser({ userId }: UserFollowRequest): Promise; + +// 取消关注用户 +unfollowUser({ userId }: UserFollowRequest): Promise; + +// 获取热门作者 +getHotAuthors(params?: GetHotAuthorsRequest): Promise; + +// 获取作者榜单 +getAuthorRanking(params?: GetAuthorRankingRequest): Promise; +``` + +### 4.2 数据类型定义 + +#### 登录请求 +```typescript +export interface LoginRequest { + username: string; + password: string; +} +``` + +#### 登录响应 +```typescript +export interface LoginResponse { + user: User; +} +``` + +#### 用户接口 +```typescript +export interface User { + id: string; + username: string; +} +``` + +#### 获取热门作者请求 +```typescript +export interface GetHotAuthorsRequest { + limit?: number; // 限制数量 + days?: number; // 时间范围(天) +} +``` + +#### 获取热门作者响应 +```typescript +export interface GetHotAuthorsResponse { + data: User[]; // 热门作者列表 + total: number; // 总数 +} +``` + +#### 获取作者榜单请求 +```typescript +export interface GetAuthorRankingRequest { + limit?: number; // 限制数量 + period?: 'day' | 'week' | 'month'; // 时间周期 + type?: 'posts' | 'views' | 'likes'; // 榜单类型 +} +``` + +#### 获取作者榜单响应 +```typescript +export interface GetAuthorRankingResponse { + data: User[]; // 作者榜单列表 + total: number; // 总数 + period: 'day' | 'week' | 'month'; // 时间周期 + type: 'posts' | 'views' | 'likes'; // 榜单类型 +} +``` + +## 5. 聊天模块 (Chat) + +### 5.1 API 接口 + +```typescript +// 获取聊天API服务 +const chatApiService = api.chat; +// 或 const chatApiService = api.modules.chat; + +// 创建聊天会话 +createSession(data: CreateChatSessionRequest): Promise<{ session: ChatSession }>; + +// 更新聊天会话 +updateSession({ sessionId, ...data }: UpdateChatSessionRequest): Promise<{ session: ChatSession }>; + +// 发送消息 +sendMessage(data: SendMessageRequest): Promise<{ message: ChatMessage }>; + +// 获取聊天会话列表 +getSessions(params?: GetChatSessionsRequest): Promise; + +// 获取聊天消息 +getMessages({ sessionId, ...params }: GetChatMessagesRequest): Promise; + +// 标记消息已读 +markMessagesAsRead({ sessionId, messageIds }: MarkMessagesAsReadRequest): Promise; +``` + +### 5.2 数据类型定义 + +#### 聊天消息接口 +```typescript +export interface ChatMessage { + id: string; + sessionId: string; + sender: User; + receiver: User; + content: string; + type: ChatMessageType; + status: ChatMessageStatus; + createdAt: Date; + // 非文本消息类型的元数据 + metadata?: { + fileName?: string; + fileSize?: number; + duration?: number; + thumbnail?: string; + [key: string]: unknown; + }; +} +``` + +#### 聊天会话接口 +```typescript +export interface ChatSession { + id: string; + participant1Id: string; + participant2Id: string; + participant1: User; + participant2: User; + lastMessage?: { + id: string; + content: string; + senderId: string; + createdAt: Date; + }; + unreadCount1: number; // 参与者1的未读消息数 + unreadCount2: number; // 参与者2的未读消息数 + createdAt: Date; + updatedAt: Date; + // 会话元数据(特殊标记、背景设置、自定义属性等等) + metadata?: { + [key: string]: unknown; + }; +} +``` + +#### 发送消息请求 +```typescript +export interface SendMessageRequest { + sessionId: string; + content: string; + type: ChatMessageType; + metadata?: Record; +} +``` + +#### 获取聊天会话列表响应 +```typescript +export interface GetChatSessionsResponse { + sessions: ChatSession[]; + total: number; + page: number; + limit: number; +} +``` + +## 6. 模型模块 (Model) + +### 6.1 API 接口 + +```typescript +// 获取模型API服务 +const modelApiService = api.model; +// 或 const modelApiService = api.modules.model; + +// 获取AI模型广场数据 +getAIPlaza(params?: GetAIPlazaRequest): Promise; + +// 获取模型详情 +getModelDetail({ modelId, ...params }: GetModelDetailRequest): Promise; + +// 获取模型评论 +getModelComments({ modelId, ...params }: GetModelCommentsRequest): Promise; +``` + +### 6.2 数据类型定义 + +#### AI模型接口 +```typescript +export interface AIModel { + id: string; + name: string; + description: string; + avatar?: string; // 模型头像 + tags?: string[]; // 模型标签 + website?: string; // 官方网站 + clickCount?: number; // 点击次数 + likeCount?: number; // 点赞次数 +} +``` + +#### AI模型评论接口 +```typescript +export interface ModelComment extends BaseEntity { + modelId: string; // 模型ID + authorId: string; // 作者ID + author: BaseUser; // 作者信息 + content: string; // 评论内容 + parentId?: string; // 父评论ID,用于嵌套评论 + stats: ModelCommentStats; // 统计信息 +} +``` + +#### AI模型广场响应 +```typescript +export interface GetAIPlazaResponse { + models: AIModel[]; // 模型卡片列表,由管理员预定义 + hotRankings: AIModelRankingItem[]; // 热评模型榜单 + clickRankings: AIModelRankingItem[]; // 点击排行榜 +} +``` + +#### 模型详情响应 +```typescript +export interface GetModelDetailResponse { + model: AIModel; + comments: ModelComment[]; // 使用新的ModelComment类型,已经是数组 + totalComments: number; + hasMoreComments: boolean; // 是否还有更多评论,支持无限滚动加载 +} +``` + +## 7. 通用数据类型 + +### 7.1 API 响应结构 + +```typescript +// 标准API响应 +export interface ApiResponse { + success: boolean; + data: T; + message?: string; + code?: number; +} + +// 分页响应 +export interface PaginatedResponse { + items: T[]; + total: number; + page: number; + pageSize: number; + totalPages: number; +} + +// 错误响应 +export interface ErrorResponse { + success: false; + message: string; + code?: number; + details?: unknown; +} +``` + +### 7.2 常量定义 + +```typescript +// API状态码 +export const ApiStatusCode = { + OK: 200, + CREATED: 201, + NO_CONTENT: 204, + BAD_REQUEST: 400, + UNAUTHORIZED: 401, + FORBIDDEN: 403, + NOT_FOUND: 404, + INTERNAL_SERVER_ERROR: 500 +} as const; + +// API错误类型 +export const ApiErrorType = { + NETWORK_ERROR: 'NETWORK_ERROR', + VALIDATION_ERROR: 'VALIDATION_ERROR', + AUTHENTICATION_ERROR: 'AUTHENTICATION_ERROR', + AUTHORIZATION_ERROR: 'AUTHORIZATION_ERROR', + NOT_FOUND_ERROR: 'NOT_FOUND_ERROR', + SERVER_ERROR: 'SERVER_ERROR', + UNKNOWN_ERROR: 'UNKNOWN_ERROR' +} as const; +``` + +## 8. 错误处理 + +### 8.1 API 错误处理示例 + +```typescript +import { ApiErrorType } from 'knowai-core'; + +try { + const posts = await api.post.getPosts({ page: 1, limit: 10 }); + // 处理成功响应 +} catch (error) { + if (error.code === ApiErrorType.AUTHENTICATION_ERROR) { + // 处理认证错误 + } else if (error.code === ApiErrorType.NETWORK_ERROR) { + // 处理网络错误 + } else { + // 处理其他错误 + } +} +``` + +## 9. 在 Page 层项目中的使用示例 + +### 9.1 初始化 API 客户端和认证服务 (Nuxt 插件) + +```typescript +// plugins/api.ts +import { createApi, createAuthService } from 'knowai-core'; + +export default defineNuxtPlugin(nuxtApp => { + // 创建API客户端 + const api = createApi({ + baseURL: '/api', + timeout: 15000 + }); + + // 创建认证服务 + const authService = createAuthService(api.client); + + // 无需手动添加认证令牌,使用浏览器的 cookie-session 机制 + // 会话由服务器端控制,前端通过API查询认证状态 + api.client.addRequestInterceptor( + (config) => { + // 会话由浏览器自动管理,无需手动添加认证信息 + return config; + }, + (error) => Promise.reject(error) + ); + + // 添加响应拦截器(处理错误) + api.client.addResponseInterceptor( + (response) => response, + (error) => { + // 统一错误处理逻辑 + console.error('API Error:', error); + return Promise.reject(error); + } + ); + + // 提供API客户端和认证服务给Nuxt应用 + nuxtApp.provide('api', api); + nuxtApp.provide('authService', authService); + + // 提供模块化API服务 + nuxtApp.provide('postApi', api.post); + nuxtApp.provide('userApi', api.user); + nuxtApp.provide('chatApi', api.chat); + nuxtApp.provide('modelApi', api.model); +}); +``` + +### 9.2 在页面中使用 API + +```typescript +// pages/index.vue + +``` + +### 9.3 在页面中使用认证服务 + +```typescript +// pages/auth/login.vue + + + +``` + +### 9.4 检查用户认证状态 + +```typescript +// middleware/auth.ts +import { useNuxtApp } from '#app'; + +export default defineNuxtRouteMiddleware(async () => { + const { $authService } = useNuxtApp(); + try { + // 检查用户是否已认证 + const isAuthenticated = await $authService.isAuthenticated(); + if (!isAuthenticated) { + // 未认证,跳转到登录页 + return navigateTo('/auth/login'); + } + } catch (error) { + // 认证检查失败,跳转到登录页 + return navigateTo('/auth/login'); + } +}); + +// 在需要认证的页面中使用 +// pages/profile.vue + +``` + +### 9.5 在 Pinia Store 中使用 API + +```typescript +// stores/postStore.ts +import { defineStore } from 'pinia'; +import { useNuxtApp } from '#app'; +import type { Post, GetPostsRequest, GetPostsResponse } from 'knowai-core'; + +export const usePostStore = defineStore('post', () => { + const { $postApi } = useNuxtApp(); + const posts = ref([]); + const loading = ref(false); + const error = ref(null); + + const fetchPosts = async (params: GetPostsRequest) => { + loading.value = true; + error.value = null; + try { + const response: GetPostsResponse = await $postApi.getPosts(params); + posts.value = response.data; + return response; + } catch (err) { + error.value = err.message || '获取帖子列表失败'; + throw err; + } finally { + loading.value = false; + } + }; + + return { + posts, + loading, + error, + fetchPosts + }; +}); +``` + +### 9.4 聊天功能使用示例 + +```typescript +// stores/chatStore.ts +import { defineStore } from 'pinia'; +import { useNuxtApp } from '#app'; +import type { ChatSession, ChatMessage, GetChatSessionsRequest, GetChatMessagesRequest } from 'knowai-core'; + +export const useChatStore = defineStore('chat', () => { + const { $chatApi } = useNuxtApp(); + const sessions = ref([]); + const currentSession = ref(null); + const messages = ref([]); + const loading = ref(false); + + // 获取会话列表 + const fetchSessions = async (params?: GetChatSessionsRequest) => { + loading.value = true; + try { + const response = await $chatApi.getSessions(params); + sessions.value = response.sessions; + return response; + } finally { + loading.value = false; + } + }; + + // 获取会话消息 + const fetchMessages = async (params: GetChatMessagesRequest) => { + loading.value = true; + try { + const response = await $chatApi.getMessages(params); + messages.value = response.messages; + return response; + } finally { + loading.value = false; + } + }; + + // 发送消息 + const sendChatMessage = async (content: string, type: ChatMessageType) => { + if (!currentSession.value) return; + + try { + const response = await $chatApi.sendMessage({ + sessionId: currentSession.value.id, + content, + type + }); + messages.value.push(response.message); + return response.message; + } catch (error) { + throw error; + } + }; + + return { + sessions, + currentSession, + messages, + loading, + fetchSessions, + fetchMessages, + sendChatMessage + }; +}); +``` + +### 9.5 模型模块使用示例 + +```typescript +// stores/modelStore.ts +import { defineStore } from 'pinia'; +import { useNuxtApp } from '#app'; +import type { AIModel, ModelComment, GetModelDetailRequest } from 'knowai-core'; + +export const useModelStore = defineStore('model', () => { + const { $modelApi } = useNuxtApp(); + const plazaData = ref<{ models: AIModel[], hotRankings: any[], clickRankings: any[] } | null>(null); + const currentModel = ref(null); + const modelComments = ref([]); + const loading = ref(false); + + // 获取AI广场数据 + const fetchAIPlaza = async () => { + loading.value = true; + try { + const response = await $modelApi.getAIPlaza(); + plazaData.value = response; + return response; + } finally { + loading.value = false; + } + }; + + // 获取模型详情 + const fetchModelDetail = async (modelId: string) => { + loading.value = true; + try { + const response = await $modelApi.getModelDetail({ modelId }); + currentModel.value = response.model; + modelComments.value = response.comments; + return response; + } finally { + loading.value = false; + } + }; + + return { + plazaData, + currentModel, + modelComments, + loading, + fetchAIPlaza, + fetchModelDetail + }; +}); +``` + +## 10. 注意事项 + +1. **认证处理**:所有需要认证的接口通过浏览器的 cookie-session 机制自动处理,无需手动添加令牌,session 完全由服务器端控制 +2. **错误处理**:使用 try/catch 捕获 API 调用可能出现的错误 +3. **分页处理**:注意检查 `hasMore` 字段来实现分页加载 +4. **数据缓存**:建议在 store 中缓存常用数据,避免重复请求 +5. **类型安全**:使用 TypeScript 类型确保数据结构正确性 +6. **聊天会话管理**:注意处理聊天会话中的未读消息计数 +7. **模型数据**:AI广场数据是静态配置的,不需要分页参数 + +## 11. 完整API参考 + +详细的API参考请查看 `knowai-core/api/modules` 目录下的各个模块文件。 \ No newline at end of file diff --git a/api/modules/post.ts b/api/modules/post.ts index 3097308..6f85ded 100644 --- a/api/modules/post.ts +++ b/api/modules/post.ts @@ -16,7 +16,11 @@ import type { GetCommentsRequest, GetCommentsResponse, LikeCommentRequest, - LikeCommentResponse + LikeCommentResponse, + GetHotPostsRequest, + GetHotPostsResponse, + GetPostRankingRequest, + GetPostRankingResponse } from '@/types/post/api'; // 帖子API服务工厂函数 @@ -61,5 +65,15 @@ export const postApi = (client: ApiClient) => ({ // 点赞评论 likeComment: ({ commentId }: LikeCommentRequest): Promise => { return client.put(`/comments/${commentId}/like`); + }, + + // 获取热门帖子 + getHotPosts: (params: GetHotPostsRequest = {}): Promise => { + return client.get('/posts/hot', { params }); + }, + + // 获取帖子榜单 + getPostRanking: (params: GetPostRankingRequest = {}): Promise => { + return client.get('/posts/ranking', { params }); } }); diff --git a/api/modules/user.ts b/api/modules/user.ts index 2711ed3..9739a2d 100644 --- a/api/modules/user.ts +++ b/api/modules/user.ts @@ -9,7 +9,11 @@ import type { UserProfileUpdateRequest, UserProfileUpdateResponse, UserFollowRequest, - UserFollowResponse + UserFollowResponse, + GetHotAuthorsRequest, + GetHotAuthorsResponse, + GetAuthorRankingRequest, + GetAuthorRankingResponse } from '@/types/user'; // 用户API服务工厂函数 @@ -47,5 +51,15 @@ export const userApi = (client: ApiClient) => ({ // 取消关注用户 unfollowUser: ({ userId }: UserFollowRequest): Promise => { return client.delete(`/user/follow/${userId}`); + }, + + // 获取热门作者 + getHotAuthors: (params: GetHotAuthorsRequest = {}): Promise => { + return client.get('/user/hot', { params }); + }, + + // 获取作者榜单 + getAuthorRanking: (params: GetAuthorRankingRequest = {}): Promise => { + return client.get('/user/ranking', { params }); } }); diff --git a/auth/session-manager.ts b/auth/session-manager.ts index c8134dc..7fff07a 100644 --- a/auth/session-manager.ts +++ b/auth/session-manager.ts @@ -48,7 +48,7 @@ export class DefaultSessionManager { this.currentUser = response.user; // 如果成功获取用户信息,触发session_authenticated事件 authEventManager.emit('session_authenticated', this.currentUser); - return this.currentUser; + return response.user; } catch (error) { this.currentUser = null; // 如果获取用户信息失败,触发session_expired事件 diff --git a/types/README.md b/types/README.md deleted file mode 100644 index 35fb033..0000000 --- a/types/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Types 模块 - -## 架构设计 - -Types模块用于定义前端数据模型,提供给其他模块进行API或行为封装。 - -## 包含 - -1. **chat** - - 包 \ No newline at end of file diff --git a/types/chat/api.d.ts b/types/chat/api.ts similarity index 100% rename from types/chat/api.d.ts rename to types/chat/api.ts diff --git a/types/chat/base.d.ts b/types/chat/base.ts similarity index 100% rename from types/chat/base.d.ts rename to types/chat/base.ts diff --git a/types/chat/enum.d.ts b/types/chat/enum.ts similarity index 100% rename from types/chat/enum.d.ts rename to types/chat/enum.ts diff --git a/types/chat/index.d.ts b/types/chat/index.ts similarity index 100% rename from types/chat/index.d.ts rename to types/chat/index.ts diff --git a/types/index.d.ts b/types/index.ts similarity index 100% rename from types/index.d.ts rename to types/index.ts diff --git a/types/model/api.d.ts b/types/model/api.ts similarity index 100% rename from types/model/api.d.ts rename to types/model/api.ts diff --git a/types/model/base.d.ts b/types/model/base.ts similarity index 100% rename from types/model/base.d.ts rename to types/model/base.ts diff --git a/types/model/enum.d.ts b/types/model/enum.ts similarity index 100% rename from types/model/enum.d.ts rename to types/model/enum.ts diff --git a/types/model/index.d.ts b/types/model/index.ts similarity index 100% rename from types/model/index.d.ts rename to types/model/index.ts diff --git a/types/post/api.d.ts b/types/post/api.ts similarity index 77% rename from types/post/api.d.ts rename to types/post/api.ts index 265e3ad..6f40c82 100644 --- a/types/post/api.d.ts +++ b/types/post/api.ts @@ -111,6 +111,33 @@ export interface LikeCommentResponse { success: boolean; } +// 获取热门帖子请求接口 +export interface GetHotPostsRequest { + limit?: number; // 每页数量 + days?: number; // 统计天数,默认7天 +} + +// 获取热门帖子响应接口 +export interface GetHotPostsResponse { + data: Post[]; // 数据列表 + total: number; // 总数 +} + +// 获取帖子榜单请求接口 +export interface GetPostRankingRequest { + limit?: number; // 每页数量 + period?: 'day' | 'week' | 'month'; // 统计周期 + type?: 'views' | 'likes' | 'comments'; // 排序类型 +} + +// 获取帖子榜单响应接口 +export interface GetPostRankingResponse { + data: Post[]; // 数据列表 + total: number; // 总数 + period: 'day' | 'week' | 'month'; // 统计周期 + type: 'views' | 'likes' | 'comments'; // 排序类型 +} + // 后面全部暂时不考虑 // 删除帖子请求接口 export interface DeletePostRequest { diff --git a/types/post/base.d.ts b/types/post/base.ts similarity index 100% rename from types/post/base.d.ts rename to types/post/base.ts diff --git a/types/post/enum.d.ts b/types/post/enum.ts similarity index 100% rename from types/post/enum.d.ts rename to types/post/enum.ts diff --git a/types/post/index.d.ts b/types/post/index.ts similarity index 100% rename from types/post/index.d.ts rename to types/post/index.ts diff --git a/types/user/api.ts b/types/user/api.ts new file mode 100644 index 0000000..cc16720 --- /dev/null +++ b/types/user/api.ts @@ -0,0 +1,28 @@ +import type { User } from './base'; + +// 获取热门作者请求接口 +export interface GetHotAuthorsRequest { + limit?: number; // 每页数量 + days?: number; // 统计天数,默认30天 +} + +// 获取热门作者响应接口 +export interface GetHotAuthorsResponse { + data: User[]; // 数据列表 + total: number; // 总数 +} + +// 获取作者榜单请求接口 +export interface GetAuthorRankingRequest { + limit?: number; // 每页数量 + period?: 'day' | 'week' | 'month'; // 统计周期 + type?: 'posts' | 'views' | 'likes'; // 排序类型 +} + +// 获取作者榜单响应接口 +export interface GetAuthorRankingResponse { + data: User[]; // 数据列表 + total: number; // 总数 + period: 'day' | 'week' | 'month'; // 统计周期 + type: 'posts' | 'views' | 'likes'; // 排序类型 +} diff --git a/types/user/base.d.ts b/types/user/base.ts similarity index 100% rename from types/user/base.d.ts rename to types/user/base.ts diff --git a/types/user/enum.d.ts b/types/user/enum.ts similarity index 100% rename from types/user/enum.d.ts rename to types/user/enum.ts diff --git a/types/user/index.d.ts b/types/user/index.ts similarity index 81% rename from types/user/index.d.ts rename to types/user/index.ts index b0b0eb0..c206117 100644 --- a/types/user/index.d.ts +++ b/types/user/index.ts @@ -2,3 +2,4 @@ export * from './base'; export * from './profile'; export * from './search'; export * from './enum'; +export * from './api'; diff --git a/types/user/profile.d.ts b/types/user/profile.ts similarity index 100% rename from types/user/profile.d.ts rename to types/user/profile.ts diff --git a/types/user/search.d.ts b/types/user/search.ts similarity index 100% rename from types/user/search.d.ts rename to types/user/search.ts diff --git a/utils/index.ts b/utils/index.ts index 1c72578..dbb5520 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -1,5 +1,6 @@ // 导出所有工具函数 export * from './date'; export * from './string'; +export * from './number'; export * from './data'; export * from './validation'; diff --git a/utils/number.ts b/utils/number.ts new file mode 100644 index 0000000..0946b6f --- /dev/null +++ b/utils/number.ts @@ -0,0 +1,54 @@ +// 数字格式化工具 +export const numberUtils = { + // 格式化数字,添加千分位分隔符 + format: (num: number, decimalPlaces: number = 0): string => { + if (isNaN(num)) return '0'; + return num.toFixed(decimalPlaces).replace(/\B(?=(\d{3})+(?!\d))/g, ','); + }, + + // 格式化大数字为K、M、B等形式 + formatLarge: (num: number, decimalPlaces: number = 1): string => { + if (isNaN(num)) return '0'; + + const thresholds = [ + { value: 1, symbol: '' }, + { value: 1000, symbol: 'K' }, + { value: 1000000, symbol: 'M' }, + { value: 1000000000, symbol: 'B' }, + { value: 1000000000000, symbol: 'T' } + ]; + + // 找到合适的阈值 + const threshold = thresholds + .reverse() + .find(threshold => num >= threshold.value); + + if (!threshold) return '0'; + + // 计算并格式化 + const result = num / threshold.value; + return `${result.toFixed(decimalPlaces)}${threshold.symbol}`; + }, + + // 格式化数字为中文形式(万、亿等) + formatChinese: (num: number, decimalPlaces: number = 1): string => { + if (isNaN(num)) return '0'; + + const thresholds = [ + { value: 1, symbol: '' }, + { value: 10000, symbol: '万' }, + { value: 100000000, symbol: '亿' } + ]; + + // 找到合适的阈值 + const threshold = thresholds + .reverse() + .find(threshold => num >= threshold.value); + + if (!threshold) return '0'; + + // 计算并格式化 + const result = num / threshold.value; + return `${result.toFixed(decimalPlaces)}${threshold.symbol}`; + } +};