306 lines
8.6 KiB
JavaScript
306 lines
8.6 KiB
JavaScript
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
console.log('=== API服务修复工具 ===');
|
||
|
||
// 修复api.js文件
|
||
async function fixApiFile() {
|
||
console.log('开始修复api.js文件...');
|
||
|
||
const apiFilePath = path.join(__dirname, 'src', 'renderer', 'services', 'api.js');
|
||
|
||
try {
|
||
// 读取原始文件内容
|
||
let originalContent = fs.readFileSync(apiFilePath, 'utf8');
|
||
|
||
// 检查并修复函数调用不一致的问题
|
||
if (originalContent.includes('detectApiPort()')) {
|
||
originalContent = originalContent.replace(/detectApiPort\(\)/g, 'findAvailablePort()');
|
||
console.log('✅ 已修复函数调用不一致问题,将detectApiPort()替换为findAvailablePort()');
|
||
}
|
||
|
||
// 创建修复后的文件内容
|
||
const fixedContent = `import axios from 'axios';
|
||
|
||
// 初始API端口
|
||
let currentPort = 3000; // 默认使用3000端口(与服务器配置一致)
|
||
|
||
// 全局调试标志
|
||
const DEBUG = true;
|
||
|
||
// 创建API实例
|
||
function createApiInstance(port) {
|
||
const api = axios.create({
|
||
baseURL: \`http://localhost:\${port}/api\`,
|
||
timeout: 15000,
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
});
|
||
|
||
// 请求拦截器
|
||
api.interceptors.request.use(
|
||
(config) => {
|
||
const token = localStorage.getItem('token');
|
||
if (token) {
|
||
config.headers.Authorization = \`Bearer \${token}\`;
|
||
}
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 发送请求: \${config.url} (端口: \${port})\`);
|
||
}
|
||
return config;
|
||
},
|
||
(error) => {
|
||
if (DEBUG) {
|
||
console.error('[API调试] 请求配置错误:', error);
|
||
}
|
||
return Promise.reject(error);
|
||
}
|
||
);
|
||
|
||
// 响应拦截器
|
||
api.interceptors.response.use(
|
||
(response) => {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 响应成功: \${response.config.url}\`);
|
||
}
|
||
return response.data;
|
||
},
|
||
async (error) => {
|
||
if (DEBUG) {
|
||
console.error('[API调试] 请求错误:', error.message || error);
|
||
}
|
||
|
||
// 如果是网络错误且没有响应,尝试查找可用端口
|
||
if (!error.response) {
|
||
if (DEBUG) {
|
||
console.log('[API调试] 无响应,尝试查找可用端口...');
|
||
}
|
||
|
||
// 立即尝试查找可用端口
|
||
const newPort = await findAvailablePort();
|
||
if (newPort) {
|
||
// 端口已更新,重试请求
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 已切换到新端口: \${newPort},正在重试请求...\`);
|
||
}
|
||
|
||
// 更新baseURL并重试请求
|
||
const config = error.config;
|
||
config.baseURL = \`http://localhost:\${newPort}/api\`;
|
||
return axios(config); // 重试请求
|
||
}
|
||
}
|
||
|
||
// 正常错误处理
|
||
if (error.response) {
|
||
const { status, data } = error.response;
|
||
|
||
if (status === 401) {
|
||
localStorage.removeItem('token');
|
||
localStorage.removeItem('userInfo');
|
||
window.location.href = '/login';
|
||
}
|
||
|
||
return Promise.reject(data.error || '服务器错误');
|
||
}
|
||
|
||
return Promise.reject('网络错误,请检查服务器连接');
|
||
}
|
||
);
|
||
|
||
return api;
|
||
}
|
||
|
||
// 创建API实例
|
||
let apiInstance = createApiInstance(currentPort);
|
||
|
||
// 主动尝试多个端口的函数
|
||
async function findAvailablePort() {
|
||
// 尝试的端口列表(按照优先级排序)
|
||
const portsToTry = [3000, 3001, 3002, 3003];
|
||
|
||
for (const port of portsToTry) {
|
||
try {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 尝试连接端口: \${port}\`);
|
||
}
|
||
// 简化健康检查
|
||
const response = await fetch(\`http://localhost:\${port}/api\`, {
|
||
method: 'GET',
|
||
signal: AbortSignal.timeout(2000)
|
||
});
|
||
|
||
if (response) {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 找到可用端口: \${port}\`);
|
||
}
|
||
currentPort = port;
|
||
apiInstance = createApiInstance(port);
|
||
return port;
|
||
}
|
||
} catch (error) {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 端口 \${port} 不可用:\`, error.message || error);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果都不可用,尝试从Electron获取端口
|
||
if (window.electronAPI && window.electronAPI.getServerPort) {
|
||
try {
|
||
if (DEBUG) {
|
||
console.log('[API调试] 尝试从Electron API获取端口');
|
||
}
|
||
const port = await window.electronAPI.getServerPort();
|
||
if (port) {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 从Electron API获取到端口: \${port}\`);
|
||
}
|
||
currentPort = port;
|
||
apiInstance = createApiInstance(port);
|
||
return port;
|
||
}
|
||
} catch (error) {
|
||
if (DEBUG) {
|
||
console.warn('[API调试] 无法从Electron API获取端口:', error);
|
||
}
|
||
}
|
||
}
|
||
|
||
return null; // 没有找到可用端口
|
||
}
|
||
|
||
// 立即执行端口查找
|
||
findAvailablePort().then(port => {
|
||
if (port) {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 服务器端口确定为: \${port}\`);
|
||
}
|
||
} else {
|
||
if (DEBUG) {
|
||
console.error('[API调试] 未找到可用的服务器端口');
|
||
}
|
||
}
|
||
}).catch(error => {
|
||
if (DEBUG) {
|
||
console.error('[API调试] 端口查找失败:', error);
|
||
}
|
||
});
|
||
|
||
// 添加到window对象,方便调试和手动控制
|
||
window.__apiPort = currentPort;
|
||
window.__findAvailablePort = findAvailablePort;
|
||
|
||
// 添加手动切换端口的方法,方便调试
|
||
window.__switchApiPort = function(port) {
|
||
if (DEBUG) {
|
||
console.log(\`[API调试] 手动切换到端口: \${port}\`);
|
||
}
|
||
currentPort = port;
|
||
apiInstance = createApiInstance(port);
|
||
window.__apiPort = port;
|
||
return port;
|
||
}
|
||
|
||
// 简单的API方法包装器
|
||
const apiMethods = {
|
||
get: async (url, config) => {
|
||
try {
|
||
return await apiInstance.get(url, config);
|
||
} catch (error) {
|
||
// 请求失败时尝试重新检测端口
|
||
console.log('请求失败,尝试重新检测端口');
|
||
await findAvailablePort();
|
||
// 即使端口检测失败,也尝试用新配置的端口重试一次
|
||
return apiInstance.get(url, config);
|
||
}
|
||
},
|
||
post: async (url, data, config) => {
|
||
try {
|
||
return await apiInstance.post(url, data, config);
|
||
} catch (error) {
|
||
console.log('请求失败,尝试重新检测端口');
|
||
await findAvailablePort();
|
||
return apiInstance.post(url, data, config);
|
||
}
|
||
},
|
||
put: async (url, data, config) => {
|
||
try {
|
||
return await apiInstance.put(url, data, config);
|
||
} catch (error) {
|
||
console.log('请求失败,尝试重新检测端口');
|
||
await findAvailablePort();
|
||
return apiInstance.put(url, data, config);
|
||
}
|
||
},
|
||
delete: async (url, config) => {
|
||
try {
|
||
return await apiInstance.delete(url, config);
|
||
} catch (error) {
|
||
console.log('请求失败,尝试重新检测端口');
|
||
await findAvailablePort();
|
||
return apiInstance.delete(url, config);
|
||
}
|
||
},
|
||
getCurrentPort: () => currentPort
|
||
};
|
||
|
||
export const api = apiMethods;
|
||
`;
|
||
|
||
// 备份原始文件
|
||
const backupPath = apiFilePath + '.backup';
|
||
fs.writeFileSync(backupPath, originalContent);
|
||
console.log(`✅ 已备份原始文件到: ${backupPath}`);
|
||
|
||
// 写入修复后的文件
|
||
fs.writeFileSync(apiFilePath, fixedContent);
|
||
console.log('✅ api.js文件修复完成');
|
||
|
||
} catch (error) {
|
||
console.error('❌ 修复api.js文件失败:', error.message);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// 创建一个简化的启动脚本来测试修复
|
||
function createTestStartScript() {
|
||
try {
|
||
const testScriptPath = path.join(__dirname, 'test-fix.js');
|
||
const testScriptContent = `
|
||
console.log('=== 测试API修复结果 ===');
|
||
console.log('\n请运行以下命令启动应用进行测试:');
|
||
console.log('npm start');
|
||
console.log('\n如果仍然有问题,请检查控制台错误信息。');
|
||
console.log('如果需要恢复原始文件,可以运行:');
|
||
console.log('node restore-api.js');
|
||
`;
|
||
fs.writeFileSync(testScriptPath, testScriptContent);
|
||
console.log(`✅ 已创建测试脚本: ${testScriptPath}`);
|
||
} catch (error) {
|
||
console.error('❌ 创建测试脚本失败:', error.message);
|
||
}
|
||
}
|
||
|
||
// 执行修复
|
||
async function runFix() {
|
||
const apiFixed = await fixApiFile();
|
||
|
||
if (apiFixed) {
|
||
createTestStartScript();
|
||
console.log('\n=== 修复完成 ===');
|
||
console.log('修复内容:');
|
||
console.log('1. 确保findAvailablePort函数正确实现和调用');
|
||
console.log('2. 优化了错误处理逻辑');
|
||
console.log('3. 增强了端口检测的稳定性');
|
||
console.log('\n请重新启动应用测试修复效果。');
|
||
} else {
|
||
console.log('\n=== 修复失败 ===');
|
||
console.log('请手动检查api.js文件。');
|
||
}
|
||
}
|
||
|
||
runFix(); |