ForcePilot/web/src/apis/base.js
Wenjie Zhang 6d7e3ea2ef feat(knowledge): 添加文档基本信息和内容信息的获取接口,支持文件下载功能
- 在知识库路由中新增获取文档基本信息和内容信息的接口
- 实现文档下载功能,支持中文文件名处理
- 更新相关文档和API调用,确保前端能够正确下载文件
2025-09-21 23:48:56 +08:00

227 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useUserStore, checkAdminPermission, checkSuperAdminPermission } from '@/stores/user'
import { message } from 'ant-design-vue'
/**
* 基础API请求封装
* 提供统一的请求方法,自动处理认证头和错误
*/
/**
* 发送API请求的基础函数
* @param {string} url - API端点
* @param {Object} options - 请求选项
* @param {boolean} requiresAuth - 是否需要认证头
* @param {string} responseType - 响应类型: 'json' | 'text' | 'blob'
* @returns {Promise} - 请求结果
*/
export async function apiRequest(url, options = {}, requiresAuth = true, responseType = 'json') {
try {
// 默认请求配置
const requestOptions = {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
}
// 如果需要认证,添加认证头
if (requiresAuth) {
const userStore = useUserStore()
if (!userStore.isLoggedIn) {
throw new Error('用户未登录')
}
Object.assign(requestOptions.headers, userStore.getAuthHeaders())
}
// 发送请求
const response = await fetch(url, requestOptions)
// 处理API返回的错误
if (!response.ok) {
// 尝试解析错误信息
let errorMessage = `请求失败: ${response.status}, ${response.statusText}`
let errorData = null
console.log('API请求失败:', {
url,
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries(response.headers.entries())
});
try {
errorData = await response.json()
errorMessage = errorData.detail || errorData.message || errorMessage
console.log('API错误详情:', errorData);
} catch (e) {
// 如果无法解析JSON使用默认错误信息
console.log('无法解析错误响应JSON:', e);
}
// 特殊处理401和403错误
if (response.status === 401) {
// 如果是认证失败,可能需要重新登录
const userStore = useUserStore()
// 检查是否是token过期
const isTokenExpired = errorData &&
(errorData.detail?.includes('令牌已过期') ||
errorData.detail?.includes('token expired') ||
errorMessage?.includes('令牌已过期') ||
errorMessage?.includes('token expired'))
message.error(isTokenExpired ? '登录已过期,请重新登录' : '认证失败,请重新登录')
// 如果用户当前认为自己已登录,则登出
if (userStore.isLoggedIn) {
userStore.logout()
}
// 使用setTimeout确保消息显示后再跳转
setTimeout(() => {
window.location.href = '/login'
}, 1500)
throw new Error('未授权,请先登录')
} else if (response.status === 403) {
throw new Error('没有权限执行此操作')
} else if (response.status === 500) {
throw new Error('Server 500 Error, please check the log use `docker logs api-dev`')
}
throw new Error(errorMessage)
}
// 根据responseType处理响应
if (responseType === 'blob') {
return response
} else if (responseType === 'json') {
// 检查Content-Type以确定如何处理响应
const contentType = response.headers.get('Content-Type')
if (contentType && contentType.includes('application/json')) {
return await response.json()
}
return await response.text()
} else if (responseType === 'text') {
return await response.text()
} else {
return response
}
} catch (error) {
console.error('API请求错误:', error)
throw error
}
}
/**
* 发送GET请求
* @param {string} url - API端点
* @param {Object} options - 请求选项
* @param {boolean} requiresAuth - 是否需要认证
* @param {string} responseType - 响应类型: 'json' | 'text' | 'blob'
* @returns {Promise} - 请求结果
*/
export function apiGet(url, options = {}, requiresAuth = true, responseType = 'json') {
return apiRequest(url, { method: 'GET', ...options }, requiresAuth, responseType)
}
export function apiAdminGet(url, options = {}, responseType = 'json') {
checkAdminPermission()
return apiGet(url, options, true, responseType)
}
export function apiSuperAdminGet(url, options = {}, responseType = 'json') {
checkSuperAdminPermission()
return apiGet(url, options, true, responseType)
}
/**
* 发送POST请求
* @param {string} url - API端点
* @param {Object} data - 请求体数据
* @param {Object} options - 其他请求选项
* @param {boolean} requiresAuth - 是否需要认证
* @param {string} responseType - 响应类型: 'json' | 'text' | 'blob'
* @returns {Promise} - 请求结果
*/
export function apiPost(url, data = {}, options = {}, requiresAuth = true, responseType = 'json') {
return apiRequest(
url,
{
method: 'POST',
body: JSON.stringify(data),
...options
},
requiresAuth,
responseType
)
}
export function apiAdminPost(url, data = {}, options = {}, responseType = 'json') {
checkAdminPermission()
return apiPost(url, data, options, true, responseType)
}
export function apiSuperAdminPost(url, data = {}, options = {}, responseType = 'json') {
checkSuperAdminPermission()
return apiPost(url, data, options, true, responseType)
}
/**
* 发送PUT请求
* @param {string} url - API端点
* @param {Object} data - 请求体数据
* @param {Object} options - 其他请求选项
* @param {boolean} requiresAuth - 是否需要认证
* @param {string} responseType - 响应类型: 'json' | 'text' | 'blob'
* @returns {Promise} - 请求结果
*/
export function apiPut(url, data = {}, options = {}, requiresAuth = true, responseType = 'json') {
return apiRequest(
url,
{
method: 'PUT',
body: JSON.stringify(data),
...options
},
requiresAuth,
responseType
)
}
export function apiAdminPut(url, data = {}, options = {}, responseType = 'json') {
checkAdminPermission()
return apiPut(url, data, options, true, responseType)
}
export function apiSuperAdminPut(url, data = {}, options = {}, responseType = 'json') {
checkSuperAdminPermission()
return apiPut(url, data, options, true, responseType)
}
/**
* 发送DELETE请求
* @param {string} url - API端点
* @param {Object} options - 请求选项
* @param {boolean} requiresAuth - 是否需要认证
* @param {string} responseType - 响应类型: 'json' | 'text' | 'blob'
* @returns {Promise} - 请求结果
*/
export function apiDelete(url, options = {}, requiresAuth = true, responseType = 'json') {
return apiRequest(url, { method: 'DELETE', ...options }, requiresAuth, responseType)
}
export function apiAdminDelete(url, options = {}) {
checkAdminPermission()
return apiDelete(url, options, true)
}
export function apiSuperAdminDelete(url, options = {}) {
checkSuperAdminPermission()
return apiDelete(url, options, true)
}