2026-09-04 12:51:58 +00:00
|
|
|
|
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import apiService from '@/services/api.service'
|
|
|
|
|
|
|
|
|
|
|
|
export interface ForumSearchResult {
|
|
|
|
|
|
categories: ForumCategory[]
|
|
|
|
|
|
topics: ForumTopic[]
|
|
|
|
|
|
posts: ForumPost[]
|
|
|
|
|
|
totalCount: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface SearchParams {
|
|
|
|
|
|
query: string
|
|
|
|
|
|
categoryId?: string
|
|
|
|
|
|
topicId?: string
|
|
|
|
|
|
searchInCategories?: boolean
|
|
|
|
|
|
searchInTopics?: boolean
|
|
|
|
|
|
searchInPosts?: boolean
|
|
|
|
|
|
page?: number
|
|
|
|
|
|
pageSize?: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface PaginatedResponse<T> {
|
|
|
|
|
|
items: T[]
|
|
|
|
|
|
totalCount: number
|
|
|
|
|
|
pageNumber: number
|
|
|
|
|
|
pageSize: number
|
|
|
|
|
|
totalPages: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface CreateTopicRequest {
|
|
|
|
|
|
title: string
|
|
|
|
|
|
content: string
|
|
|
|
|
|
categoryId: string
|
|
|
|
|
|
isPinned?: boolean
|
|
|
|
|
|
isLocked?: boolean
|
|
|
|
|
|
tenantId?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface CreatePostRequest {
|
|
|
|
|
|
topicId: string
|
|
|
|
|
|
content: string
|
|
|
|
|
|
parentPostId?: string
|
|
|
|
|
|
tenantId?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface CategoryListParams {
|
|
|
|
|
|
page?: number
|
|
|
|
|
|
pageSize?: number
|
|
|
|
|
|
isActive?: boolean
|
|
|
|
|
|
search?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface TopicListParams {
|
|
|
|
|
|
page?: number
|
|
|
|
|
|
pageSize?: number
|
|
|
|
|
|
categoryId?: string
|
|
|
|
|
|
isPinned?: boolean
|
|
|
|
|
|
isSolved?: boolean
|
|
|
|
|
|
search?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface PostListParams {
|
|
|
|
|
|
page?: number
|
|
|
|
|
|
pageSize?: number
|
|
|
|
|
|
topicId?: string
|
|
|
|
|
|
isAcceptedAnswer?: boolean
|
|
|
|
|
|
search?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class ForumService {
|
|
|
|
|
|
// Search
|
|
|
|
|
|
async search(params: SearchParams): Promise<ForumSearchResult> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumSearchResult>({
|
|
|
|
|
|
url: '/api/app/forum/search',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Categories
|
|
|
|
|
|
async getCategories(params: CategoryListParams = {}): Promise<PaginatedResponse<ForumCategory>> {
|
|
|
|
|
|
const response = await apiService.fetchData<PaginatedResponse<ForumCategory>>({
|
|
|
|
|
|
url: '/api/app/forum/categories',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getCategoryById(id: string): Promise<ForumCategory> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumCategory>({
|
|
|
|
|
|
url: `/api/app/forum/categories/${id}`,
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getCategoryBySlug(slug: string): Promise<ForumCategory> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumCategory>({
|
|
|
|
|
|
url: `/api/app/forum/categories/by-slug`,
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params: { slug },
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Topics
|
|
|
|
|
|
async getTopics(params: TopicListParams = {}): Promise<PaginatedResponse<ForumTopic>> {
|
|
|
|
|
|
const response = await apiService.fetchData<PaginatedResponse<ForumTopic>>({
|
|
|
|
|
|
url: '/api/app/forum/topics',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getTopicById(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/topic`,
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async createTopic(data: CreateTopicRequest): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: '/api/app/forum/topic',
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
data: {...data},
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async updateTopic(id: string, data: Partial<CreateTopicRequest>): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/topic`,
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
data,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async deleteTopic(id: string): Promise<void> {
|
|
|
|
|
|
await apiService.fetchData({
|
|
|
|
|
|
url: `/api/app/forum/${id}/topic`,
|
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async likeTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/like-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unlikeTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unlike-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async pinTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/pin-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unpinTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unpin-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async lockTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/lock-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unlockTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unlock-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async solvedTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/solved-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unsolvedTopic(id: string): Promise<ForumTopic> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumTopic>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unsolved-topic`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Posts
|
|
|
|
|
|
async getPosts(params: PostListParams = {}): Promise<PaginatedResponse<ForumPost>> {
|
|
|
|
|
|
const response = await apiService.fetchData<PaginatedResponse<ForumPost>>({
|
|
|
|
|
|
url: '/api/app/forum/posts',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
params,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getPostById(id: string): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/posts/${id}`,
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async createPost(data: CreatePostRequest): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: '/api/app/forum/post',
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
data: {...data},
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async updatePost(id: string, data: Partial<CreatePostRequest>): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/post`,
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
data,
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async deletePost(id: string): Promise<void> {
|
|
|
|
|
|
await apiService.fetchData({
|
|
|
|
|
|
url: `/api/app/forum/${id}/post`,
|
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async likePost(id: string): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/like-post`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unlikePost(id: string): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unlike-post`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async markPostAsAcceptedAnswer(id: string): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/mark-post`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async unmarkPostAsAcceptedAnswer(id: string): Promise<ForumPost> {
|
|
|
|
|
|
const response = await apiService.fetchData<ForumPost>({
|
|
|
|
|
|
url: `/api/app/forum/${id}/unmark-post`,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
})
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Forum statistics
|
|
|
|
|
|
async getForumStats(): Promise<{
|
|
|
|
|
|
totalCategories: number
|
|
|
|
|
|
totalTopics: number
|
|
|
|
|
|
totalPosts: number
|
|
|
|
|
|
totalUsers: number
|
|
|
|
|
|
activeUsers: number
|
|
|
|
|
|
}> {
|
|
|
|
|
|
const response = await apiService.fetchData<{
|
|
|
|
|
|
totalCategories: number
|
|
|
|
|
|
totalTopics: number
|
|
|
|
|
|
totalPosts: number
|
|
|
|
|
|
totalUsers: number
|
|
|
|
|
|
activeUsers: number
|
|
|
|
|
|
}>({
|
|
|
|
|
|
url: '/api/app/forum/stats',
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const forumService = new ForumService()
|