保存本地对routes.ts的修改
Change-Id: I4f4dbd8069893d7363e251130791dc0594be44e1
diff --git a/src/api/categoryApi.ts b/src/api/categoryApi.ts
new file mode 100644
index 0000000..816ac71
--- /dev/null
+++ b/src/api/categoryApi.ts
@@ -0,0 +1,90 @@
+import axios from 'axios';
+import type { CategoryDTO, Category, WorkResponse } from './otherType';
+
+const API_BASE_URL = '/api';
+
+class CategoryAPI {
+ /**
+ * 获取全部分区(树形结构)
+ * @returns 返回分区的树形结构数据
+ */
+ static getCategoryTree(): Promise<CategoryDTO[]> {
+ return axios.get<CategoryDTO[]>(`${API_BASE_URL}/categories`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取单个分区详情
+ * @param id 分区ID
+ * @returns 返回单个分区的详细信息
+ */
+ static getCategory(id: number): Promise<Category> {
+ return axios.get<Category>(`${API_BASE_URL}/categories/${id}`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 创建新分区
+ * @param category 分区数据(不包含ID)
+ * @returns 返回创建成功的消息
+ */
+ static createCategory(category: Omit<Category, 'id'>): Promise<string> {
+ return axios.post<string>(`${API_BASE_URL}/categories`, category)
+ .then(response => response.data);
+ }
+
+ /**
+ * 更新分区信息
+ * @param id 分区ID
+ * @param category 更新后的分区数据
+ * @returns 返回更新成功的消息
+ */
+ static updateCategory(id: number, category: Partial<Category>): Promise<string> {
+ return axios.put<string>(`${API_BASE_URL}/categories/${id}`, category)
+ .then(response => response.data);
+ }
+
+ /**
+ * 删除分区
+ * @param id 分区ID
+ * @returns 返回删除成功的消息
+ */
+ static deleteCategory(id: number): Promise<string> {
+ return axios.delete<string>(`${API_BASE_URL}/categories/${id}`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取分区下的作品列表(带分页)
+ * @param categoryId 分区ID
+ * @param params 分页和排序参数
+ * @returns 返回作品列表和分页信息
+ */
+ static getWorksByCategory(
+ categoryId: number,
+ params?: {
+ page?: number;
+ size?: number;
+ sort?: string;
+ }
+ ): Promise<WorkResponse> {
+ return axios.get<WorkResponse>(`${API_BASE_URL}/works`, {
+ params: {
+ categoryId,
+ ...params
+ }
+ }).then(response => response.data);
+ }
+
+ /**
+ * 获取子分区列表
+ * @param parentId 父分区ID
+ * @returns 返回子分区列表
+ */
+ static getSubCategories(parentId: number): Promise<CategoryDTO[]> {
+ return axios.get<CategoryDTO[]>(`${API_BASE_URL}/categories/${parentId}/children`)
+ .then(response => response.data);
+ }
+}
+
+export default CategoryAPI;
\ No newline at end of file
diff --git a/src/api/categoryTypes.ts b/src/api/categoryTypes.ts
new file mode 100644
index 0000000..4a46034
--- /dev/null
+++ b/src/api/categoryTypes.ts
@@ -0,0 +1,67 @@
+import type { ReactNode } from "react";
+
+// 基础分类接口
+export interface CategoryDTO {
+ id: number;
+ name: string;
+ description?: string;
+ parentId?: number; // 移除了 null 类型,只保留 number | undefined
+ children?: CategoryDTO[];
+ workCount?: number;
+}
+
+
+// 基础资源接口
+interface BaseResource {
+ id: number;
+ title: string;
+ categoryId: number;
+ categoryName: string;
+ uploadDate: string;
+ uploader: string;
+ size: string;
+ seeders: number;
+ leechers: number;
+ downloadCount: number;
+ hash: string;
+}
+
+// 音乐资源
+export interface MusicResource extends BaseResource {
+ category: ReactNode;
+ artist: string;
+ quality: 'MP3 128k' | 'MP3 320k' | 'FLAC' | 'APE' | 'Hi-Res' | 'DSD';
+ genre: string[];
+}
+
+// 影视资源
+export interface MovieResource extends BaseResource {
+ director: string;
+ actors: string[];
+ resolution: '1080p' | '720p' | '4K' | '8K';
+ duration: string;
+}
+
+// 游戏资源
+export interface GameResource extends BaseResource {
+ developer: string;
+ publisher: string;
+ platform: 'PC' | 'PS' | 'Xbox' | 'Switch';
+ releaseDate: string;
+}
+
+// 其他资源
+export interface OtherResource extends BaseResource {
+ description: string;
+ fileType: string;
+}
+
+// 分类DTO
+export interface CategoryDTO {
+ id: number;
+ name: string;
+ description?: string;
+ parentId?: number;
+ children?: CategoryDTO[];
+ workCount?: number;
+}
\ No newline at end of file
diff --git a/src/api/commentApi.ts b/src/api/commentApi.ts
new file mode 100644
index 0000000..360e659
--- /dev/null
+++ b/src/api/commentApi.ts
@@ -0,0 +1,77 @@
+import axios from 'axios';
+import type { Comment, CommentFormData, CommentReply, ReplyFormData } from './otherType';
+
+const API_BASE_URL = '/api';
+
+class CommentAPI {
+ /**
+ * 添加评论
+ */
+ static addComment(data: CommentFormData): Promise<Comment> {
+ return axios.post<Comment>(`${API_BASE_URL}/comments`, data)
+ .then(response => response.data);
+ }
+
+ /**
+ * 删除评论
+ */
+ static deleteComment(commentId: number): Promise<void> {
+ return axios.delete(`${API_BASE_URL}/comments/${commentId}`);
+ }
+
+ /**
+ * 更新评论
+ */
+ static updateComment(commentId: number, data: CommentFormData): Promise<Comment> {
+ return axios.put<Comment>(`${API_BASE_URL}/comments/${commentId}`, data)
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取单个评论
+ */
+ static getCommentById(commentId: number): Promise<Comment> {
+ return axios.get<Comment>(`${API_BASE_URL}/comments/${commentId}`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取帖子下的所有评论
+ */
+ static getCommentsByPostId(postId: number): Promise<Comment[]> {
+ return axios.get<Comment[]>(`${API_BASE_URL}/comments/post/${postId}`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 添加回复
+ */
+ static addReply(commentId: number, data: ReplyFormData): Promise<CommentReply> {
+ return axios.post<CommentReply>(`${API_BASE_URL}/comments/${commentId}/replies`, data)
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取评论的所有回复
+ */
+ static getReplies(commentId: number): Promise<CommentReply[]> {
+ return axios.get<CommentReply[]>(`${API_BASE_URL}/comments/${commentId}/replies`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 点赞评论
+ */
+ static likeComment(commentId: number): Promise<void> {
+ return axios.post(`${API_BASE_URL}/comments/${commentId}/like`);
+ }
+
+ /**
+ * 举报评论
+ */
+ static reportComment(commentId: number, reason: string): Promise<void> {
+ return axios.post(`${API_BASE_URL}/comments/${commentId}/report`, { reason });
+ }
+}
+
+export default CommentAPI;
\ No newline at end of file
diff --git a/src/api/otherType.ts b/src/api/otherType.ts
new file mode 100644
index 0000000..60523d0
--- /dev/null
+++ b/src/api/otherType.ts
@@ -0,0 +1,164 @@
+// 认证相关类型
+export interface LoginRequest {
+ email: string;
+ password: string;
+}
+
+export interface LoginResponse {
+ user: string;
+ token: string;
+ refreshToken: string;
+}
+
+export interface CommonResponse<T= null> {
+ code: number;
+ message: string;
+ data: T;
+}
+
+// 作品相关类型
+export interface Work {
+ size: string;
+ data(data: any): unknown;
+ artist: string;
+ quality: string;
+ genre: string[];
+ id: number;
+ title: string;
+ author: string;
+ authorId: number;
+ views: number;
+ likes: number;
+ categoryId: number;
+ categoryName: string;
+ description: string;
+ content: string;
+ coverUrl: string;
+ createTime: string;
+ attachments: Attachment[];
+ bugCount: number;
+ discussionCount: number;
+}
+
+export interface WorkResponse {
+ content: Work[];
+ totalElements: number;
+ totalPages: number;
+}
+
+export interface WorkFormData {
+ title: string;
+ categoryId: number;
+ description: string;
+ content: string;
+ coverFile?: File;
+ attachments?: File[];
+}
+
+// Bug反馈相关类型
+export interface BugReport {
+ id: number;
+ title: string;
+ description: string;
+ severity: 'low' | 'medium' | 'high';
+ status: 'open' | 'resolved' | 'wontfix';
+ reporter: string;
+ reporterId: number;
+ workId: number;
+ createTime: string;
+}
+
+// 讨论区相关类型
+export interface Discussion {
+ id: number;
+ title: string;
+ content: string;
+ author: string;
+ authorId: number;
+ workId: number;
+ isPinned: boolean;
+ commentCount: number;
+ createTime: string;
+ lastUpdateTime: string;
+}
+
+export interface DiscussionFormData {
+ workId: number;
+ title: string;
+ content: string;
+}
+
+// 评论相关类型
+export interface Comment {
+ id: number;
+ author: string;
+ avatar: string;
+ content: string;
+ likes: number;
+ replyCount: number;
+ createTime: string;
+ replies?: CommentReply[];
+}
+
+export interface CommentFormData {
+ postId: number; // 可以是作品ID或讨论区ID
+ content: string;
+ parentId?: number; // 用于回复评论
+}
+
+export interface CommentReply {
+ id: number;
+ author: string;
+ avatar: string;
+ content: string;
+ likes: number;
+ createTime: string;
+}
+
+export interface ReplyFormData {
+ content: string;
+}
+
+// 分区相关类型
+export interface Category {
+ id: number;
+ name: string;
+ description?: string;
+ parentId?: number | null;
+ coverUrl?: string;
+ createdAt?: string;
+ updatedAt?: string;
+}
+
+export interface CategoryDTO extends Category {
+ children?: CategoryDTO[];
+ workCount?: number;
+}
+
+// 用户相关类型
+export interface User {
+ id: number;
+ username: string;
+ email: string;
+ avatar?: string;
+ role: 'user' | 'admin';
+ createdAt: string;
+ worksCount: number;
+ completedWorks: number;
+}
+
+// 通用类型
+export interface Attachment {
+ id: number;
+ name: string;
+ url: string;
+ size: string;
+}
+
+// API响应通用类型
+export interface ApiResponse<T> {
+ success: boolean;
+ data?: T;
+ message?: string;
+ error?: string;
+}
\ No newline at end of file
diff --git a/src/api/workApi.ts b/src/api/workApi.ts
new file mode 100644
index 0000000..d624821
--- /dev/null
+++ b/src/api/workApi.ts
@@ -0,0 +1,105 @@
+import axios from 'axios';
+import type { Work, WorkResponse, WorkFormData, BugReport, Discussion } from './otherType';
+
+const API_BASE_URL = '/api';
+
+class WorkAPI {
+ /**
+ * 获取作品列表(支持分页、分类筛选和搜索)
+ */
+ static getWorks(params?: {
+ categoryId?: number;
+ page?: number;
+ size?: number;
+ search?: string;
+ }): Promise<WorkResponse> {
+ return axios.get<WorkResponse>(`${API_BASE_URL}/works`, { params })
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取单个作品详情
+ */
+ static getWorkById(id: number): Promise<Work> {
+ return axios.get<Work>(`${API_BASE_URL}/works/${id}`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 创建新作品
+ */
+ static createWork(data: WorkFormData): Promise<Work> {
+ return axios.post<Work>(`${API_BASE_URL}/works`, data)
+ .then(response => response.data);
+ }
+
+ /**
+ * 更新作品信息
+ */
+ static updateWork(id: number, data: WorkFormData): Promise<Work> {
+ return axios.put<Work>(`${API_BASE_URL}/works/${id}`, data)
+ .then(response => response.data);
+ }
+
+ /**
+ * 删除作品
+ */
+ static deleteWork(id: number): Promise<void> {
+ return axios.delete(`${API_BASE_URL}/works/${id}`);
+ }
+
+ /**
+ * 点赞作品
+ */
+ static likeWork(id: number): Promise<void> {
+ return axios.post(`${API_BASE_URL}/works/${id}/like`);
+ }
+
+ /**
+ * 根据作者查询作品
+ */
+ static getWorksByAuthor(author: string): Promise<Work[]> {
+ return axios.get<Work[]>(`${API_BASE_URL}/works/byAuthor`, { params: { author } })
+ .then(response => response.data);
+ }
+
+ /**
+ * 获取作品Bug反馈列表
+ */
+ static getBugReports(workId: number): Promise<BugReport[]> {
+ return axios.get<BugReport[]>(`${API_BASE_URL}/works/${workId}/bugs`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 提交Bug反馈
+ */
+ static reportBug(workId: number, data: {
+ title: string;
+ description: string;
+ severity: 'low' | 'medium' | 'high';
+ }): Promise<void> {
+ return axios.post(`${API_BASE_URL}/works/${workId}/bugs`, data);
+ }
+
+ /**
+ * 获取作品讨论区列表
+ */
+ static getDiscussions(workId: number): Promise<Discussion[]> {
+ return axios.get<Discussion[]>(`${API_BASE_URL}/works/${workId}/discussions`)
+ .then(response => response.data);
+ }
+
+ /**
+ * 创建新讨论
+ */
+ static createDiscussion(data: {
+ workId: number;
+ title: string;
+ content: string;
+ }): Promise<void> {
+ return axios.post(`${API_BASE_URL}/discussions`, data);
+ }
+}
+
+export default WorkAPI;
\ No newline at end of file