初始提交:极码 GeekCode 全栈项目(FastAPI + Vue3)
This commit is contained in:
30
frontend/src/api/index.js
Normal file
30
frontend/src/api/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 60000,
|
||||
})
|
||||
|
||||
// 请求拦截器:自动添加Token
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
// 响应拦截器:处理401
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401 && !error.config.url?.includes('/auth/')) {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('user')
|
||||
window.location.href = '/login'
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default api
|
||||
449
frontend/src/api/modules.js
Normal file
449
frontend/src/api/modules.js
Normal file
@@ -0,0 +1,449 @@
|
||||
import api from './index'
|
||||
|
||||
export const authApi = {
|
||||
register(data) {
|
||||
return api.post('/auth/register', data)
|
||||
},
|
||||
login(data) {
|
||||
return api.post('/auth/login', data)
|
||||
},
|
||||
getMe() {
|
||||
return api.get('/auth/me')
|
||||
},
|
||||
updateProfile(data) {
|
||||
return api.put('/auth/profile', data)
|
||||
},
|
||||
}
|
||||
|
||||
export const requirementApi = {
|
||||
getConversations() {
|
||||
return api.get('/requirement/conversations')
|
||||
},
|
||||
getConversation(id) {
|
||||
return api.get(`/requirement/conversations/${id}`)
|
||||
},
|
||||
deleteConversation(id) {
|
||||
return api.delete(`/requirement/conversations/${id}`)
|
||||
},
|
||||
uploadImage(file) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return api.post('/requirement/upload-image', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
},
|
||||
// analyze使用SSE流式,不走axios
|
||||
}
|
||||
|
||||
export const architectureApi = {
|
||||
getConversations() {
|
||||
return api.get('/architecture/conversations')
|
||||
},
|
||||
getConversation(id) {
|
||||
return api.get(`/architecture/conversations/${id}`)
|
||||
},
|
||||
deleteConversation(id) {
|
||||
return api.delete(`/architecture/conversations/${id}`)
|
||||
},
|
||||
}
|
||||
|
||||
export const postsApi = {
|
||||
getPosts(params) {
|
||||
return api.get('/posts', { params })
|
||||
},
|
||||
getPost(id) {
|
||||
return api.get(`/posts/${id}`)
|
||||
},
|
||||
createPost(data) {
|
||||
return api.post('/posts', data)
|
||||
},
|
||||
updatePost(id, data) {
|
||||
return api.put(`/posts/${id}`, data)
|
||||
},
|
||||
deletePost(id) {
|
||||
return api.delete(`/posts/${id}`)
|
||||
},
|
||||
toggleLike(id) {
|
||||
return api.post(`/posts/${id}/like`)
|
||||
},
|
||||
toggleCollect(id) {
|
||||
return api.post(`/posts/${id}/collect`)
|
||||
},
|
||||
getComments(id) {
|
||||
return api.get(`/posts/${id}/comments`)
|
||||
},
|
||||
createComment(id, data) {
|
||||
return api.post(`/posts/${id}/comments`, data)
|
||||
},
|
||||
getAttachments(id) {
|
||||
return api.get(`/posts/${id}/attachments`)
|
||||
},
|
||||
deleteAttachment(postId, attachmentId) {
|
||||
return api.delete(`/posts/${postId}/attachments/${attachmentId}`)
|
||||
},
|
||||
getDrafts(params) {
|
||||
return api.get('/posts/drafts', { params })
|
||||
},
|
||||
}
|
||||
|
||||
export const searchApi = {
|
||||
search(params) {
|
||||
return api.get('/search', { params })
|
||||
},
|
||||
}
|
||||
|
||||
export const aiModelsApi = {
|
||||
getPresets() {
|
||||
return api.get('/admin/models/presets')
|
||||
},
|
||||
getTaskTypes() {
|
||||
return api.get('/admin/models/task-types')
|
||||
},
|
||||
getModels(params) {
|
||||
return api.get('/admin/models', { params })
|
||||
},
|
||||
createModel(data) {
|
||||
return api.post('/admin/models', data)
|
||||
},
|
||||
updateModel(id, data) {
|
||||
return api.put(`/admin/models/${id}`, data)
|
||||
},
|
||||
deleteModel(id) {
|
||||
return api.delete(`/admin/models/${id}`)
|
||||
},
|
||||
initDefaults() {
|
||||
return api.post('/admin/models/init-defaults')
|
||||
},
|
||||
testConnection(id) {
|
||||
return api.post(`/admin/models/${id}/test`)
|
||||
},
|
||||
// 公开接口 - 获取可用模型列表(登录用户)
|
||||
getAvailableModels(params) {
|
||||
return api.get('/models/available', { params })
|
||||
},
|
||||
}
|
||||
|
||||
export const bookmarksApi = {
|
||||
getBookmarks() {
|
||||
return api.get('/bookmarks')
|
||||
},
|
||||
createBookmark(data) {
|
||||
return api.post('/bookmarks', data)
|
||||
},
|
||||
updateBookmark(id, data) {
|
||||
return api.put(`/bookmarks/${id}`, data)
|
||||
},
|
||||
deleteBookmark(id) {
|
||||
return api.delete(`/bookmarks/${id}`)
|
||||
},
|
||||
reorder(items) {
|
||||
return api.put('/bookmarks/reorder', { items })
|
||||
},
|
||||
}
|
||||
|
||||
export const usersApi = {
|
||||
getProfile(id) {
|
||||
return api.get(`/users/${id}`)
|
||||
},
|
||||
toggleFollow(id) {
|
||||
return api.post(`/users/${id}/follow`)
|
||||
},
|
||||
getUserPosts(id, params) {
|
||||
return api.get(`/users/${id}/posts`, { params })
|
||||
},
|
||||
getUserCollects(id, params) {
|
||||
return api.get(`/users/${id}/collects`, { params })
|
||||
},
|
||||
getFollowers(id, params) {
|
||||
return api.get(`/users/${id}/followers`, { params })
|
||||
},
|
||||
getFollowing(id, params) {
|
||||
return api.get(`/users/${id}/following`, { params })
|
||||
},
|
||||
}
|
||||
|
||||
export const notificationsApi = {
|
||||
getNotifications(params) {
|
||||
return api.get('/notifications', { params })
|
||||
},
|
||||
getUnreadCount() {
|
||||
return api.get('/notifications/unread-count')
|
||||
},
|
||||
readAll() {
|
||||
return api.put('/notifications/read-all')
|
||||
},
|
||||
readOne(id) {
|
||||
return api.put(`/notifications/${id}/read`)
|
||||
},
|
||||
}
|
||||
|
||||
export const feedApi = {
|
||||
getFeed(params) {
|
||||
return api.get('/posts/feed', { params })
|
||||
},
|
||||
getHot(params) {
|
||||
return api.get('/posts/hot', { params })
|
||||
},
|
||||
getLatest(params) {
|
||||
return api.get('/posts/latest', { params })
|
||||
},
|
||||
}
|
||||
|
||||
export const uploadApi = {
|
||||
uploadImage(file) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return api.post('/upload/image', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
},
|
||||
uploadAttachment(file, postId) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
if (postId) formData.append('post_id', postId)
|
||||
return api.post('/upload/attachment', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
},
|
||||
updateAttachmentPost(attachmentId, postId) {
|
||||
return api.put(`/upload/attachment/${attachmentId}/post`, null, { params: { post_id: postId } })
|
||||
},
|
||||
}
|
||||
|
||||
export const adminApi = {
|
||||
getStats() {
|
||||
return api.get('/admin/stats')
|
||||
},
|
||||
getUsers(params) {
|
||||
return api.get('/admin/users', { params })
|
||||
},
|
||||
toggleAdmin(id) {
|
||||
return api.put(`/admin/users/${id}/toggle-admin`)
|
||||
},
|
||||
toggleBan(id) {
|
||||
return api.put(`/admin/users/${id}/toggle-ban`)
|
||||
},
|
||||
approveUser(id) {
|
||||
return api.put(`/admin/users/${id}/approve`)
|
||||
},
|
||||
rejectUser(id) {
|
||||
return api.put(`/admin/users/${id}/reject`)
|
||||
},
|
||||
getPosts(params) {
|
||||
return api.get('/admin/posts', { params })
|
||||
},
|
||||
deletePost(id) {
|
||||
return api.delete(`/admin/posts/${id}`)
|
||||
},
|
||||
// 对象存储管理
|
||||
getStorageConfig() {
|
||||
return api.get('/admin/storage/config')
|
||||
},
|
||||
updateStorageConfig(data) {
|
||||
return api.put('/admin/storage/config', data)
|
||||
},
|
||||
testStorageConnection() {
|
||||
return api.post('/admin/storage/test')
|
||||
},
|
||||
// 分类管理
|
||||
getCategories() {
|
||||
return api.get('/admin/categories')
|
||||
},
|
||||
createCategory(data) {
|
||||
return api.post('/admin/categories', data)
|
||||
},
|
||||
updateCategory(id, data) {
|
||||
return api.put(`/admin/categories/${id}`, data)
|
||||
},
|
||||
deleteCategory(id) {
|
||||
return api.delete(`/admin/categories/${id}`)
|
||||
},
|
||||
}
|
||||
|
||||
// 公开分类API
|
||||
export const categoryApi = {
|
||||
getActiveCategories() {
|
||||
return api.get('/admin/public/categories')
|
||||
},
|
||||
}
|
||||
|
||||
// 开源项目API
|
||||
export const projectsApi = {
|
||||
// 管理员接口
|
||||
adminList(params) {
|
||||
return api.get('/projects/admin/list', { params })
|
||||
},
|
||||
adminCreate(data) {
|
||||
return api.post('/projects/admin', data)
|
||||
},
|
||||
adminUpdate(id, data) {
|
||||
return api.put(`/projects/admin/${id}`, data)
|
||||
},
|
||||
adminDelete(id) {
|
||||
return api.delete(`/projects/admin/${id}`)
|
||||
},
|
||||
githubSearch(params) {
|
||||
return api.get('/projects/admin/github-search', { params })
|
||||
},
|
||||
githubImport(data) {
|
||||
return api.post('/projects/admin/github-import', data)
|
||||
},
|
||||
// 公开接口
|
||||
getHot(params) {
|
||||
return api.get('/projects/hot', { params })
|
||||
},
|
||||
getLatest(params) {
|
||||
return api.get('/projects/latest', { params })
|
||||
},
|
||||
search(params) {
|
||||
return api.get('/projects/search', { params })
|
||||
},
|
||||
getCategories() {
|
||||
return api.get('/projects/categories')
|
||||
},
|
||||
getDetail(id) {
|
||||
return api.get(`/projects/${id}`)
|
||||
},
|
||||
// 公开GitHub搜索(登录用户可用)
|
||||
publicGithubSearch(params) {
|
||||
return api.get('/projects/github-search', { params })
|
||||
},
|
||||
// 收藏
|
||||
toggleCollect(id) {
|
||||
return api.post(`/projects/${id}/collect`)
|
||||
},
|
||||
getMyCollects(params) {
|
||||
return api.get('/projects/my-collects', { params })
|
||||
},
|
||||
}
|
||||
|
||||
// 导航站API
|
||||
export const navApi = {
|
||||
// 管理员接口
|
||||
getCategories() {
|
||||
return api.get('/nav/admin/categories')
|
||||
},
|
||||
createCategory(data) {
|
||||
return api.post('/nav/admin/categories', data)
|
||||
},
|
||||
updateCategory(id, data) {
|
||||
return api.put(`/nav/admin/categories/${id}`, data)
|
||||
},
|
||||
deleteCategory(id) {
|
||||
return api.delete(`/nav/admin/categories/${id}`)
|
||||
},
|
||||
getLinks(params) {
|
||||
return api.get('/nav/admin/links', { params })
|
||||
},
|
||||
createLink(data) {
|
||||
return api.post('/nav/admin/links', data)
|
||||
},
|
||||
updateLink(id, data) {
|
||||
return api.put(`/nav/admin/links/${id}`, data)
|
||||
},
|
||||
deleteLink(id) {
|
||||
return api.delete(`/nav/admin/links/${id}`)
|
||||
},
|
||||
// 公开接口
|
||||
getPublicNav() {
|
||||
return api.get('/nav/public')
|
||||
},
|
||||
getPublicCategories() {
|
||||
return api.get('/nav/public/categories')
|
||||
},
|
||||
// 用户提交
|
||||
submitLink(data) {
|
||||
return api.post('/nav/submit', data)
|
||||
},
|
||||
getMySubmissions() {
|
||||
return api.get('/nav/my-submissions')
|
||||
},
|
||||
// 审核
|
||||
getPendingCount() {
|
||||
return api.get('/nav/admin/pending-count')
|
||||
},
|
||||
reviewLink(id, data) {
|
||||
return api.put(`/nav/admin/links/${id}/review`, data)
|
||||
},
|
||||
}
|
||||
|
||||
// API Hub
|
||||
function hubHeaders() {
|
||||
const t = sessionStorage.getItem('hub_token')
|
||||
return t ? { 'X-Hub-Token': t } : {}
|
||||
}
|
||||
|
||||
export const apiHubApi = {
|
||||
// 密码认证
|
||||
auth(password) { return api.post('/api-hub/auth', { password }) },
|
||||
checkPassword() { return api.get('/api-hub/check-password') },
|
||||
// 管理员设置密码
|
||||
setPassword(password) { return api.put('/api-hub/admin/password', { password }) },
|
||||
getPasswordStatus() { return api.get('/api-hub/admin/password-status') },
|
||||
// 分类
|
||||
getCategories() { return api.get('/api-hub/categories', { headers: hubHeaders() }) },
|
||||
createCategory(data) { return api.post('/api-hub/categories', data, { headers: hubHeaders() }) },
|
||||
updateCategory(id, data) { return api.put(`/api-hub/categories/${id}`, data, { headers: hubHeaders() }) },
|
||||
deleteCategory(id) { return api.delete(`/api-hub/categories/${id}`, { headers: hubHeaders() }) },
|
||||
// API CRUD
|
||||
getApis(params) { return api.get('/api-hub/list', { params, headers: hubHeaders() }) },
|
||||
createApi(data) { return api.post('/api-hub/', data, { headers: hubHeaders() }) },
|
||||
updateApi(id, data) { return api.put(`/api-hub/${id}`, data, { headers: hubHeaders() }) },
|
||||
deleteApi(id) { return api.delete(`/api-hub/${id}`, { headers: hubHeaders() }) },
|
||||
// 测试和健康检查
|
||||
testApi(id, data) { return api.post(`/api-hub/${id}/test`, data, { headers: hubHeaders() }) },
|
||||
healthCheck(id) { return api.post(`/api-hub/${id}/health-check`, {}, { headers: hubHeaders() }) },
|
||||
// 日志和统计
|
||||
getLogs(id, params) { return api.get(`/api-hub/${id}/logs`, { params, headers: hubHeaders() }) },
|
||||
getStats() { return api.get('/api-hub/stats', { headers: hubHeaders() }) },
|
||||
}
|
||||
|
||||
// 团队知识库
|
||||
function kbHeaders() {
|
||||
const t = sessionStorage.getItem('kb_token')
|
||||
return t ? { 'X-Kb-Token': t } : {}
|
||||
}
|
||||
|
||||
export const kbApi = {
|
||||
// 密码认证
|
||||
auth(password) { return api.post('/kb/auth', { password }) },
|
||||
checkPassword() { return api.get('/kb/check-password') },
|
||||
// 公开接口
|
||||
getCategories() { return api.get('/kb/categories', { headers: kbHeaders() }) },
|
||||
getItems(params) { return api.get('/kb/items', { params, headers: kbHeaders() }) },
|
||||
getItem(id) { return api.get(`/kb/items/${id}`, { headers: kbHeaders() }) },
|
||||
getStats() { return api.get('/kb/stats', { headers: kbHeaders() }) },
|
||||
// 管理员接口
|
||||
setPassword(password) { return api.put('/kb/admin/password', { password }) },
|
||||
getPasswordStatus() { return api.get('/kb/admin/password-status') },
|
||||
adminGetCategories() { return api.get('/kb/admin/categories') },
|
||||
adminCreateCategory(data) { return api.post('/kb/admin/categories', data) },
|
||||
adminUpdateCategory(id, data) { return api.put(`/kb/admin/categories/${id}`, data) },
|
||||
adminDeleteCategory(id) { return api.delete(`/kb/admin/categories/${id}`) },
|
||||
adminGetItems(params) { return api.get('/kb/admin/items', { params }) },
|
||||
adminAddItems(data) { return api.post('/kb/admin/items', data) },
|
||||
adminUpdateItem(id, data) { return api.put(`/kb/admin/items/${id}`, data) },
|
||||
adminDeleteItem(id) { return api.delete(`/kb/admin/items/${id}`) },
|
||||
adminGetPostsForPick(params) { return api.get('/kb/admin/posts-for-pick', { params }) },
|
||||
adminGetStats() { return api.get('/kb/admin/stats') },
|
||||
}
|
||||
|
||||
// 联网搜索
|
||||
export const webSearchApi = {
|
||||
getConversations() {
|
||||
return api.get('/web-search/conversations')
|
||||
},
|
||||
getConversation(id) {
|
||||
return api.get(`/web-search/conversations/${id}`)
|
||||
},
|
||||
deleteConversation(id) {
|
||||
return api.delete(`/web-search/conversations/${id}`)
|
||||
},
|
||||
// search 使用 SSE 不走 axios
|
||||
}
|
||||
|
||||
export const aiFormatApi = {
|
||||
formatArticle(data) {
|
||||
return api.post('/ai/format', data, { timeout: 120000 })
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user