Files
knowai/api-documentation.md
tobegold574 a0c907beed feat(api): 添加热门卡片与榜单接口及实现
- 新增热门帖子、热门作者、榜单接口及实现
- 新增api-documentation,更好的ai协作
- 修复types没有导出的问题

BREAKING CHANGES: 1.0.0->1.1.0(latest)
2025-11-18 22:29:40 +08:00

22 KiB
Raw Permalink Blame History

KnowAI Core API 文档

本文档详细介绍了 KnowAI Core 库提供的 API 接口和类型定义,供 Page 层项目使用。

1. 库概述

KnowAI Core 是一个通用的前端核心库,提供了 API 调用、认证管理、工具函数等基础功能。

// 导入方式
export * from './types';      // 类型定义
export * from './api';        // API客户端和模块
export * from './auth';       // 鉴权相关功能
export * from './utils';      // 工具函数

2. API 客户端

2.1 初始化 API 客户端

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 客户端功能

// 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 接口

// 获取帖子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 数据类型定义

创建帖子请求

export interface CreatePostRequest extends BaseEntityContent {
  type: PostType; // 帖子类型:提问或文章
  images?: string[]; // 图片
  publishedAt?: Date; // 发布时间
}

获取帖子列表请求

export interface GetPostsRequest {
  page?: number; // 页码
  limit?: number; // 每页数量
  sortBy?: PostSortBy; // 帖子排序方式
  type?: PostType; // 帖子类型:提问或文章
  sortOrder?: SortOrder; // 排序方向
  authorId?: string;
  search?: string;
}

获取帖子列表响应

export interface GetPostsResponse {
  data: Post[]; // 数据列表
  total: number; // 总数
  page: number; // 当前页码
  limit: number; // 每页数量
  hasMore: boolean; // 是否有更多数据
  sortBy?: PostSortBy; // 帖子排序方式
}

帖子接口

export interface Post extends BaseEntity, BaseEntityContent {
  type: PostType; // 帖子类型:提问或文章
  authorId: string; // 作者ID
  author: BaseUser; // 作者信息
  images?: string[]; // 图片数组
  publishedAt?: Date; // 发布时间
}

基础实体内容接口

export interface BaseEntityContent {
  title?: string; // 标题
  excerpt: string; // 摘要
  tags?: string[]; // 标签数组
  metadata?: Record<string, unknown>; // 元数据
  stars: number; // 收藏数
  likes: number; // 点赞数
  comments: number; // 评论数
}

获取热门帖子请求

export interface GetHotPostsRequest {
    limit?: number; // 限制数量
    days?: number; // 时间范围(天)
}

获取热门帖子响应

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'; // 榜单类型
}

4. 用户模块 (User)

4.1 API 接口

// 获取用户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 数据类型定义

登录请求

export interface LoginRequest {
    username: string;
    password: string;
}

登录响应

export interface LoginResponse {
    user: User;
}

用户接口

export interface User {
    id: string;
    username: string;
}

获取热门作者请求

export interface GetHotAuthorsRequest {
    limit?: number; // 限制数量
    days?: number; // 时间范围(天)
}

获取热门作者响应

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'; // 榜单类型
}

5. 聊天模块 (Chat)

5.1 API 接口

// 获取聊天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 数据类型定义

聊天消息接口

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

聊天会话接口

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

发送消息请求

export interface SendMessageRequest {
    sessionId: string;
    content: string;
    type: ChatMessageType;
    metadata?: Record<string, unknown>;
}

获取聊天会话列表响应

export interface GetChatSessionsResponse {
    sessions: ChatSession[];
    total: number;
    page: number;
    limit: number;
}

6. 模型模块 (Model)

6.1 API 接口

// 获取模型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模型接口

export interface AIModel {
  id: string;
  name: string;
  description: string;
  avatar?: string; // 模型头像
  tags?: string[]; // 模型标签
  website?: string; // 官方网站
  clickCount?: number; // 点击次数
  likeCount?: number; // 点赞次数
}

AI模型评论接口

export interface ModelComment extends BaseEntity {
  modelId: string; // 模型ID
  authorId: string; // 作者ID
  author: BaseUser; // 作者信息
  content: string; // 评论内容
  parentId?: string; // 父评论ID用于嵌套评论
  stats: ModelCommentStats; // 统计信息
}

AI模型广场响应

export interface GetAIPlazaResponse {
  models: AIModel[]; // 模型卡片列表,由管理员预定义
  hotRankings: AIModelRankingItem[]; // 热评模型榜单
  clickRankings: AIModelRankingItem[]; // 点击排行榜
}

模型详情响应

export interface GetModelDetailResponse {
  model: AIModel;
  comments: ModelComment[]; // 使用新的ModelComment类型已经是数组
  totalComments: number;
  hasMoreComments: boolean;   // 是否还有更多评论,支持无限滚动加载
}

7. 通用数据类型

7.1 API 响应结构

// 标准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 常量定义

// 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 错误处理示例

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 插件)

// 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

// 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 在页面中使用认证服务

// 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 检查用户认证状态

// 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

// 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 聊天功能使用示例

// 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 模型模块使用示例

// 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 目录下的各个模块文件。