diff --git a/package-lock.json b/package-lock.json index 6e4a376..6e7396c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@react-navigation/stack": "^7.4.2", "@rneui/base": "^4.0.0-rc.8", "@rneui/themed": "^4.0.0-rc.8", - "axios": "^1.10.0", + "axios": "^1.11.0", "react": "19.1.0", "react-native": "0.80.1", "react-native-gesture-handler": "^2.27.1", @@ -4419,13 +4419,13 @@ } }, "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "version": "1.11.0", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, diff --git a/package.json b/package.json index 0b06553..3633f51 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@react-navigation/stack": "^7.4.2", "@rneui/base": "^4.0.0-rc.8", "@rneui/themed": "^4.0.0-rc.8", - "axios": "^1.10.0", + "axios": "^1.11.0", "react": "19.1.0", "react-native": "0.80.1", "react-native-gesture-handler": "^2.27.1", diff --git a/src/screens/TaskEditScreen.tsx b/src/screens/TaskEditScreen.tsx index 1bc3bb4..8760296 100644 --- a/src/screens/TaskEditScreen.tsx +++ b/src/screens/TaskEditScreen.tsx @@ -39,6 +39,7 @@ export default function TaskEditScreen() { useEffect(() => { const loadTask = async () => { let taskData = getTaskById(taskId); + debugger; if (taskData && !taskData.detail) { await fetchTaskDetail(taskId); taskData = getTaskById(taskId); diff --git a/src/services/api.ts b/src/services/api.ts new file mode 100644 index 0000000..13318aa --- /dev/null +++ b/src/services/api.ts @@ -0,0 +1,88 @@ +import axios from 'axios'; +import { getConfig, getSettings } from './configService'; + +// 创建 axios 实例 +const api = axios.create({ + timeout: 10000, // 请求超时时间 +}); + +// 请求拦截器 +api.interceptors.request.use( + async config => { + const appConfig = await getConfig(); + const settings = await getSettings(); + const serverUrl = settings.serverUrl || appConfig?.serverUrl; + + if (!serverUrl) { + const error = new Error('服务器地址未配置'); + console.error(error.message); + return Promise.reject(error); + } + + config.baseURL = serverUrl.replace(/\/$/, ''); + // 设置通用请求头 + config.headers = { + 'Content-Type': 'application/json', + ...appConfig?.headers, + ...config.headers, + } as any; + + console.log( + `[Request] ${config.method?.toUpperCase()} ${config.baseURL}${ + config.url + }`, + { params: config.params, data: config.data }, + ); + return config; + }, + error => { + console.error('[Request Error]', error); + return Promise.reject(error); + }, +); + +// 响应拦截器 +api.interceptors.response.use( + response => { + // 统一处理API响应 + if (response.data && response.data.code && response.data.code !== 200) { + throw new Error(`API 错误: ${response.data.message}`); + } + // 优先处理嵌套的 data 字段 + if (response.data && typeof response.data.data !== 'undefined') { + // 如果 data 字段中有 list,则返回 list + if (Array.isArray(response.data.data.list)) { + return response.data.data.list; + } + // 否则返回 data 字段本身 + return response.data.data; + } + // 如果没有嵌套的 data 字段,直接返回整个响应数据 + return response.data; + }, + error => { + if (error.response) { + // 请求已发出,但服务器响应的状态码不在 2xx 范围 + console.error( + `[Response Error] Status: ${error.response.status}`, + error.response.data, + ); + const httpError = new Error( + `HTTP ${error.response.status}: ${ + error.response.statusText || 'Unknown Error' + }`, + ); + return Promise.reject(httpError); + } else if (error.request) { + // 请求已发出,但没有收到响应 + console.error('[Network Error]', error.request); + return Promise.reject(new Error('网络错误,请检查您的连接')); + } else { + // 在设置请求时触发了一个错误 + console.error('[Request Setup Error]', error.message); + return Promise.reject(error); + } + }, +); + +export default api; diff --git a/src/services/taskService.ts b/src/services/taskService.ts index c819307..e0ca21c 100644 --- a/src/services/taskService.ts +++ b/src/services/taskService.ts @@ -1,14 +1,6 @@ -import { getSettings, getConfig } from './configService'; +import { getConfig } from './configService'; import { RunTaskRequest, RunTaskApiResponse, Task } from '../types/task'; - -// 获取通用请求头 -const getHeaders = async () => { - const config = await getConfig(); - return { - 'Content-Type': 'application/json', - ...config?.headers, - }; -}; +import api from './api'; // 获取任务列表 export const getTasks = async (params: { @@ -18,46 +10,12 @@ export const getTasks = async (params: { try { const config = await getConfig(); const endpoint = config?.apiEndpoints?.getTasks; + if (!endpoint) throw new Error('获取任务列表的API端点未配置'); - if (!endpoint) { - throw new Error('获取任务列表的API端点未配置'); - } - - const settings = await getSettings(); - const serverUrl = settings.serverUrl || config?.serverUrl; - - if (!serverUrl) { - throw new Error('服务器地址未配置'); - } - - const urlObj = new URL(`${serverUrl.replace(/\/$/, '')}${endpoint}`); - urlObj.searchParams.append('pageNum', String(params.pageNum)); - urlObj.searchParams.append('pageSize', String(params.pageSize)); - const url = urlObj.toString(); - console.log('获取任务列表:', url); - - const headers = await getHeaders(); - const response = await fetch(url, { headers }); - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - if (result.code !== 200) { - throw new Error(`API 错误: ${result.message}`); - } - - // 兼容两种可能的数据结构: result.data.list or result.data - if (result.data && Array.isArray(result.data.list)) { - return result.data.list; - } - if (Array.isArray(result.data)) { - return result.data; - } - console.warn('任务列表数据格式不正确', result.data); - return []; + const response = await api.get(endpoint, { params }); + return response as unknown as Task[]; } catch (error) { - console.error('获取任务列表失败:', error); + console.error('获取任务列表失败 (service):', error); throw error; } }; @@ -67,34 +25,11 @@ export const getTaskDetail = async (taskId: string): Promise => { try { const config = await getConfig(); let endpoint = config?.apiEndpoints?.getTaskDetail; + if (!endpoint) throw new Error('获取任务详情的API端点未配置'); - if (!endpoint) { - throw new Error('获取任务详情的API端点未配置'); - } endpoint = endpoint.replace('{taskId}', taskId); - - const settings = await getSettings(); - const serverUrl = settings.serverUrl || config?.serverUrl; - - if (!serverUrl) { - throw new Error('服务器地址未配置'); - } - - const url = `${serverUrl.replace(/\/$/, '')}${endpoint}`; - console.log('获取任务详情:', url); - - const headers = await getHeaders(); - const response = await fetch(url, { headers }); - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - if (result.code !== 200) { - throw new Error(`API 错误: ${result.message}`); - } - - return result.data; + const response = await api.get(endpoint); + return response as unknown as Task; } catch (error) { console.error(`获取任务详情失败 (ID: ${taskId}):`, error); throw error; @@ -108,41 +43,10 @@ export const runTask = async ( try { const config = await getConfig(); const endpoint = config?.apiEndpoints?.runTask; + if (!endpoint) throw new Error('运行任务的API端点未配置'); - if (!endpoint) { - throw new Error('运行任务的API端点未配置'); - } - - const settings = await getSettings(); - const serverUrl = settings.serverUrl || config?.serverUrl; - - if (!serverUrl) { - throw new Error('服务器地址未配置'); - } - - const url = `${serverUrl.replace(/\/$/, '')}${endpoint}`; - console.log('运行任务请求:', url, JSON.stringify(taskData, null, 2)); - - const headers = await getHeaders(); - const response = await fetch(url, { - method: 'POST', - headers: headers, - body: JSON.stringify(taskData), - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`HTTP ${response.status}: ${errorText}`); - } - - const result: RunTaskApiResponse = await response.json(); - console.log('运行任务响应:', result); - - if (result.code !== 200) { - throw new Error(`API 错误: ${result.message}`); - } - - return result; + const response = await api.post(endpoint, taskData); + return response as unknown as RunTaskApiResponse; } catch (error) { console.error('运行任务失败:', error); throw error;