feat(api): 添加热门卡片与榜单接口及实现

- 新增热门帖子、热门作者、榜单接口及实现
- 新增api-documentation,更好的ai协作
- 修复types没有导出的问题

BREAKING CHANGES: 1.0.0->1.1.0(latest)
This commit is contained in:
tobegold574
2025-11-18 22:29:40 +08:00
parent c3a8a525cb
commit a0c907beed
28 changed files with 1074 additions and 15 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ node_modules
# 测试与打包
coverage/
dist/
# 编辑器
.vscode/*

View File

@@ -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撰写
- 重新整理所有逻辑模块架构完成对应README撰写
### 2025-11-12
- 实现帖子相关新功能:热门帖子、帖子榜单
- 实现用户相关新功能:热门作者、作者榜单
- 更新README文档添加新功能说明
### 2025-11-18
- 添加热门帖子、榜单、热门作者接口
- 完成api-documentation.md文档详细描述所有接口的功能、参数、响应格式等
- 修复类型未导出问题

909
api-documentation.md Normal file
View File

@@ -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<T = unknown>(config: AxiosRequestConfig): Promise<T>;
get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
setDefaults(config: Partial<AxiosRequestConfig>): void;
setBaseURL(baseURL: string): void;
createInstance(config?: Partial<AxiosRequestConfig>): ApiClient;
addRequestInterceptor(
onFulfilled?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>,
onRejected?: (error: unknown) => unknown
): number;
addResponseInterceptor(
onFulfilled?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>,
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<CreatePostResponse>;
// 获取帖子列表
getPosts(params: GetPostsRequest): Promise<GetPostsResponse>;
// 获取帖子详情
getPost({ postId }: GetPostRequest): Promise<GetPostResponse>;
// 点赞帖子
likePost({ postId }: LikePostRequest): Promise<LikePostResponse>;
// 收藏帖子
bookmarkPost({ postId }: BookmarkPostRequest): Promise<BookmarkPostResponse>;
// 创建评论
createComment(data: CreateCommentRequest): Promise<CreateCommentResponse>;
// 获取评论列表
getComments(params: GetCommentsRequest): Promise<GetCommentsResponse>;
// 点赞评论
likeComment({ commentId }: LikeCommentRequest): Promise<LikeCommentResponse>;
// 获取热门帖子
getHotPosts(params?: GetHotPostsRequest): Promise<GetHotPostsResponse>;
// 获取帖子榜单
getPostRanking(params?: GetPostRankingRequest): Promise<GetPostRankingResponse>;
```
### 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<string, unknown>; // 元数据
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<LoginResponse>;
// 用户注册
register(data: RegisterRequest): Promise<RegisterResponse>;
// 系统使用服务器端session管理无需手动刷新令牌
// 获取用户档案
getProfile(): Promise<UserProfileUpdateResponse>;
// 更新用户档案
updateProfile(data: UserProfileUpdateRequest): Promise<UserProfileUpdateResponse>;
// 关注用户
followUser({ userId }: UserFollowRequest): Promise<UserFollowResponse>;
// 取消关注用户
unfollowUser({ userId }: UserFollowRequest): Promise<UserFollowResponse>;
// 获取热门作者
getHotAuthors(params?: GetHotAuthorsRequest): Promise<GetHotAuthorsResponse>;
// 获取作者榜单
getAuthorRanking(params?: GetAuthorRankingRequest): Promise<GetAuthorRankingResponse>;
```
### 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<GetChatSessionsResponse>;
// 获取聊天消息
getMessages({ sessionId, ...params }: GetChatMessagesRequest): Promise<GetChatMessagesResponse>;
// 标记消息已读
markMessagesAsRead({ sessionId, messageIds }: MarkMessagesAsReadRequest): Promise<MarkMessagesAsReadResponse>;
```
### 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<string, unknown>;
}
```
#### 获取聊天会话列表响应
```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<GetAIPlazaResponse>;
// 获取模型详情
getModelDetail({ modelId, ...params }: GetModelDetailRequest): Promise<GetModelDetailResponse>;
// 获取模型评论
getModelComments({ modelId, ...params }: GetModelCommentsRequest): Promise<GetModelCommentsResponse>;
```
### 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<T = unknown> {
success: boolean;
data: T;
message?: string;
code?: number;
}
// 分页响应
export interface PaginatedResponse<T = unknown> {
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
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useNuxtApp } from '#app';
const { $postApi, $userApi } = useNuxtApp();
const posts = ref([]);
const hotPosts = ref([]);
const postRanking = ref([]);
const hotAuthors = ref([]);
const authorRanking = ref([]);
const loading = ref(false);
const error = ref(null);
onMounted(async () => {
loading.value = true;
try {
// 获取普通帖子列表
const response = await $postApi.getPosts({
page: 1,
limit: 10,
sortBy: 'latest'
});
posts.value = response.data;
// 获取热门帖子
const hotPostsResponse = await $postApi.getHotPosts({
limit: 5,
days: 7
});
hotPosts.value = hotPostsResponse.data;
// 获取帖子榜单(周榜,按点赞数排序)
const rankingResponse = await $postApi.getPostRanking({
limit: 10,
period: 'week',
type: 'likes'
});
postRanking.value = rankingResponse.data;
// 获取热门作者
const hotAuthorsResponse = await $userApi.getHotAuthors({
limit: 5,
days: 30
});
hotAuthors.value = hotAuthorsResponse.data;
// 获取作者榜单(月榜,按发帖量排序)
const authorRankingResponse = await $userApi.getAuthorRanking({
limit: 10,
period: 'month',
type: 'posts'
});
authorRanking.value = authorRankingResponse.data;
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
});
</script>
```
### 9.3 在页面中使用认证服务
```typescript
// pages/auth/login.vue
<script setup lang="ts">
import { ref } from 'vue';
import { useNuxtApp, navigateTo } from '#app';
import type { LoginRequest } from 'knowai-core';
const { $authService } = useNuxtApp();
const loginForm = ref<LoginRequest>({
username: '',
password: ''
});
const loading = ref(false);
const error = ref<string | null>(null);
// 用户登录
const handleLogin = async () => {
loading.value = true;
error.value = null;
try {
await $authService.login(loginForm.value);
// 登录成功,跳转到首页
await navigateTo('/');
} catch (err: any) {
error.value = err.message || '登录失败,请检查用户名和密码';
} finally {
loading.value = false;
}
};
</script>
<template>
<div class="login-form">
<h1>登录</h1>
<div v-if="error" class="error-message">{{ error }}</div>
<form @submit.prevent="handleLogin">
<div>
<label>用户名</label>
<input v-model="loginForm.username" type="text" required />
</div>
<div>
<label>密码</label>
<input v-model="loginForm.password" type="password" required />
</div>
<button type="submit" :disabled="loading">
{{ loading ? '登录中...' : '登录' }}
</button>
</form>
</div>
</template>
```
### 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
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
});
// 页面内容...
</script>
```
### 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<Post[]>([]);
const loading = ref(false);
const error = ref<string | null>(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<ChatSession[]>([]);
const currentSession = ref<ChatSession | null>(null);
const messages = ref<ChatMessage[]>([]);
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<AIModel | null>(null);
const modelComments = ref<ModelComment[]>([]);
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` 目录下的各个模块文件。

View File

@@ -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<LikeCommentResponse> => {
return client.put(`/comments/${commentId}/like`);
},
// 获取热门帖子
getHotPosts: (params: GetHotPostsRequest = {}): Promise<GetHotPostsResponse> => {
return client.get('/posts/hot', { params });
},
// 获取帖子榜单
getPostRanking: (params: GetPostRankingRequest = {}): Promise<GetPostRankingResponse> => {
return client.get('/posts/ranking', { params });
}
});

View File

@@ -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<UserFollowResponse> => {
return client.delete(`/user/follow/${userId}`);
},
// 获取热门作者
getHotAuthors: (params: GetHotAuthorsRequest = {}): Promise<GetHotAuthorsResponse> => {
return client.get('/user/hot', { params });
},
// 获取作者榜单
getAuthorRanking: (params: GetAuthorRankingRequest = {}): Promise<GetAuthorRankingResponse> => {
return client.get('/user/ranking', { params });
}
});

View File

@@ -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事件

View File

@@ -1,10 +0,0 @@
# Types 模块
## 架构设计
Types模块用于定义前端数据模型提供给其他模块进行API或行为封装。
## 包含
1. **chat**
- 包

View File

@@ -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 {

28
types/user/api.ts Normal file
View File

@@ -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'; // 排序类型
}

View File

@@ -2,3 +2,4 @@ export * from './base';
export * from './profile';
export * from './search';
export * from './enum';
export * from './api';

View File

@@ -1,5 +1,6 @@
// 导出所有工具函数
export * from './date';
export * from './string';
export * from './number';
export * from './data';
export * from './validation';

54
utils/number.ts Normal file
View File

@@ -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}`;
}
};