修改小程序及大屏
This commit is contained in:
@@ -1,133 +0,0 @@
|
||||
# Nginx 404 错误最终修复方案
|
||||
|
||||
## 🔍 问题现状
|
||||
|
||||
根据测试结果:
|
||||
- ✅ 后端服务正常:`http://localhost:5352/api/government/departments` 返回 200
|
||||
- ✅ 登录接口正常:`https://ad.ningmuyun.com/api/government/auth/login` 返回 401
|
||||
- ❌ 正确路径 404:`https://ad.ningmuyun.com/api/government/departments` 返回 404
|
||||
- ❌ 正确路径 404:`https://ad.ningmuyun.com/api/government/data-center` 返回 404
|
||||
- ❌ 正确路径 404:`https://ad.ningmuyun.com/api/government/market-price` 返回 404
|
||||
- ✅ 重复路径正常:`https://ad.ningmuyun.com/api/government/government/departments` 返回 200
|
||||
|
||||
## 📊 问题分析
|
||||
|
||||
### 关键发现
|
||||
1. 登录接口 `/api/government/auth/login` 正常工作
|
||||
2. 其他政府接口 `/api/government/departments` 等返回 404
|
||||
3. 重复路径 `/api/government/government/departments` 却能正常工作
|
||||
|
||||
### 推断
|
||||
这说明 nginx 配置中:
|
||||
- `location ^~ /api/government/auth/` 规则工作正常
|
||||
- `location ^~ /api/government/` 规则没有生效
|
||||
- 重复路径能工作,说明可能有其他规则在处理请求
|
||||
|
||||
## 🔧 当前 Nginx 配置
|
||||
|
||||
```nginx
|
||||
# 政府认证API代理 - 处理登录等认证接口
|
||||
location ^~ /api/government/auth/ {
|
||||
proxy_pass http://localhost:5352/api/auth/;
|
||||
# ... CORS 配置
|
||||
}
|
||||
|
||||
# 政府API代理 - 处理其他政府相关接口
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
# ... CORS 配置
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 可能的原因和解决方案
|
||||
|
||||
### 方案 1:Nginx 配置未重新加载
|
||||
最可能的原因是 nginx 配置修改后没有重新加载。
|
||||
|
||||
**解决步骤:**
|
||||
```bash
|
||||
# 1. 检查 nginx 配置语法
|
||||
sudo nginx -t
|
||||
|
||||
# 2. 重新加载 nginx 配置
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# 3. 如果 reload 不行,尝试重启
|
||||
sudo systemctl restart nginx
|
||||
|
||||
# 4. 检查 nginx 状态
|
||||
sudo systemctl status nginx
|
||||
|
||||
# 5. 查看 nginx 错误日志
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### 方案 2:浏览器缓存问题
|
||||
**解决步骤:**
|
||||
1. 清除浏览器缓存
|
||||
2. 使用无痕模式测试
|
||||
3. 或使用 curl 命令测试(绕过浏览器)
|
||||
|
||||
### 方案 3:Location 规则匹配优先级问题
|
||||
如果还不行,可能需要调整 location 规则的顺序或写法。
|
||||
|
||||
**尝试修改为:**
|
||||
```nginx
|
||||
# 方案 A:使用正则表达式匹配
|
||||
location ~ ^/api/government/(?!auth/) {
|
||||
proxy_pass http://localhost:5352;
|
||||
# ... 其他配置
|
||||
}
|
||||
|
||||
# 方案 B:去掉尾部斜杠
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352;
|
||||
rewrite ^/api/government/(.*)$ /api/government/$1 break;
|
||||
# ... 其他配置
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 验证步骤
|
||||
|
||||
修复后运行以下命令验证:
|
||||
```bash
|
||||
node test-final-fix.js
|
||||
```
|
||||
|
||||
或使用 curl 测试:
|
||||
```bash
|
||||
# 测试部门接口
|
||||
curl -X GET https://ad.ningmuyun.com/api/government/departments
|
||||
|
||||
# 测试数据中心接口
|
||||
curl -X GET https://ad.ningmuyun.com/api/government/data-center
|
||||
|
||||
# 测试市场价格接口
|
||||
curl -X GET "https://ad.ningmuyun.com/api/government/market-price?type=beef"
|
||||
```
|
||||
|
||||
## 🚨 重要提醒
|
||||
|
||||
1. **必须重启 nginx**:修改配置文件后,必须重启或重新加载 nginx 服务
|
||||
2. **清除缓存**:测试时要清除浏览器缓存或使用无痕模式
|
||||
3. **检查日志**:如果问题持续,查看 nginx 错误日志以获取更多信息
|
||||
|
||||
## 📞 下一步行动
|
||||
|
||||
请在服务器上执行以下命令:
|
||||
```bash
|
||||
# 1. 检查配置语法
|
||||
sudo nginx -t
|
||||
|
||||
# 2. 重新加载配置
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# 3. 验证修复效果
|
||||
curl -X GET https://ad.ningmuyun.com/api/government/departments
|
||||
```
|
||||
|
||||
如果执行后问题仍然存在,请提供:
|
||||
1. nginx -t 的输出结果
|
||||
2. nginx error.log 的最新内容
|
||||
3. curl 命令的完整输出
|
||||
|
||||
188
government-backend/ROUTING_MIGRATION_GUIDE.md
Normal file
188
government-backend/ROUTING_MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# 政府端路由设计迁移指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档说明如何将政府端的路由设计从分散的模块化结构迁移到统一的、与银行端一致的设计模式。
|
||||
|
||||
## 设计原则
|
||||
|
||||
### 银行端设计模式(参考)
|
||||
- 所有API统一使用 `/api/` 前缀
|
||||
- 按功能模块分组:`/api/auth`, `/api/dashboard`, `/api/users` 等
|
||||
- nginx配置简单:只需要一个代理规则
|
||||
- 前端API调用统一:`api.模块名.方法名()`
|
||||
|
||||
### 政府端新设计
|
||||
- 统一使用 `/api/` 前缀
|
||||
- 按功能模块分组,整合相关功能
|
||||
- 简化nginx配置
|
||||
- 统一前端API调用方式
|
||||
|
||||
## 路由结构对比
|
||||
|
||||
### 旧设计(分散式)
|
||||
```
|
||||
/api/auth/...
|
||||
/api/supervision/...
|
||||
/api/epidemic/...
|
||||
/api/government/...
|
||||
/api/personnel/...
|
||||
/api/approval/...
|
||||
/api/service/...
|
||||
/api/visualization/...
|
||||
/api/system/...
|
||||
/api/files/...
|
||||
/api/smart-earmark/...
|
||||
/api/smart-host/...
|
||||
/api/slaughter/...
|
||||
/api/harmless/...
|
||||
/api/harmless-place/...
|
||||
/api/epidemic-record/...
|
||||
/api/vaccine/...
|
||||
/api/epidemic-activity/...
|
||||
/api/production-material-certification/...
|
||||
/api/approval-process/...
|
||||
/api/cattle-academy/...
|
||||
/api/device-warning/...
|
||||
```
|
||||
|
||||
### 新设计(整合式)
|
||||
```
|
||||
/api/auth/... # 认证相关
|
||||
/api/dashboard/... # 仪表盘(整合数据览仓、市场行情、统计等)
|
||||
/api/government/... # 政府管理(部门、岗位、人员、养殖户等)
|
||||
/api/personnel/... # 人员管理
|
||||
/api/supervision/... # 监管管理
|
||||
/api/approval/... # 审批管理
|
||||
/api/epidemic/... # 疫情管理
|
||||
/api/slaughter/... # 屠宰管理
|
||||
/api/smart-earmark/... # 智能硬件管理
|
||||
/api/service/... # 服务管理
|
||||
/api/visualization/... # 可视化数据
|
||||
/api/system/... # 系统管理
|
||||
/api/files/... # 文件管理
|
||||
```
|
||||
|
||||
## 主要变更
|
||||
|
||||
### 1. 后端路由整合
|
||||
|
||||
#### 新增 dashboard 模块
|
||||
将以下功能整合到 `/api/dashboard/`:
|
||||
- 数据览仓:`/api/dashboard/data-center`
|
||||
- 市场行情:`/api/dashboard/market-price`
|
||||
- 监管统计:`/api/dashboard/supervision-stats`
|
||||
- 疫情统计:`/api/dashboard/epidemic-stats`
|
||||
- 总体概览:`/api/dashboard/overview`
|
||||
|
||||
#### 整合 government 模块
|
||||
将以下功能整合到 `/api/government/`:
|
||||
- 部门管理:`/api/government/departments`
|
||||
- 岗位管理:`/api/government/positions`
|
||||
- 行政人员:`/api/government/admin-staff`
|
||||
- 养殖户管理:`/api/government/farmers`
|
||||
- 智能项圈:`/api/government/collars`
|
||||
|
||||
### 2. nginx配置简化
|
||||
|
||||
#### 旧配置(复杂)
|
||||
```nginx
|
||||
location ^~ /api/auth/ { ... }
|
||||
location ^~ /api/supervision/ { ... }
|
||||
location ^~ /api/epidemic/ { ... }
|
||||
location ^~ /api/government/ { ... }
|
||||
location ~ ^/api/(personnel|approval|...)/ { ... }
|
||||
```
|
||||
|
||||
#### 新配置(简单)
|
||||
```nginx
|
||||
location ^~ /api/ {
|
||||
proxy_pass http://localhost:5352/api/;
|
||||
# ... CORS配置
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 前端API调用更新
|
||||
|
||||
#### 旧调用方式
|
||||
```javascript
|
||||
// 分散的API调用
|
||||
axios.get('/api/government/data-center')
|
||||
axios.get('/api/government/market-price')
|
||||
axios.get('/api/supervision/stats')
|
||||
axios.get('/api/epidemic/stats')
|
||||
```
|
||||
|
||||
#### 新调用方式
|
||||
```javascript
|
||||
// 统一的API调用
|
||||
api.dashboard.getDataCenter()
|
||||
api.dashboard.getMarketPrice()
|
||||
api.dashboard.getSupervisionStats()
|
||||
api.dashboard.getEpidemicStats()
|
||||
```
|
||||
|
||||
## 迁移步骤
|
||||
|
||||
### 1. 后端迁移
|
||||
1. 创建新的 `app-redesigned.js` 文件
|
||||
2. 创建 `routes/dashboard.js` 模块
|
||||
3. 更新现有路由文件,确保路径正确
|
||||
4. 测试所有API端点
|
||||
|
||||
### 2. nginx配置更新
|
||||
1. 备份现有nginx配置
|
||||
2. 更新为简化的代理规则
|
||||
3. 测试nginx配置:`nginx -t`
|
||||
4. 重载nginx:`nginx -s reload`
|
||||
|
||||
### 3. 前端迁移
|
||||
1. 创建新的 `api-redesigned.js` 文件
|
||||
2. 更新组件中的API调用
|
||||
3. 测试所有功能模块
|
||||
|
||||
### 4. 测试验证
|
||||
1. 运行 `test-redesigned-routing.js` 脚本
|
||||
2. 检查所有API端点是否正常
|
||||
3. 验证前端功能是否正常
|
||||
|
||||
## 优势
|
||||
|
||||
### 1. 维护性
|
||||
- 统一的API设计模式
|
||||
- 简化的nginx配置
|
||||
- 清晰的功能模块划分
|
||||
|
||||
### 2. 一致性
|
||||
- 与银行端保持一致的设计
|
||||
- 统一的错误处理
|
||||
- 标准化的响应格式
|
||||
|
||||
### 3. 扩展性
|
||||
- 易于添加新功能模块
|
||||
- 统一的认证和权限管理
|
||||
- 标准化的API文档
|
||||
|
||||
### 4. 性能
|
||||
- 简化的nginx匹配规则
|
||||
- 减少配置复杂度
|
||||
- 提高请求处理效率
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **向后兼容**:在迁移过程中保持旧API的兼容性
|
||||
2. **测试充分**:确保所有功能模块都经过充分测试
|
||||
3. **文档更新**:及时更新API文档和用户手册
|
||||
4. **监控告警**:设置监控告警,及时发现和解决问题
|
||||
|
||||
## 回滚计划
|
||||
|
||||
如果新设计出现问题,可以:
|
||||
1. 恢复旧的nginx配置
|
||||
2. 使用旧的app.js文件
|
||||
3. 恢复旧的前端API调用
|
||||
4. 分析问题原因并修复
|
||||
|
||||
## 总结
|
||||
|
||||
新的路由设计使政府端与银行端保持一致,提高了系统的可维护性和一致性。通过整合相关功能模块和简化配置,使整个系统更加清晰和易于管理。
|
||||
124
government-backend/app-redesigned.js
Normal file
124
government-backend/app-redesigned.js
Normal file
@@ -0,0 +1,124 @@
|
||||
require('dotenv').config();
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const bodyParser = require('body-parser');
|
||||
const helmet = require('helmet');
|
||||
const morgan = require('morgan');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// 创建Express应用
|
||||
const app = express();
|
||||
|
||||
// 中间件
|
||||
app.use(cors());
|
||||
app.use(helmet());
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
// 日志配置
|
||||
const accessLogStream = fs.createWriteStream(
|
||||
path.join(__dirname, 'logs', 'access.log'),
|
||||
{ flags: 'a' }
|
||||
);
|
||||
app.use(morgan('combined', { stream: accessLogStream }));
|
||||
|
||||
// 数据库连接
|
||||
const sequelize = require('./config/database');
|
||||
|
||||
// 测试数据库连接
|
||||
sequelize.authenticate()
|
||||
.then(() => {
|
||||
console.log('数据库连接成功');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('数据库连接失败:', err);
|
||||
});
|
||||
|
||||
// ==================== 重新设计的路由结构 ====================
|
||||
// 按照银行端的模式,统一使用 /api/ 前缀,按功能模块分组
|
||||
|
||||
// 1. 认证相关
|
||||
app.use('/api/auth', require('./routes/auth'));
|
||||
|
||||
// 2. 仪表盘和统计
|
||||
app.use('/api/dashboard', require('./routes/dashboard'));
|
||||
|
||||
// 3. 政府管理核心功能
|
||||
app.use('/api/government', require('./routes/government'));
|
||||
|
||||
// 4. 人员管理
|
||||
app.use('/api/personnel', require('./routes/personnel'));
|
||||
|
||||
// 5. 监管相关
|
||||
app.use('/api/supervision', require('./routes/supervision'));
|
||||
|
||||
// 6. 审批流程
|
||||
app.use('/api/approval', require('./routes/approval'));
|
||||
app.use('/api/approval-process', require('./routes/approvalProcess'));
|
||||
|
||||
// 7. 疫情管理
|
||||
app.use('/api/epidemic', require('./routes/epidemic'));
|
||||
app.use('/api/epidemic-record', require('./routes/epidemicRecord'));
|
||||
app.use('/api/epidemic-activity', require('./routes/epidemicActivity'));
|
||||
app.use('/api/vaccine', require('./routes/vaccine'));
|
||||
|
||||
// 8. 屠宰管理
|
||||
app.use('/api/slaughter', require('./routes/slaughter'));
|
||||
app.use('/api/harmless', require('./routes/harmless'));
|
||||
app.use('/api/harmless-place', require('./routes/harmlessPlace'));
|
||||
|
||||
// 9. 智能硬件管理
|
||||
app.use('/api/smart-earmark', require('./routes/smartEarmark'));
|
||||
app.use('/api/smart-host', require('./routes/smartHost'));
|
||||
|
||||
// 10. 服务管理
|
||||
app.use('/api/service', require('./routes/service'));
|
||||
|
||||
// 11. 可视化数据
|
||||
app.use('/api/visualization', require('./routes/visualization'));
|
||||
|
||||
// 12. 系统管理
|
||||
app.use('/api/system', require('./routes/system'));
|
||||
|
||||
// 13. 文件管理
|
||||
app.use('/api/files', require('./routes/files'));
|
||||
|
||||
// 14. 其他功能
|
||||
app.use('/api/production-material-certification', require('./routes/productionMaterialCertification'));
|
||||
app.use('/api/cattle-academy', require('./routes/cattleAcademy'));
|
||||
app.use('/api/device-warning', require('./routes/deviceWarning'));
|
||||
|
||||
// 健康检查
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date() });
|
||||
});
|
||||
|
||||
// 根路径
|
||||
app.get('/', (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
message: '政府管理系统API服务',
|
||||
version: '1.0.0',
|
||||
health: '/health'
|
||||
});
|
||||
});
|
||||
|
||||
// 错误处理
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err.stack);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: 'Internal Server Error',
|
||||
error: process.env.NODE_ENV === 'development' ? err.message : undefined
|
||||
});
|
||||
});
|
||||
|
||||
// 启动服务器
|
||||
const PORT = process.env.PORT || 5352;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
app.listen(PORT, HOST, () => {
|
||||
console.log(`政府管理系统后端服务已启动,地址: ${HOST}:${PORT}`);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
@@ -1,77 +0,0 @@
|
||||
// 清除模块缓存
|
||||
function clearModuleCache() {
|
||||
const modulesToClear = Object.keys(require.cache).filter(key =>
|
||||
key.includes('HarmlessPlace') || key.includes('database') || key.includes('controller')
|
||||
);
|
||||
|
||||
console.log('清除以下模块的缓存:', modulesToClear.length, '个模块');
|
||||
modulesToClear.forEach(key => {
|
||||
console.log('-', key);
|
||||
delete require.cache[key];
|
||||
});
|
||||
}
|
||||
|
||||
// 清除缓存后再导入
|
||||
clearModuleCache();
|
||||
|
||||
// 直接导入HarmlessPlace模型和控制器
|
||||
const HarmlessPlace = require('./models/HarmlessPlace');
|
||||
const harmlessPlaceController = require('./controllers/HarmlessPlaceController');
|
||||
|
||||
// 检查直接导入的HarmlessPlace模型
|
||||
console.log('=== 直接导入的HarmlessPlace模型 ===');
|
||||
console.log('类型:', typeof HarmlessPlace);
|
||||
console.log('是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
if (HarmlessPlace.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
|
||||
}
|
||||
|
||||
// 检查控制器中的getList函数
|
||||
console.log('\n=== 检查控制器的getList函数 ===');
|
||||
console.log('getList的类型:', typeof harmlessPlaceController.getList);
|
||||
|
||||
// 分析控制器中如何使用HarmlessPlace模型
|
||||
// 我们需要查看控制器的源代码
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('\n=== 查看控制器的源代码 ===');
|
||||
const controllerPath = path.join(__dirname, 'controllers', 'HarmlessPlaceController.js');
|
||||
const controllerContent = fs.readFileSync(controllerPath, 'utf8');
|
||||
|
||||
// 查找导入语句
|
||||
const importStatementMatch = controllerContent.match(/require\(['"]\.\.?\/models\/[^'"]+['"]\)/g);
|
||||
console.log('控制器中的导入语句:', importStatementMatch || '未找到');
|
||||
|
||||
// 查找HarmlessPlace的使用
|
||||
const harmlessPlaceUsage = controllerContent.match(/HarmlessPlace\.\w+/g);
|
||||
console.log('控制器中HarmlessPlace的使用:', harmlessPlaceUsage || '未找到');
|
||||
|
||||
console.log('\n=== 检查控制器中实际使用的HarmlessPlace ===');
|
||||
// 创建一个模拟的req和res对象
|
||||
const mockReq = {
|
||||
query: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
};
|
||||
|
||||
const mockRes = {
|
||||
json: function(data) {
|
||||
console.log('res.json被调用:', data);
|
||||
},
|
||||
status: function(code) {
|
||||
console.log('res.status被调用:', code);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// 尝试从控制器中获取实际使用的HarmlessPlace模型
|
||||
// 我们需要查看控制器的导入方式
|
||||
const controllerModule = require('./controllers/HarmlessPlaceController');
|
||||
|
||||
// 如果控制器导出了其使用的模型,我们可以检查
|
||||
// 但通常控制器不会导出这种依赖
|
||||
console.log('控制器模块导出:', Object.keys(controllerModule));
|
||||
|
||||
console.log('\n所有检查完成!');
|
||||
77
government-backend/check-nginx-syntax.js
Normal file
77
government-backend/check-nginx-syntax.js
Normal file
@@ -0,0 +1,77 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 检查nginx配置语法
|
||||
const nginxConfigPath = path.join(__dirname, 'nginx.conf');
|
||||
const nginxConfig = fs.readFileSync(nginxConfigPath, 'utf8');
|
||||
|
||||
console.log('检查nginx配置语法...');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// 检查server块
|
||||
const serverBlocks = nginxConfig.match(/server\s*{/g) || [];
|
||||
console.log(`发现 ${serverBlocks.length} 个server块`);
|
||||
|
||||
// 检查location块
|
||||
const locationBlocks = nginxConfig.match(/location\s+[^{]+{/g) || [];
|
||||
console.log(`发现 ${locationBlocks.length} 个location块`);
|
||||
|
||||
// 检查API相关的location块
|
||||
const apiLocationBlocks = locationBlocks.filter(block =>
|
||||
block.includes('/api') || block.includes('proxy_pass')
|
||||
);
|
||||
|
||||
console.log(`\nAPI相关的location块:`);
|
||||
apiLocationBlocks.forEach((block, index) => {
|
||||
console.log(`${index + 1}. ${block.trim()}`);
|
||||
});
|
||||
|
||||
// 检查是否有重复的location路径
|
||||
const locationPaths = locationBlocks.map(block => {
|
||||
const pathMatch = block.match(/location\s+([^{]+)/);
|
||||
return pathMatch ? pathMatch[1].trim() : '';
|
||||
});
|
||||
|
||||
const duplicatePaths = locationPaths.filter((path, index) =>
|
||||
locationPaths.indexOf(path) !== index && path !== ''
|
||||
);
|
||||
|
||||
if (duplicatePaths.length > 0) {
|
||||
console.log('\n❌ 发现重复的location路径:');
|
||||
duplicatePaths.forEach(path => {
|
||||
console.log(` - ${path}`);
|
||||
});
|
||||
} else {
|
||||
console.log('\n✅ 没有重复的location路径');
|
||||
}
|
||||
|
||||
// 检查proxy_pass配置
|
||||
const proxyPassBlocks = nginxConfig.match(/proxy_pass\s+[^;]+;/g) || [];
|
||||
console.log(`\nproxy_pass配置:`);
|
||||
proxyPassBlocks.forEach((block, index) => {
|
||||
console.log(`${index + 1}. ${block.trim()}`);
|
||||
});
|
||||
|
||||
// 检查是否有路径重复的proxy_pass
|
||||
const problematicProxyPass = proxyPassBlocks.filter(block => {
|
||||
const url = block.match(/proxy_pass\s+([^;]+);/);
|
||||
if (url) {
|
||||
const proxyUrl = url[1].trim();
|
||||
// 检查是否以/api/结尾
|
||||
return proxyUrl.endsWith('/api/');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (problematicProxyPass.length > 0) {
|
||||
console.log('\n⚠️ 发现可能有问题的proxy_pass配置:');
|
||||
problematicProxyPass.forEach(block => {
|
||||
console.log(` - ${block.trim()}`);
|
||||
});
|
||||
console.log(' 这些配置可能导致路径重复问题');
|
||||
} else {
|
||||
console.log('\n✅ proxy_pass配置看起来正常');
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(50));
|
||||
console.log('nginx配置检查完成');
|
||||
@@ -1,106 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 调试nginx问题
|
||||
async function debugNginxIssue() {
|
||||
console.log('🔍 调试nginx问题...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '直接测试后端服务',
|
||||
url: 'http://localhost:5352/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试部门接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误'
|
||||
},
|
||||
{
|
||||
name: '测试重复路径接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/departments',
|
||||
expected: '应该返回200(如果nginx配置有问题)'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置问题,路径映射不正确`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 调试完成!');
|
||||
console.log('');
|
||||
console.log('📝 可能的问题:');
|
||||
console.log(' 1. nginx配置语法错误');
|
||||
console.log(' 2. nginx服务未重启');
|
||||
console.log(' 3. location规则冲突');
|
||||
console.log(' 4. proxy_pass配置错误');
|
||||
console.log('');
|
||||
console.log('🔄 建议的解决步骤:');
|
||||
console.log(' 1. 检查nginx配置语法: sudo nginx -t');
|
||||
console.log(' 2. 重启nginx服务: sudo systemctl reload nginx');
|
||||
console.log(' 3. 检查nginx错误日志: sudo tail -f /var/log/nginx/error.log');
|
||||
console.log(' 4. 检查nginx访问日志: sudo tail -f /var/log/nginx/ad.ningmuyun.com.access.log');
|
||||
}
|
||||
|
||||
// 运行调试
|
||||
debugNginxIssue().catch(console.error);
|
||||
@@ -73,3 +73,4 @@ async function diagnoseURLIssue() {
|
||||
|
||||
// 运行诊断
|
||||
diagnoseURLIssue().catch(console.error);
|
||||
|
||||
|
||||
@@ -171,3 +171,4 @@ async function finalNginxTest() {
|
||||
|
||||
// 运行测试
|
||||
finalNginxTest().catch(console.error);
|
||||
|
||||
|
||||
@@ -61,3 +61,4 @@ sudo tail -f /var/log/nginx/ad.ningmuyun.com.access.log
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/departments` (部门列表)
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/data-center` (数据中心)
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/market-price` (市场价格)
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
# Nginx配置测试说明
|
||||
|
||||
## 问题描述
|
||||
- 登录接口:`/api/government/auth/login` ✅ 正常
|
||||
- 其他接口:`/api/government/departments` ❌ 报错
|
||||
- 错误URL:`/api/government/government/departments` (路径重复)
|
||||
|
||||
## 当前nginx配置分析
|
||||
|
||||
### Server块1: ad.ningmuyun.com (HTTPS 443)
|
||||
```nginx
|
||||
# 静态文件服务
|
||||
location ^~ /government/ {
|
||||
alias /data/vue/ningmuyun/government/dist/;
|
||||
# 处理前端静态文件
|
||||
}
|
||||
|
||||
# 认证API代理 (优先级最高)
|
||||
location ^~ /api/government/auth/ {
|
||||
proxy_pass http://localhost:5352/api/auth/;
|
||||
# 处理登录等认证接口
|
||||
}
|
||||
|
||||
# 其他API代理 (优先级较低)
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
# 处理其他政府API接口
|
||||
}
|
||||
```
|
||||
|
||||
## 路径映射测试
|
||||
|
||||
| 请求路径 | 匹配规则 | 代理目标 | 预期结果 |
|
||||
|---------|---------|---------|---------|
|
||||
| `/api/government/auth/login` | `^~ /api/government/auth/` | `/api/auth/login` | ✅ 正常 |
|
||||
| `/api/government/departments` | `^~ /api/government/` | `/api/government/departments` | ✅ 应该正常 |
|
||||
| `/api/government/government/departments` | 无匹配 | 404 | ❌ 不应该出现 |
|
||||
|
||||
## 可能的问题原因
|
||||
|
||||
1. **前端请求路径错误**:前端可能错误地构造了重复路径
|
||||
2. **nginx重写规则**:可能有隐藏的rewrite规则导致路径重复
|
||||
3. **代理配置问题**:proxy_pass的路径处理可能有问题
|
||||
|
||||
## 测试步骤
|
||||
|
||||
1. 运行诊断脚本:
|
||||
```bash
|
||||
node diagnose-url-issue.js
|
||||
```
|
||||
|
||||
2. 检查nginx错误日志:
|
||||
```bash
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
3. 检查nginx访问日志:
|
||||
```bash
|
||||
sudo tail -f /var/log/nginx/ad.ningmuyun.com.access.log
|
||||
```
|
||||
|
||||
## 修复建议
|
||||
|
||||
如果确认是nginx配置问题,可能需要:
|
||||
|
||||
1. 调整location规则的顺序
|
||||
2. 添加更具体的路径匹配规则
|
||||
3. 检查是否有隐藏的rewrite规则
|
||||
4. 验证proxy_pass的路径处理
|
||||
|
||||
## 验证方法
|
||||
|
||||
修复后,以下URL应该正常工作:
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/auth/login`
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/departments`
|
||||
- ✅ `https://ad.ningmuyun.com/api/government/market-price`
|
||||
- ❌ `https://ad.ningmuyun.com/api/government/government/departments` (不应该存在)
|
||||
@@ -1,113 +0,0 @@
|
||||
# 政府端API 404错误问题分析报告
|
||||
|
||||
## 问题描述
|
||||
- **错误URL**: `https://ad.ningmuyun.com/api/government/market-price?type=beef`
|
||||
- **错误状态**: 404 Not Found
|
||||
- **影响范围**: 政府端管理系统市场价格功能
|
||||
|
||||
## 问题根因分析
|
||||
|
||||
### 1. 后端代码检查 ✅
|
||||
- **路由配置**: `government-backend/routes/government.js` 第11行
|
||||
```javascript
|
||||
router.get('/market-price', governmentController.getMarketPrice);
|
||||
```
|
||||
- **控制器方法**: `governmentController.getMarketPrice` 已正确实现
|
||||
- **应用路由注册**: `app.js` 第50行已正确注册
|
||||
```javascript
|
||||
app.use('/api/government', require('./routes/government'));
|
||||
```
|
||||
|
||||
### 2. 前端代码检查 ✅
|
||||
- **API调用**: `government-admin/src/views/MarketPrice.vue` 第94行
|
||||
```javascript
|
||||
const response = await axios.get('/api/government/market-price', {
|
||||
params: { type }
|
||||
})
|
||||
```
|
||||
- **代理配置**: `vite.config.js` 开发环境代理配置正确
|
||||
|
||||
### 3. Nginx配置问题 ❌
|
||||
**问题所在**: nginx配置中政府API的路径匹配错误
|
||||
|
||||
**原始错误配置**:
|
||||
```nginx
|
||||
location ^~ /government/api/ {
|
||||
proxy_pass http://localhost:5352/;
|
||||
}
|
||||
```
|
||||
|
||||
**问题分析**:
|
||||
- 前端请求路径: `/api/government/market-price`
|
||||
- nginx匹配路径: `/government/api/`
|
||||
- 路径不匹配导致404错误
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 修复nginx配置
|
||||
将政府API代理路径从 `/government/api/` 修改为 `/api/government/`:
|
||||
|
||||
```nginx
|
||||
# 政府API代理 - 修复路径匹配问题
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# CORS配置
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With';
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Content-Type' 'text/plain; charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 部署步骤
|
||||
|
||||
1. **备份当前nginx配置**:
|
||||
```bash
|
||||
sudo cp /etc/nginx/conf.d/ningmuyun_one.conf /etc/nginx/conf.d/ningmuyun_one.conf.backup
|
||||
```
|
||||
|
||||
2. **应用修复配置**:
|
||||
```bash
|
||||
sudo cp nginx-fix-government-api.conf /etc/nginx/conf.d/
|
||||
# 或者手动编辑配置文件,将上述配置添加到 ad.ningmuyun.com server 块中
|
||||
```
|
||||
|
||||
3. **测试nginx配置**:
|
||||
```bash
|
||||
sudo nginx -t
|
||||
```
|
||||
|
||||
4. **重新加载nginx**:
|
||||
```bash
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
5. **验证修复**:
|
||||
```bash
|
||||
curl -k https://ad.ningmuyun.com/api/government/market-price?type=beef
|
||||
```
|
||||
|
||||
## 预期结果
|
||||
修复后,`https://ad.ningmuyun.com/api/government/market-price?type=beef` 应该返回正确的市场价格数据,而不是404错误。
|
||||
|
||||
## 相关文件
|
||||
- `government-backend/_etc_nginx_conf.d_ningmuyun_one.conf` - 主nginx配置文件
|
||||
- `government-backend/nginx-fix-government-api.conf` - 修复配置片段
|
||||
- `government-backend/routes/government.js` - 后端路由
|
||||
- `government-backend/controllers/governmentController.js` - 控制器实现
|
||||
- `government-admin/src/views/MarketPrice.vue` - 前端页面
|
||||
@@ -93,8 +93,8 @@ server {
|
||||
access_log /var/log/nginx/wapi.ningmuyun.com.access.log;
|
||||
error_log /var/log/nginx/wapi.ningmuyun.com.error.log;
|
||||
|
||||
# API反向代理
|
||||
location /api/ {
|
||||
# 养殖端API反向代理 - 使用更具体的路径匹配
|
||||
location ^~ /farm-api/ {
|
||||
proxy_pass http://localhost:5350/api/;
|
||||
limit_except GET POST OPTIONS { # 确保包含 POST
|
||||
deny all;
|
||||
@@ -340,9 +340,29 @@ server {
|
||||
}
|
||||
}
|
||||
|
||||
# 政府认证API代理 - 处理登录等认证接口(优先级最高)
|
||||
location ^~ /api/government/auth/ {
|
||||
proxy_pass http://localhost:5352/api/auth/; # 政府后端认证服务端口
|
||||
# ==================== 政府项目 (zhengfu) ====================
|
||||
location ^~ /government/ {
|
||||
alias /data/vue/ningmuyun/government/dist/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /zhengfu/index.html;
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location ~* \.html$ {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
expires 0;
|
||||
}
|
||||
}
|
||||
|
||||
# ==================== 政府项目API代理 ====================
|
||||
# 政府端API统一代理 - 参考银行端设计模式
|
||||
location ^~ /api/ {
|
||||
proxy_pass http://localhost:5352/api/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
@@ -365,54 +385,6 @@ server {
|
||||
}
|
||||
}
|
||||
|
||||
# 政府API代理 - 处理其他政府相关接口(优先级第二)
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# CORS配置(同上)
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With';
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Content-Type' 'text/plain; charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# ==================== 政府项目 (zhengfu) ====================
|
||||
location ^~ /government/ {
|
||||
alias /data/vue/ningmuyun/government/dist/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /zhengfu/index.html;
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location ~* \.html$ {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
expires 0;
|
||||
}
|
||||
}
|
||||
|
||||
# location ^~ /government/api/ {
|
||||
# proxy_pass http://localhost:5352/; # 政府后端服务端口
|
||||
# }
|
||||
|
||||
# ==================== 养殖项目 (yangzhi) ====================
|
||||
location ^~ /farm/ {
|
||||
alias /data/vue/ningmuyun/farm/dist/;
|
||||
@@ -789,4 +761,3 @@ server {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
78
government-backend/routes/dashboard.js
Normal file
78
government-backend/routes/dashboard.js
Normal file
@@ -0,0 +1,78 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const governmentController = require('../controllers/governmentController');
|
||||
|
||||
// 数据览仓接口 - 整合到dashboard模块
|
||||
router.get('/data-center', governmentController.getDataCenterStats);
|
||||
|
||||
// 市场行情接口 - 整合到dashboard模块
|
||||
router.get('/market-price', governmentController.getMarketPrice);
|
||||
|
||||
// 监管统计接口
|
||||
router.get('/supervision-stats', async (req, res) => {
|
||||
try {
|
||||
// 这里可以调用监管相关的统计方法
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
totalSupervisions: 0,
|
||||
pendingSupervisions: 0,
|
||||
completedSupervisions: 0
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取监管统计失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 疫情统计接口
|
||||
router.get('/epidemic-stats', async (req, res) => {
|
||||
try {
|
||||
// 这里可以调用疫情相关的统计方法
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
totalEpidemics: 0,
|
||||
activeEpidemics: 0,
|
||||
resolvedEpidemics: 0
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取疫情统计失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 总体仪表盘数据
|
||||
router.get('/overview', async (req, res) => {
|
||||
try {
|
||||
// 整合所有统计数据
|
||||
const data = {
|
||||
farmers: { total: 0, active: 0 },
|
||||
animals: { total: 0, healthy: 0 },
|
||||
transactions: { total: 0, amount: 0 },
|
||||
supervisions: { total: 0, pending: 0 },
|
||||
epidemics: { total: 0, active: 0 }
|
||||
};
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: '获取仪表盘数据失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,116 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试重启后的API接口
|
||||
async function testAfterRestart() {
|
||||
console.log('🔍 测试nginx重启后的API接口...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '登录接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误(接口正常)'
|
||||
},
|
||||
{
|
||||
name: '部门列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回200或401'
|
||||
},
|
||||
{
|
||||
name: '数据中心接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回200或401'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回200或401'
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回200或401'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method,
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置可能还有问题`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 当前nginx配置:');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/positions → http://localhost:5352/api/government/positions');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testAfterRestart().catch(console.error);
|
||||
62
government-backend/test-backend-service.js
Normal file
62
government-backend/test-backend-service.js
Normal file
@@ -0,0 +1,62 @@
|
||||
const axios = require('axios');
|
||||
|
||||
async function testBackendService() {
|
||||
console.log('测试政府后端服务...');
|
||||
|
||||
const baseURL = 'http://localhost:5352';
|
||||
|
||||
const testAPIs = [
|
||||
{
|
||||
name: '健康检查',
|
||||
url: '/health',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '根路径',
|
||||
url: '/',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '养殖类型接口',
|
||||
url: '/api/government/farm-types',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '养殖种类接口',
|
||||
url: '/api/government/animal-types',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '数据览仓接口',
|
||||
url: '/api/government/data-center',
|
||||
method: 'GET'
|
||||
}
|
||||
];
|
||||
|
||||
for (const api of testAPIs) {
|
||||
try {
|
||||
console.log(`\n测试 ${api.name}...`);
|
||||
console.log(`URL: ${baseURL}${api.url}`);
|
||||
|
||||
const response = await axios({
|
||||
method: api.method,
|
||||
url: `${baseURL}${api.url}`,
|
||||
timeout: 5000
|
||||
});
|
||||
|
||||
console.log(`✅ 状态码: ${response.status}`);
|
||||
console.log(`✅ 响应: ${JSON.stringify(response.data).substring(0, 100)}...`);
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ 错误: ${error.message}`);
|
||||
if (error.response) {
|
||||
console.log(`❌ 状态码: ${error.response.status}`);
|
||||
console.log(`❌ 响应: ${JSON.stringify(error.response.data)}`);
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
console.log(`❌ 连接被拒绝 - 服务可能没有启动`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testBackendService().catch(console.error);
|
||||
@@ -1,50 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
const API_BASE_URL = 'http://localhost:5352/api/government';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: API_BASE_URL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer test-token'
|
||||
}
|
||||
});
|
||||
|
||||
async function testDataCenterAPI() {
|
||||
console.log('开始测试数据中心API...\n');
|
||||
|
||||
try {
|
||||
// 测试获取数据中心统计数据
|
||||
console.log('1. 测试获取数据中心统计数据...');
|
||||
const response = await api.get('/data-center');
|
||||
console.log('数据中心统计:', JSON.stringify(response.data, null, 2));
|
||||
console.log('✅ 获取数据中心统计数据成功\n');
|
||||
|
||||
// 测试获取市场价格信息
|
||||
console.log('2. 测试获取市场价格信息...');
|
||||
const priceResponse = await api.get('/market-price?type=beef');
|
||||
console.log('市场价格信息:', JSON.stringify(priceResponse.data, null, 2));
|
||||
console.log('✅ 获取市场价格信息成功\n');
|
||||
|
||||
// 测试获取部门列表
|
||||
console.log('3. 测试获取部门列表...');
|
||||
const deptResponse = await api.get('/departments');
|
||||
console.log('部门列表:', JSON.stringify(deptResponse.data, null, 2));
|
||||
console.log('✅ 获取部门列表成功\n');
|
||||
|
||||
// 测试获取行政人员列表
|
||||
console.log('4. 测试获取行政人员列表...');
|
||||
const staffResponse = await api.get('/admin-staff');
|
||||
console.log('行政人员列表:', JSON.stringify(staffResponse.data, null, 2));
|
||||
console.log('✅ 获取行政人员列表成功\n');
|
||||
|
||||
console.log('🎉 所有数据中心API测试通过!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ API测试失败:', error.response ? error.response.data : error.message);
|
||||
}
|
||||
}
|
||||
|
||||
testDataCenterAPI();
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试最终修复效果
|
||||
async function testFinalFix() {
|
||||
console.log('🔍 测试最终修复效果...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200状态码和部门数据'
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
expected: '应该返回200状态码和统计数据'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
expected: '应该返回200状态码和价格数据'
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
expected: '应该返回200状态码和岗位数据'
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
expected: '应该返回200状态码和养殖户数据'
|
||||
},
|
||||
{
|
||||
name: '养殖类型接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farm-types',
|
||||
expected: '应该返回200状态码和养殖类型数据'
|
||||
},
|
||||
{
|
||||
name: '登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误(接口正常)'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置可能还有问题`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 最终nginx配置:');
|
||||
console.log(' location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/data-center → http://localhost:5352/api/government/data-center');
|
||||
console.log(' /api/government/market-price → http://localhost:5352/api/government/market-price');
|
||||
console.log('');
|
||||
console.log('🔄 现在需要重启nginx使配置生效:');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testFinalFix().catch(console.error);
|
||||
@@ -1,94 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试修复后的API接口
|
||||
async function testFixedAPIs() {
|
||||
console.log('🔍 测试修复后的政府端API接口...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200状态码和部门数据'
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
expected: '应该返回200状态码和统计数据'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
expected: '应该返回200状态码和价格数据'
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
expected: '应该返回200状态码和岗位数据'
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
expected: '应该返回200状态码和养殖户数据'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const response = await axios.get(test.url, {
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
});
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置可能还有问题`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 问题: location规则缺少注释符号,导致被注释掉');
|
||||
console.log(' 修复: 添加了正确的注释和location规则');
|
||||
console.log('');
|
||||
console.log('🔄 现在需要重启nginx使配置生效:');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testFixedAPIs().catch(console.error);
|
||||
@@ -1,97 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试政府端各种API接口
|
||||
async function testGovernmentAPIs() {
|
||||
console.log('🔍 测试政府端API接口...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '登录接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回登录成功或认证错误'
|
||||
},
|
||||
{
|
||||
name: '部门列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回部门列表或认证错误'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回市场价格数据或认证错误'
|
||||
},
|
||||
{
|
||||
name: '数据中心接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
method: 'GET',
|
||||
data: null,
|
||||
expected: '应该返回数据中心数据或认证错误'
|
||||
}
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
console.log(`📋 ${testCase.name}`);
|
||||
console.log(` URL: ${testCase.url}`);
|
||||
console.log(` 方法: ${testCase.method}`);
|
||||
console.log(` 预期: ${testCase.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: testCase.method,
|
||||
url: testCase.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
};
|
||||
|
||||
if (testCase.data) {
|
||||
config.data = testCase.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
console.log(` ✅ 响应数据: ${JSON.stringify(response.data, null, 2).substring(0, 200)}...`);
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误信息: ${JSON.stringify(error.response.data, null, 2)}`);
|
||||
|
||||
// 分析错误类型
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: 404错误,可能是路径映射问题`);
|
||||
} else if (error.response.status === 401) {
|
||||
console.log(` 🔍 分析: 401错误,需要认证,这是正常的`);
|
||||
} else if (error.response.status === 500) {
|
||||
console.log(` 🔍 分析: 500错误,服务器内部错误`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 分析说明:');
|
||||
console.log(' - 如果所有接口都返回404,说明nginx配置有问题');
|
||||
console.log(' - 如果只有登录接口正常,其他返回404,说明路径映射有问题');
|
||||
console.log(' - 如果返回401认证错误,说明接口正常但需要登录');
|
||||
console.log(' - 如果返回500错误,说明后端服务有问题');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testGovernmentAPIs().catch(console.error);
|
||||
@@ -1,160 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试location规则顺序修复效果
|
||||
async function testLocationOrderFix() {
|
||||
console.log('🔍 测试location规则顺序修复效果...\n');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 调整了location规则的顺序,让API规则优先于静态文件规则');
|
||||
console.log(' 1. location ^~ /api/government/auth/ (最高优先级)');
|
||||
console.log(' 2. location ^~ /api/government/ (第二优先级)');
|
||||
console.log(' 3. location ^~ /government/ (静态文件,最低优先级)');
|
||||
console.log('');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
shouldWork: true,
|
||||
expectedStatus: 401
|
||||
}
|
||||
];
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500;
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` 状态码: ${response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
if (test.expectedStatus) {
|
||||
if (response.status === test.expectedStatus) {
|
||||
console.log(` ✅ 成功: 返回预期状态码 ${test.expectedStatus}`);
|
||||
successCount++;
|
||||
} else {
|
||||
console.log(` ❌ 失败: 预期状态码 ${test.expectedStatus},实际 ${response.status}`);
|
||||
failCount++;
|
||||
}
|
||||
} else if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
successCount++;
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 失败: 接口返回 404`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` 状态码: ${error.response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
console.log(` ❌ 失败: ${error.response.statusText}`);
|
||||
failCount++;
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log(` ✅ 成功: ${successCount} 个`);
|
||||
console.log(` ❌ 失败: ${failCount} 个`);
|
||||
console.log('');
|
||||
|
||||
if (failCount === 0) {
|
||||
console.log('🎉 所有测试通过!Location规则顺序修复成功!');
|
||||
} else {
|
||||
console.log('⚠️ 还有测试失败,请检查:');
|
||||
console.log(' 1. Nginx配置是否正确修改');
|
||||
console.log(' 2. Nginx服务是否已重启');
|
||||
console.log(' 3. 后端服务是否正常运行');
|
||||
console.log('');
|
||||
console.log('🔄 重启Nginx:');
|
||||
console.log(' sudo nginx -t');
|
||||
console.log(' sudo systemctl reload nginx');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('📝 修复后的nginx配置顺序:');
|
||||
console.log(' 1. location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' 2. location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log(' 3. location ^~ /government/ {');
|
||||
console.log(' alias /data/vue/ningmuyun/government/dist/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/data-center → http://localhost:5352/api/government/data-center');
|
||||
console.log(' /api/government/market-price → http://localhost:5352/api/government/market-price');
|
||||
console.log('');
|
||||
console.log('🚨 重要提醒:');
|
||||
console.log(' 修改nginx配置后,必须重启nginx服务才能生效!');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testLocationOrderFix().catch(console.error);
|
||||
@@ -1,66 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试登录接口
|
||||
async function testLoginAPI() {
|
||||
console.log('🔍 测试政府端登录接口...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '本地后端直接测试',
|
||||
url: 'http://localhost:5352/api/auth/login',
|
||||
description: '直接访问后端服务'
|
||||
},
|
||||
{
|
||||
name: '生产环境nginx代理测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
description: '通过nginx代理访问'
|
||||
}
|
||||
];
|
||||
|
||||
const testData = {
|
||||
username: 'admin',
|
||||
password: 'admin123'
|
||||
};
|
||||
|
||||
for (const testCase of testCases) {
|
||||
console.log(`📋 ${testCase.name}`);
|
||||
console.log(` 描述: ${testCase.description}`);
|
||||
console.log(` URL: ${testCase.url}`);
|
||||
console.log(` 数据: ${JSON.stringify(testData)}`);
|
||||
|
||||
try {
|
||||
const response = await axios.post(testCase.url, testData, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
console.log(` ✅ 响应: ${JSON.stringify(response.data, null, 2)}`);
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误信息: ${JSON.stringify(error.response.data, null, 2)}`);
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(50));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 说明:');
|
||||
console.log(' - 如果本地测试成功但生产环境失败,说明nginx配置有问题');
|
||||
console.log(' - 如果两个都失败,说明后端服务有问题');
|
||||
console.log(' - 如果两个都成功,说明修复生效');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testLoginAPI().catch(console.error);
|
||||
@@ -1,114 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试nginx配置问题
|
||||
async function testNginxConfig() {
|
||||
console.log('🔍 测试nginx配置问题...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '直接测试后端服务',
|
||||
url: 'http://localhost:5352/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试部门接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误'
|
||||
},
|
||||
{
|
||||
name: '测试重复路径接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/departments',
|
||||
expected: '应该返回200(如果nginx配置有问题)'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500;
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置问题,路径映射不正确`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 可能的问题:');
|
||||
console.log(' 1. nginx配置语法错误');
|
||||
console.log(' 2. nginx服务未重启');
|
||||
console.log(' 3. location规则冲突');
|
||||
console.log(' 4. proxy_pass配置错误');
|
||||
console.log('');
|
||||
console.log('🔄 建议的解决步骤:');
|
||||
console.log(' 1. 检查nginx配置语法: sudo nginx -t');
|
||||
console.log(' 2. 重启nginx服务: sudo systemctl reload nginx');
|
||||
console.log(' 3. 检查nginx错误日志: sudo tail -f /var/log/nginx/error.log');
|
||||
console.log(' 4. 检查nginx访问日志: sudo tail -f /var/log/nginx/ad.ningmuyun.com.access.log');
|
||||
console.log('');
|
||||
console.log('📝 当前nginx配置应该是:');
|
||||
console.log(' location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxConfig().catch(console.error);
|
||||
@@ -1,112 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 调试nginx配置问题
|
||||
async function testNginxDebug() {
|
||||
console.log('🔍 调试nginx配置问题...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '直接测试后端服务',
|
||||
url: 'http://localhost:5352/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试部门接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
expected: '应该返回200'
|
||||
},
|
||||
{
|
||||
name: '通过nginx测试登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置问题,路径映射不正确`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 调试完成!');
|
||||
console.log('');
|
||||
console.log('📝 当前nginx配置:');
|
||||
console.log(' location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 如果所有接口都返回404,可能需要:');
|
||||
console.log(' 1. 检查nginx配置语法: sudo nginx -t');
|
||||
console.log(' 2. 重启nginx服务: sudo systemctl reload nginx');
|
||||
console.log(' 3. 检查nginx错误日志: sudo tail -f /var/log/nginx/error.log');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxDebug().catch(console.error);
|
||||
158
government-backend/test-nginx-deployment.js
Normal file
158
government-backend/test-nginx-deployment.js
Normal file
@@ -0,0 +1,158 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试部署环境的nginx配置
|
||||
const baseURL = 'https://ad.ningmuyun.com';
|
||||
|
||||
const testAPIs = [
|
||||
// 测试正常工作的接口
|
||||
{
|
||||
name: '数据览仓接口',
|
||||
url: '/api/government/data-center',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '市场行情接口',
|
||||
url: '/api/government/market-price',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '行政部门接口',
|
||||
url: '/api/government/departments',
|
||||
method: 'GET'
|
||||
},
|
||||
|
||||
// 测试有问题的接口
|
||||
{
|
||||
name: '行政人员接口',
|
||||
url: '/api/government/admin-staff',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '养殖户接口',
|
||||
url: '/api/government/farmers',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '智能项圈接口',
|
||||
url: '/api/government/collars',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '养殖类型接口',
|
||||
url: '/api/government/farm-types',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: '养殖种类接口',
|
||||
url: '/api/government/animal-types',
|
||||
method: 'GET'
|
||||
}
|
||||
];
|
||||
|
||||
async function testAPI(api) {
|
||||
try {
|
||||
console.log(`\n测试 ${api.name}...`);
|
||||
console.log(`URL: ${baseURL}${api.url}`);
|
||||
|
||||
const response = await axios({
|
||||
method: api.method,
|
||||
url: `${baseURL}${api.url}`,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ 状态码: ${response.status}`);
|
||||
console.log(`✅ 响应: ${JSON.stringify(response.data).substring(0, 100)}...`);
|
||||
return { success: true, status: response.status, data: response.data };
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ 错误: ${error.message}`);
|
||||
if (error.response) {
|
||||
console.log(`❌ 状态码: ${error.response.status}`);
|
||||
console.log(`❌ 响应: ${JSON.stringify(error.response.data)}`);
|
||||
|
||||
// 检查是否是路径重复错误
|
||||
if (error.response.data && JSON.stringify(error.response.data).includes('government/government')) {
|
||||
console.log(`🚨 发现路径重复错误!`);
|
||||
console.log(` 这可能是nginx配置问题导致的路径重复`);
|
||||
}
|
||||
|
||||
// 检查是否是404错误
|
||||
if (error.response.status === 404) {
|
||||
console.log(`🚨 404错误 - 接口不存在或路由配置问题`);
|
||||
}
|
||||
|
||||
// 检查是否是500错误
|
||||
if (error.response.status === 500) {
|
||||
console.log(`🚨 500错误 - 服务器内部错误`);
|
||||
}
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
console.log(`🚨 连接被拒绝 - 服务可能没有启动`);
|
||||
} else if (error.code === 'ENOTFOUND') {
|
||||
console.log(`🚨 域名解析失败 - 请检查域名配置`);
|
||||
}
|
||||
return { success: false, error: error.message, status: error.response?.status };
|
||||
}
|
||||
}
|
||||
|
||||
async function runTests() {
|
||||
console.log('测试部署环境的nginx配置...');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const api of testAPIs) {
|
||||
const result = await testAPI(api);
|
||||
results.push({
|
||||
name: api.name,
|
||||
url: api.url,
|
||||
...result
|
||||
});
|
||||
|
||||
// 等待1秒再测试下一个接口
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('测试结果汇总:');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const successCount = results.filter(r => r.success).length;
|
||||
const totalCount = results.length;
|
||||
|
||||
results.forEach(result => {
|
||||
const status = result.success ? '✅' : '❌';
|
||||
console.log(`${status} ${result.name}`);
|
||||
});
|
||||
|
||||
console.log(`\n总计: ${successCount}/${totalCount} 个接口测试通过`);
|
||||
|
||||
if (successCount === totalCount) {
|
||||
console.log('🎉 所有接口测试通过!nginx配置正常!');
|
||||
} else {
|
||||
console.log('⚠️ 部分接口测试失败,请检查nginx配置');
|
||||
|
||||
// 分析失败原因
|
||||
const failedResults = results.filter(r => !r.success);
|
||||
const pathDuplicationErrors = failedResults.filter(r =>
|
||||
r.error && r.error.includes('government/government')
|
||||
);
|
||||
|
||||
if (pathDuplicationErrors.length > 0) {
|
||||
console.log('\n🔍 问题分析:');
|
||||
console.log('🚨 发现路径重复错误,这通常是由以下原因造成的:');
|
||||
console.log(' 1. nginx配置中有多个location规则匹配同一个请求');
|
||||
console.log(' 2. proxy_pass配置不正确导致路径重复');
|
||||
console.log(' 3. 后端服务返回的路径包含重复的路径段');
|
||||
console.log('\n💡 建议解决方案:');
|
||||
console.log(' 1. 检查nginx配置中的location规则顺序');
|
||||
console.log(' 2. 确保只有一个location规则匹配/api/路径');
|
||||
console.log(' 3. 检查proxy_pass配置是否正确');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
runTests().catch(console.error);
|
||||
@@ -1,155 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试nginx最终修复效果
|
||||
async function testNginxFixFinal() {
|
||||
console.log('🔍 测试nginx最终修复效果...\n');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 将 proxy_pass http://localhost:5352');
|
||||
console.log(' 改为 proxy_pass http://localhost:5352/api/government/');
|
||||
console.log(' 这样可以正确代理到后端API路径\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
shouldWork: true,
|
||||
expectedStatus: 401
|
||||
}
|
||||
];
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500;
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` 状态码: ${response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
if (test.expectedStatus) {
|
||||
if (response.status === test.expectedStatus) {
|
||||
console.log(` ✅ 成功: 返回预期状态码 ${test.expectedStatus}`);
|
||||
successCount++;
|
||||
} else {
|
||||
console.log(` ❌ 失败: 预期状态码 ${test.expectedStatus},实际 ${response.status}`);
|
||||
failCount++;
|
||||
}
|
||||
} else if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
successCount++;
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 失败: 接口返回 404`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` 状态码: ${error.response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
console.log(` ❌ 失败: ${error.response.statusText}`);
|
||||
failCount++;
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log(` ✅ 成功: ${successCount} 个`);
|
||||
console.log(` ❌ 失败: ${failCount} 个`);
|
||||
console.log('');
|
||||
|
||||
if (failCount === 0) {
|
||||
console.log('🎉 所有测试通过!Nginx配置修复成功!');
|
||||
} else {
|
||||
console.log('⚠️ 还有测试失败,请检查:');
|
||||
console.log(' 1. Nginx配置是否正确修改');
|
||||
console.log(' 2. Nginx服务是否已重启');
|
||||
console.log(' 3. 后端服务是否正常运行');
|
||||
console.log('');
|
||||
console.log('🔄 重启Nginx:');
|
||||
console.log(' sudo nginx -t');
|
||||
console.log(' sudo systemctl reload nginx');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('📝 当前nginx配置:');
|
||||
console.log(' location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/data-center → http://localhost:5352/api/government/data-center');
|
||||
console.log(' /api/government/market-price → http://localhost:5352/api/government/market-price');
|
||||
console.log('');
|
||||
console.log('🚨 重要提醒:');
|
||||
console.log(' 修改nginx配置后,必须重启nginx服务才能生效!');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxFixFinal().catch(console.error);
|
||||
@@ -1,111 +1,143 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试nginx配置修复后的API接口
|
||||
async function testNginxFix() {
|
||||
console.log('🔍 测试nginx配置修复后的API接口...\n');
|
||||
// 测试修复后的nginx配置
|
||||
const baseURL = 'https://ad.ningmuyun.com';
|
||||
|
||||
const testAPIs = [
|
||||
// 政府端API测试
|
||||
{
|
||||
name: '政府端数据览仓',
|
||||
url: '/api/government/data-center',
|
||||
method: 'GET',
|
||||
expected: 'government'
|
||||
},
|
||||
{
|
||||
name: '政府端市场行情',
|
||||
url: '/api/government/market-price',
|
||||
method: 'GET',
|
||||
expected: 'government'
|
||||
},
|
||||
{
|
||||
name: '政府端行政部门',
|
||||
url: '/api/government/departments',
|
||||
method: 'GET',
|
||||
expected: 'government'
|
||||
},
|
||||
{
|
||||
name: '政府端养殖类型',
|
||||
url: '/api/government/farm-types',
|
||||
method: 'GET',
|
||||
expected: 'government'
|
||||
},
|
||||
{
|
||||
name: '政府端养殖种类',
|
||||
url: '/api/government/animal-types',
|
||||
method: 'GET',
|
||||
expected: 'government'
|
||||
},
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '登录接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
expected: '应该返回401认证错误(接口正常)'
|
||||
},
|
||||
{
|
||||
name: '部门列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
method: 'GET',
|
||||
expected: '应该返回200状态码和部门数据'
|
||||
},
|
||||
{
|
||||
name: '数据中心接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
method: 'GET',
|
||||
expected: '应该返回200状态码和统计数据'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
method: 'GET',
|
||||
expected: '应该返回200状态码和价格数据'
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
method: 'GET',
|
||||
expected: '应该返回200状态码和岗位数据'
|
||||
}
|
||||
];
|
||||
// 银行端API测试
|
||||
{
|
||||
name: '银行端API',
|
||||
url: '/bank/api/auth/login',
|
||||
method: 'POST',
|
||||
expected: 'bank'
|
||||
},
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
// 保险端API测试
|
||||
{
|
||||
name: '保险端API',
|
||||
url: '/insurance/api/auth/login',
|
||||
method: 'POST',
|
||||
expected: 'insurance'
|
||||
},
|
||||
|
||||
// 养殖端API测试
|
||||
{
|
||||
name: '养殖端API',
|
||||
url: '/farm/api/auth/login',
|
||||
method: 'POST',
|
||||
expected: 'farm'
|
||||
}
|
||||
];
|
||||
|
||||
async function testAPI(api) {
|
||||
try {
|
||||
console.log(`\n测试 ${api.name}...`);
|
||||
console.log(`URL: ${baseURL}${api.url}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method,
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
const response = await axios({
|
||||
method: api.method,
|
||||
url: `${baseURL}${api.url}`,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ 状态码: ${response.status}`);
|
||||
console.log(`✅ 响应: ${JSON.stringify(response.data).substring(0, 100)}...`);
|
||||
return { success: true, status: response.status, data: response.data };
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ 错误: ${error.message}`);
|
||||
if (error.response) {
|
||||
console.log(`❌ 状态码: ${error.response.status}`);
|
||||
console.log(`❌ 响应: ${JSON.stringify(error.response.data)}`);
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 接口不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: nginx配置可能还有问题`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
// 检查是否是路径重复错误
|
||||
if (error.response.data && JSON.stringify(error.response.data).includes('government/government')) {
|
||||
console.log(`🚨 发现路径重复错误!`);
|
||||
}
|
||||
}
|
||||
return { success: false, error: error.message, status: error.response?.status };
|
||||
}
|
||||
}
|
||||
|
||||
async function runTests() {
|
||||
console.log('测试修复后的nginx配置...');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const api of testAPIs) {
|
||||
const result = await testAPI(api);
|
||||
results.push({
|
||||
name: api.name,
|
||||
url: api.url,
|
||||
expected: api.expected,
|
||||
...result
|
||||
});
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
// 等待1秒再测试下一个接口
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 问题: location规则缩进不正确,被嵌套在错误的块内');
|
||||
console.log(' 修复: 调整了location规则的缩进和位置');
|
||||
console.log('');
|
||||
console.log('🔄 现在需要重启nginx使配置生效:');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('测试结果汇总:');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const successCount = results.filter(r => r.success).length;
|
||||
const totalCount = results.length;
|
||||
|
||||
results.forEach(result => {
|
||||
const status = result.success ? '✅' : '❌';
|
||||
console.log(`${status} ${result.name} (${result.expected})`);
|
||||
});
|
||||
|
||||
console.log(`\n总计: ${successCount}/${totalCount} 个接口测试通过`);
|
||||
|
||||
if (successCount === totalCount) {
|
||||
console.log('🎉 所有接口测试通过!nginx配置修复成功!');
|
||||
} else {
|
||||
console.log('⚠️ 部分接口测试失败,请检查配置');
|
||||
}
|
||||
|
||||
console.log('\n修复说明:');
|
||||
console.log('✅ 将养殖端API路径从 /api/ 改为 /farm-api/');
|
||||
console.log('✅ 避免与政府端 /api/ 路径冲突');
|
||||
console.log('✅ 政府端API现在可以正常访问');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxFix().catch(console.error);
|
||||
runTests().catch(console.error);
|
||||
@@ -1,150 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试nginx重启后的修复效果
|
||||
async function testNginxRestartFix() {
|
||||
console.log('🔍 测试nginx重启后的修复效果...\n');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 将 proxy_pass http://localhost:5352');
|
||||
console.log(' 改为 proxy_pass http://localhost:5352/api/government/');
|
||||
console.log(' 这样可以正确代理到后端API路径\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
shouldWork: true,
|
||||
expectedStatus: 401
|
||||
}
|
||||
];
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500;
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` 状态码: ${response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
if (test.expectedStatus) {
|
||||
if (response.status === test.expectedStatus) {
|
||||
console.log(` ✅ 成功: 返回预期状态码 ${test.expectedStatus}`);
|
||||
successCount++;
|
||||
} else {
|
||||
console.log(` ❌ 失败: 预期状态码 ${test.expectedStatus},实际 ${response.status}`);
|
||||
failCount++;
|
||||
}
|
||||
} else if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
successCount++;
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 失败: 接口返回 404`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` 状态码: ${error.response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
console.log(` ❌ 失败: ${error.response.statusText}`);
|
||||
failCount++;
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log(` ✅ 成功: ${successCount} 个`);
|
||||
console.log(` ❌ 失败: ${failCount} 个`);
|
||||
console.log('');
|
||||
|
||||
if (failCount === 0) {
|
||||
console.log('🎉 所有测试通过!Nginx配置修复成功!');
|
||||
} else {
|
||||
console.log('⚠️ 还有测试失败,请检查:');
|
||||
console.log(' 1. Nginx配置是否正确修改');
|
||||
console.log(' 2. Nginx服务是否已重启');
|
||||
console.log(' 3. 后端服务是否正常运行');
|
||||
console.log('');
|
||||
console.log('🔄 重启Nginx:');
|
||||
console.log(' sudo nginx -t');
|
||||
console.log(' sudo systemctl reload nginx');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('📝 当前nginx配置:');
|
||||
console.log(' location ^~ /api/government/auth/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/auth/;');
|
||||
console.log(' }');
|
||||
console.log(' location ^~ /api/government/ {');
|
||||
console.log(' proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' }');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/data-center → http://localhost:5352/api/government/data-center');
|
||||
console.log(' /api/government/market-price → http://localhost:5352/api/government/market-price');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxRestartFix().catch(console.error);
|
||||
@@ -1,35 +0,0 @@
|
||||
const { exec } = require('child_process');
|
||||
|
||||
// 测试nginx配置语法
|
||||
function testNginxSyntax() {
|
||||
console.log('🔍 测试nginx配置语法...\n');
|
||||
|
||||
exec('nginx -t', (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.log('❌ nginx配置语法错误:');
|
||||
console.log(stderr);
|
||||
console.log('\n🔍 可能的问题:');
|
||||
console.log(' 1. 缩进问题');
|
||||
console.log(' 2. 缺少分号');
|
||||
console.log(' 3. 括号不匹配');
|
||||
console.log(' 4. 隐藏字符');
|
||||
return;
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.log('⚠️ nginx配置警告:');
|
||||
console.log(stderr);
|
||||
}
|
||||
|
||||
console.log('✅ nginx配置语法正确');
|
||||
console.log(stdout);
|
||||
|
||||
console.log('\n🔄 建议的解决步骤:');
|
||||
console.log(' 1. 重启nginx服务: sudo systemctl reload nginx');
|
||||
console.log(' 2. 检查nginx错误日志: sudo tail -f /var/log/nginx/error.log');
|
||||
console.log(' 3. 检查nginx访问日志: sudo tail -f /var/log/nginx/access.log');
|
||||
});
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testNginxSyntax();
|
||||
@@ -1,115 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试路径重复修复效果
|
||||
async function testPathDuplicationFix() {
|
||||
console.log('🔍 测试路径重复修复效果...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '正确路径 - 部门列表',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回200状态码'
|
||||
},
|
||||
{
|
||||
name: '重复路径 - 部门列表',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/departments',
|
||||
expected: '应该返回404错误(路径不存在)'
|
||||
},
|
||||
{
|
||||
name: '正确路径 - 数据中心',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
expected: '应该返回200状态码'
|
||||
},
|
||||
{
|
||||
name: '重复路径 - 数据中心',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/data-center',
|
||||
expected: '应该返回404错误(路径不存在)'
|
||||
},
|
||||
{
|
||||
name: '正确路径 - 市场价格',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
expected: '应该返回200状态码'
|
||||
},
|
||||
{
|
||||
name: '重复路径 - 市场价格',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/market-price?type=beef',
|
||||
expected: '应该返回404错误(路径不存在)'
|
||||
},
|
||||
{
|
||||
name: '正确路径 - 养殖类型',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farm-types',
|
||||
expected: '应该返回200状态码'
|
||||
},
|
||||
{
|
||||
name: '重复路径 - 养殖类型',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/farm-types',
|
||||
expected: '应该返回404错误(路径不存在)'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const response = await axios.get(test.url, {
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
});
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证(接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ✅ 正常: 路径不存在(符合预期)`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` ✅ 正常: 路径不存在(符合预期)`);
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
} else {
|
||||
console.log(` ❌ 请求配置错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' 问题: proxy_pass配置导致路径重复');
|
||||
console.log(' 修复前: proxy_pass http://localhost:5352/api/government/;');
|
||||
console.log(' 修复后: proxy_pass http://localhost:5352/;');
|
||||
console.log('');
|
||||
console.log('🔄 路径映射:');
|
||||
console.log(' /api/government/departments → http://localhost:5352/api/government/departments');
|
||||
console.log(' /api/government/data-center → http://localhost:5352/api/government/data-center');
|
||||
console.log(' /api/government/market-price → http://localhost:5352/api/government/market-price');
|
||||
console.log('');
|
||||
console.log('🔄 现在需要重启nginx使配置生效:');
|
||||
console.log(' sudo nginx -t # 检查配置语法');
|
||||
console.log(' sudo systemctl reload nginx # 重新加载配置');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testPathDuplicationFix().catch(console.error);
|
||||
@@ -1,84 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试路径修复效果
|
||||
async function testPathFix() {
|
||||
console.log('🔍 测试政府端API路径修复效果...\n');
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '岗位列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
expected: '应该返回岗位列表数据'
|
||||
},
|
||||
{
|
||||
name: '部门列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
expected: '应该返回部门列表数据'
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
expected: '应该返回养殖户列表数据'
|
||||
},
|
||||
{
|
||||
name: '市场价格接口测试',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
expected: '应该返回市场价格数据'
|
||||
}
|
||||
];
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
console.log(` 预期: ${test.expected}`);
|
||||
|
||||
try {
|
||||
const response = await axios.get(test.url, {
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500; // 接受所有小于500的状态码
|
||||
}
|
||||
});
|
||||
|
||||
console.log(` ✅ 状态码: ${response.status}`);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 返回了正确的数据`);
|
||||
if (Array.isArray(response.data)) {
|
||||
console.log(` 📊 数据量: ${response.data.length} 条记录`);
|
||||
} else if (response.data && typeof response.data === 'object') {
|
||||
console.log(` 📊 数据类型: 对象,包含 ${Object.keys(response.data).length} 个字段`);
|
||||
}
|
||||
} else if (response.status === 401) {
|
||||
console.log(` ✅ 正常: 需要认证 (接口路径正确)`);
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 错误: 路径不存在`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` ❌ 状态码: ${error.response.status}`);
|
||||
console.log(` ❌ 错误: ${error.response.statusText}`);
|
||||
|
||||
if (error.response.status === 404) {
|
||||
console.log(` 🔍 分析: 可能是nginx配置问题,路径映射不正确`);
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log('');
|
||||
console.log('📝 修复说明:');
|
||||
console.log(' - 修复前: proxy_pass http://localhost:5352/api/government/; (会重复路径)');
|
||||
console.log(' - 修复后: proxy_pass http://localhost:5352/; (正确映射)');
|
||||
console.log(' - 现在 /api/government/positions 应该正确映射到 /api/government/positions');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
testPathFix().catch(console.error);
|
||||
162
government-backend/test-problematic-apis.js
Normal file
162
government-backend/test-problematic-apis.js
Normal file
@@ -0,0 +1,162 @@
|
||||
const axios = require('axios');
|
||||
|
||||
// 测试有问题的政府端API接口
|
||||
const baseURL = 'https://ad.ningmuyun.com';
|
||||
|
||||
const testAPIs = [
|
||||
// 正常的接口
|
||||
{
|
||||
name: '数据览仓接口',
|
||||
url: '/api/government/data-center',
|
||||
method: 'GET',
|
||||
category: '正常'
|
||||
},
|
||||
{
|
||||
name: '市场行情接口',
|
||||
url: '/api/government/market-price',
|
||||
method: 'GET',
|
||||
category: '正常'
|
||||
},
|
||||
{
|
||||
name: '行政部门接口',
|
||||
url: '/api/government/departments',
|
||||
method: 'GET',
|
||||
category: '正常'
|
||||
},
|
||||
|
||||
// 有问题的接口
|
||||
{
|
||||
name: '行政人员接口',
|
||||
url: '/api/government/admin-staff',
|
||||
method: 'GET',
|
||||
category: '问题'
|
||||
},
|
||||
{
|
||||
name: '养殖户接口',
|
||||
url: '/api/government/farmers',
|
||||
method: 'GET',
|
||||
category: '问题'
|
||||
},
|
||||
{
|
||||
name: '智能项圈接口',
|
||||
url: '/api/government/collars',
|
||||
method: 'GET',
|
||||
category: '问题'
|
||||
},
|
||||
{
|
||||
name: '养殖类型接口',
|
||||
url: '/api/government/farm-types',
|
||||
method: 'GET',
|
||||
category: '问题'
|
||||
},
|
||||
{
|
||||
name: '养殖种类接口',
|
||||
url: '/api/government/animal-types',
|
||||
method: 'GET',
|
||||
category: '问题'
|
||||
}
|
||||
];
|
||||
|
||||
async function testAPI(api) {
|
||||
try {
|
||||
console.log(`\n测试 ${api.name} (${api.category})...`);
|
||||
console.log(`URL: ${baseURL}${api.url}`);
|
||||
|
||||
const response = await axios({
|
||||
method: api.method,
|
||||
url: `${baseURL}${api.url}`,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ 状态码: ${response.status}`);
|
||||
console.log(`✅ 响应: ${JSON.stringify(response.data).substring(0, 100)}...`);
|
||||
return { success: true, status: response.status, data: response.data };
|
||||
|
||||
} catch (error) {
|
||||
console.log(`❌ 错误: ${error.message}`);
|
||||
if (error.response) {
|
||||
console.log(`❌ 状态码: ${error.response.status}`);
|
||||
console.log(`❌ 响应: ${JSON.stringify(error.response.data)}`);
|
||||
|
||||
// 检查是否是路径重复错误
|
||||
if (error.response.data && JSON.stringify(error.response.data).includes('government/government')) {
|
||||
console.log(`🚨 发现路径重复错误!`);
|
||||
}
|
||||
|
||||
// 检查是否是404错误
|
||||
if (error.response.status === 404) {
|
||||
console.log(`🚨 404错误 - 接口不存在或路由配置问题`);
|
||||
}
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
console.log(`🚨 连接被拒绝 - 服务可能没有启动`);
|
||||
}
|
||||
return { success: false, error: error.message, status: error.response?.status };
|
||||
}
|
||||
}
|
||||
|
||||
async function runTests() {
|
||||
console.log('测试政府端API接口 - 对比正常和问题接口...');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const results = [];
|
||||
|
||||
for (const api of testAPIs) {
|
||||
const result = await testAPI(api);
|
||||
results.push({
|
||||
name: api.name,
|
||||
url: api.url,
|
||||
category: api.category,
|
||||
...result
|
||||
});
|
||||
|
||||
// 等待1秒再测试下一个接口
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('测试结果汇总:');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// 按类别分组统计
|
||||
const normalAPIs = results.filter(r => r.category === '正常');
|
||||
const problemAPIs = results.filter(r => r.category === '问题');
|
||||
|
||||
console.log('\n正常接口:');
|
||||
normalAPIs.forEach(result => {
|
||||
const status = result.success ? '✅' : '❌';
|
||||
console.log(` ${status} ${result.name}`);
|
||||
});
|
||||
|
||||
console.log('\n问题接口:');
|
||||
problemAPIs.forEach(result => {
|
||||
const status = result.success ? '✅' : '❌';
|
||||
console.log(` ${status} ${result.name}`);
|
||||
});
|
||||
|
||||
const normalSuccess = normalAPIs.filter(r => r.success).length;
|
||||
const problemSuccess = problemAPIs.filter(r => r.success).length;
|
||||
|
||||
console.log(`\n统计结果:`);
|
||||
console.log(`正常接口: ${normalSuccess}/${normalAPIs.length} 通过`);
|
||||
console.log(`问题接口: ${problemSuccess}/${problemAPIs.length} 通过`);
|
||||
|
||||
if (normalSuccess === normalAPIs.length && problemSuccess === 0) {
|
||||
console.log('\n🔍 分析结果:');
|
||||
console.log('✅ 正常接口全部通过');
|
||||
console.log('❌ 问题接口全部失败');
|
||||
console.log('🚨 这表明问题接口确实存在路由或实现问题');
|
||||
} else if (normalSuccess === normalAPIs.length && problemSuccess > 0) {
|
||||
console.log('\n🔍 分析结果:');
|
||||
console.log('✅ 部分问题接口已修复');
|
||||
console.log('⚠️ 仍有部分问题接口需要修复');
|
||||
} else {
|
||||
console.log('\n🔍 分析结果:');
|
||||
console.log('⚠️ 所有接口都有问题,可能是nginx配置问题');
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
runTests().catch(console.error);
|
||||
@@ -1,149 +1,143 @@
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 验证nginx修复效果
|
||||
async function verifyNginxFix() {
|
||||
console.log('🔍 验证 Nginx 修复效果...\n');
|
||||
console.log('📝 修改说明:');
|
||||
console.log(' 将 proxy_pass http://localhost:5352/api/government/');
|
||||
console.log(' 改为 proxy_pass http://localhost:5352');
|
||||
console.log(' 这样可以保持完整路径,避免路径重复\n');
|
||||
// 读取nginx配置文件
|
||||
const nginxConfigPath = path.join(__dirname, 'nginx.conf');
|
||||
const nginxConfig = fs.readFileSync(nginxConfigPath, 'utf8');
|
||||
|
||||
console.log('验证nginx配置修复...');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// 检查是否存在路径冲突
|
||||
const apiLocationPatterns = [
|
||||
{
|
||||
name: '养殖端API (旧)',
|
||||
pattern: /location \/api\//,
|
||||
shouldExist: false,
|
||||
description: '旧的养殖端API路径,应该被移除'
|
||||
},
|
||||
{
|
||||
name: '养殖端API (新)',
|
||||
pattern: /location \^~ \/farm-api\//,
|
||||
shouldExist: true,
|
||||
description: '新的养殖端API路径'
|
||||
},
|
||||
{
|
||||
name: '政府端API',
|
||||
pattern: /location \^~ \/api\//,
|
||||
shouldExist: true,
|
||||
description: '政府端API路径'
|
||||
},
|
||||
{
|
||||
name: '银行端API',
|
||||
pattern: /location \^~ \/bank\/api\//,
|
||||
shouldExist: true,
|
||||
description: '银行端API路径'
|
||||
},
|
||||
{
|
||||
name: '保险端API',
|
||||
pattern: /location \^~ \/insurance\/api\//,
|
||||
shouldExist: true,
|
||||
description: '保险端API路径'
|
||||
}
|
||||
];
|
||||
|
||||
console.log('检查API路径配置:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
let allCorrect = true;
|
||||
|
||||
apiLocationPatterns.forEach(config => {
|
||||
const found = config.pattern.test(nginxConfig);
|
||||
const status = found === config.shouldExist ? '✅' : '❌';
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
name: '部门列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/departments',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '数据中心接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/data-center',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '市场价格接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/market-price?type=beef',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '岗位列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/positions',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '养殖户列表接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/farmers',
|
||||
shouldWork: true
|
||||
},
|
||||
{
|
||||
name: '登录接口',
|
||||
url: 'https://ad.ningmuyun.com/api/government/auth/login',
|
||||
method: 'POST',
|
||||
data: { username: 'admin', password: 'admin123' },
|
||||
shouldWork: true,
|
||||
expectedStatus: 401
|
||||
},
|
||||
{
|
||||
name: '重复路径接口(应该404)',
|
||||
url: 'https://ad.ningmuyun.com/api/government/government/departments',
|
||||
shouldWork: false
|
||||
}
|
||||
];
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
for (const test of testCases) {
|
||||
console.log(`📋 ${test.name}`);
|
||||
console.log(` URL: ${test.url}`);
|
||||
|
||||
try {
|
||||
const config = {
|
||||
method: test.method || 'GET',
|
||||
url: test.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: 10000,
|
||||
validateStatus: function (status) {
|
||||
return status < 500;
|
||||
}
|
||||
};
|
||||
|
||||
if (test.data) {
|
||||
config.data = test.data;
|
||||
}
|
||||
|
||||
const response = await axios(config);
|
||||
|
||||
console.log(` 状态码: ${response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
if (test.expectedStatus) {
|
||||
if (response.status === test.expectedStatus) {
|
||||
console.log(` ✅ 成功: 返回预期状态码 ${test.expectedStatus}`);
|
||||
successCount++;
|
||||
} else {
|
||||
console.log(` ❌ 失败: 预期状态码 ${test.expectedStatus},实际 ${response.status}`);
|
||||
failCount++;
|
||||
}
|
||||
} else if (response.status === 200) {
|
||||
console.log(` ✅ 成功: 接口正常工作`);
|
||||
successCount++;
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ 失败: 接口返回 404`);
|
||||
failCount++;
|
||||
}
|
||||
} else {
|
||||
if (response.status === 404) {
|
||||
console.log(` ✅ 成功: 正确返回 404(重复路径应该不存在)`);
|
||||
successCount++;
|
||||
} else if (response.status === 200) {
|
||||
console.log(` ❌ 失败: 重复路径不应该工作`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
console.log(` 状态码: ${error.response.status}`);
|
||||
|
||||
if (test.shouldWork) {
|
||||
console.log(` ❌ 失败: ${error.response.statusText}`);
|
||||
failCount++;
|
||||
} else {
|
||||
if (error.response.status === 404) {
|
||||
console.log(` ✅ 成功: 正确返回 404`);
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(` ❌ 网络错误: ${error.message}`);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(' ' + '─'.repeat(60));
|
||||
console.log('');
|
||||
if (found !== config.shouldExist) {
|
||||
allCorrect = false;
|
||||
}
|
||||
|
||||
console.log('🎯 测试完成!');
|
||||
console.log(` ✅ 成功: ${successCount} 个`);
|
||||
console.log(` ❌ 失败: ${failCount} 个`);
|
||||
console.log('');
|
||||
|
||||
if (failCount === 0) {
|
||||
console.log('🎉 所有测试通过!Nginx 配置修复成功!');
|
||||
} else {
|
||||
console.log('⚠️ 还有测试失败,请检查:');
|
||||
console.log(' 1. Nginx 配置是否正确修改');
|
||||
console.log(' 2. Nginx 服务是否已重启');
|
||||
console.log(' 3. 浏览器缓存是否已清除');
|
||||
console.log('');
|
||||
console.log('🔄 重启 Nginx:');
|
||||
console.log(' sudo nginx -t');
|
||||
console.log(' sudo systemctl reload nginx');
|
||||
console.log(`${status} ${config.name}: ${found ? '存在' : '不存在'}`);
|
||||
console.log(` ${config.description}`);
|
||||
});
|
||||
|
||||
// 检查代理目标端口
|
||||
const proxyTargets = [
|
||||
{
|
||||
name: '政府端代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\/api\//,
|
||||
expected: 'http://localhost:5352/api/'
|
||||
},
|
||||
{
|
||||
name: '养殖端代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5350\/api\//,
|
||||
expected: 'http://localhost:5350/api/'
|
||||
},
|
||||
{
|
||||
name: '银行端代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5351\/api\//,
|
||||
expected: 'http://localhost:5351/api/'
|
||||
},
|
||||
{
|
||||
name: '保险端代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:3000\/api\//,
|
||||
expected: 'http://localhost:3000/api/'
|
||||
}
|
||||
];
|
||||
|
||||
console.log('\n检查代理目标配置:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
proxyTargets.forEach(config => {
|
||||
const found = config.pattern.test(nginxConfig);
|
||||
const status = found ? '✅' : '❌';
|
||||
console.log(`${status} ${config.name}: ${found ? '已配置' : '未找到'}`);
|
||||
if (!found) {
|
||||
console.log(` 期望: ${config.expected}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 检查是否有重复的location规则
|
||||
console.log('\n检查重复的location规则:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
const locationMatches = nginxConfig.match(/location\s+[^{]+{/g) || [];
|
||||
const locationPaths = locationMatches.map(match => {
|
||||
const pathMatch = match.match(/location\s+([^{]+)/);
|
||||
return pathMatch ? pathMatch[1].trim() : '';
|
||||
});
|
||||
|
||||
const duplicatePaths = locationPaths.filter((path, index) =>
|
||||
locationPaths.indexOf(path) !== index && path !== ''
|
||||
);
|
||||
|
||||
if (duplicatePaths.length > 0) {
|
||||
console.log('❌ 发现重复的location规则:');
|
||||
duplicatePaths.forEach(path => {
|
||||
console.log(` - ${path}`);
|
||||
});
|
||||
allCorrect = false;
|
||||
} else {
|
||||
console.log('✅ 没有重复的location规则');
|
||||
}
|
||||
|
||||
// 运行验证
|
||||
verifyNginxFix().catch(console.error);
|
||||
console.log('\n' + '='.repeat(50));
|
||||
console.log('配置验证结果:');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
if (allCorrect) {
|
||||
console.log('🎉 nginx配置修复成功!');
|
||||
console.log('✅ 路径冲突已解决');
|
||||
console.log('✅ 各端API路径正确配置');
|
||||
console.log('✅ 代理目标端口正确');
|
||||
} else {
|
||||
console.log('⚠️ nginx配置需要进一步修复');
|
||||
console.log('请检查上述错误并修复');
|
||||
}
|
||||
|
||||
console.log('\n建议的nginx重载命令:');
|
||||
console.log('sudo nginx -t && sudo nginx -s reload');
|
||||
|
||||
console.log('\n修复说明:');
|
||||
console.log('1. 将养殖端API路径从 /api/ 改为 /farm-api/');
|
||||
console.log('2. 避免与政府端 /api/ 路径冲突');
|
||||
console.log('3. 政府端API现在可以正常访问');
|
||||
console.log('4. 各端API路径互不冲突');
|
||||
152
government-backend/verify-nginx-government-config.js
Normal file
152
government-backend/verify-nginx-government-config.js
Normal file
@@ -0,0 +1,152 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 读取nginx配置文件
|
||||
const nginxConfigPath = path.join(__dirname, 'nginx.conf');
|
||||
const nginxConfig = fs.readFileSync(nginxConfigPath, 'utf8');
|
||||
|
||||
console.log('检查政府端nginx配置...');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// 检查政府端API代理配置
|
||||
const governmentAPIConfigs = [
|
||||
{
|
||||
name: '认证API代理',
|
||||
pattern: /location \^~ \/api\/auth\//,
|
||||
expected: 'location ^~ /api/auth/'
|
||||
},
|
||||
{
|
||||
name: '监管API代理',
|
||||
pattern: /location \^~ \/api\/supervision\//,
|
||||
expected: 'location ^~ /api/supervision/'
|
||||
},
|
||||
{
|
||||
name: '疫情API代理',
|
||||
pattern: /location \^~ \/api\/epidemic\//,
|
||||
expected: 'location ^~ /api/epidemic/'
|
||||
},
|
||||
{
|
||||
name: '政府API代理',
|
||||
pattern: /location \^~ \/api\/government\//,
|
||||
expected: 'location ^~ /api/government/'
|
||||
},
|
||||
{
|
||||
name: '其他API代理',
|
||||
pattern: /location ~ \^\/api\/\(personnel\|approval\|service\|visualization\|system\|files\|smart-earmark\|smart-host\|slaughter\|harmless\|harmless-place\|epidemic-record\|vaccine\|epidemic-activity\|production-material-certification\|approval-process\|cattle-academy\|device-warning\)\//,
|
||||
expected: 'location ~ ^/api/(personnel|approval|service|...)/'
|
||||
}
|
||||
];
|
||||
|
||||
// 检查代理目标端口
|
||||
const proxyTargets = [
|
||||
{
|
||||
name: '认证API代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\/api\/auth\//,
|
||||
expected: 'http://localhost:5352/api/auth/'
|
||||
},
|
||||
{
|
||||
name: '监管API代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\/api\/supervision\//,
|
||||
expected: 'http://localhost:5352/api/supervision/'
|
||||
},
|
||||
{
|
||||
name: '疫情API代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\/api\/epidemic\//,
|
||||
expected: 'http://localhost:5352/api/epidemic/'
|
||||
},
|
||||
{
|
||||
name: '政府API代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\/api\/government\//,
|
||||
expected: 'http://localhost:5352/api/government/'
|
||||
},
|
||||
{
|
||||
name: '其他API代理目标',
|
||||
pattern: /proxy_pass http:\/\/localhost:5352\$request_uri/,
|
||||
expected: 'http://localhost:5352$request_uri'
|
||||
}
|
||||
];
|
||||
|
||||
console.log('检查API代理配置:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
governmentAPIConfigs.forEach(config => {
|
||||
const found = config.pattern.test(nginxConfig);
|
||||
const status = found ? '✅' : '❌';
|
||||
console.log(`${status} ${config.name}: ${found ? '已配置' : '未找到'}`);
|
||||
if (!found) {
|
||||
console.log(` 期望: ${config.expected}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n检查代理目标配置:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
proxyTargets.forEach(config => {
|
||||
const found = config.pattern.test(nginxConfig);
|
||||
const status = found ? '✅' : '❌';
|
||||
console.log(`${status} ${config.name}: ${found ? '已配置' : '未找到'}`);
|
||||
if (!found) {
|
||||
console.log(` 期望: ${config.expected}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 检查CORS配置
|
||||
console.log('\n检查CORS配置:');
|
||||
console.log('-'.repeat(30));
|
||||
|
||||
const corsConfigs = [
|
||||
{
|
||||
name: 'Access-Control-Allow-Origin',
|
||||
pattern: /add_header 'Access-Control-Allow-Origin' 'https:\/\/ad\.ningmuyun\.com' always;/,
|
||||
expected: 'https://ad.ningmuyun.com'
|
||||
},
|
||||
{
|
||||
name: 'Access-Control-Allow-Methods',
|
||||
pattern: /add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;/,
|
||||
expected: 'GET, POST, OPTIONS, PUT, DELETE'
|
||||
},
|
||||
{
|
||||
name: 'Access-Control-Allow-Headers',
|
||||
pattern: /add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;/,
|
||||
expected: 'Authorization, Content-Type, X-Requested-With'
|
||||
}
|
||||
];
|
||||
|
||||
corsConfigs.forEach(config => {
|
||||
const found = config.pattern.test(nginxConfig);
|
||||
const status = found ? '✅' : '❌';
|
||||
console.log(`${status} ${config.name}: ${found ? '已配置' : '未找到'}`);
|
||||
if (!found) {
|
||||
console.log(` 期望: ${config.expected}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 统计配置数量
|
||||
const totalAPIConfigs = governmentAPIConfigs.length;
|
||||
const foundAPIConfigs = governmentAPIConfigs.filter(config => config.pattern.test(nginxConfig)).length;
|
||||
|
||||
const totalProxyTargets = proxyTargets.length;
|
||||
const foundProxyTargets = proxyTargets.filter(config => config.pattern.test(nginxConfig)).length;
|
||||
|
||||
const totalCorsConfigs = corsConfigs.length;
|
||||
const foundCorsConfigs = corsConfigs.filter(config => config.pattern.test(nginxConfig)).length;
|
||||
|
||||
console.log('\n' + '='.repeat(50));
|
||||
console.log('配置检查结果汇总:');
|
||||
console.log('='.repeat(50));
|
||||
console.log(`API代理配置: ${foundAPIConfigs}/${totalAPIConfigs}`);
|
||||
console.log(`代理目标配置: ${foundProxyTargets}/${totalProxyTargets}`);
|
||||
console.log(`CORS配置: ${foundCorsConfigs}/${totalCorsConfigs}`);
|
||||
|
||||
const allConfigured = foundAPIConfigs === totalAPIConfigs &&
|
||||
foundProxyTargets === totalProxyTargets &&
|
||||
foundCorsConfigs === totalCorsConfigs;
|
||||
|
||||
if (allConfigured) {
|
||||
console.log('\n🎉 所有政府端nginx配置检查通过!');
|
||||
} else {
|
||||
console.log('\n⚠️ 部分配置缺失,请检查nginx.conf文件');
|
||||
}
|
||||
|
||||
console.log('\n建议的nginx重载命令:');
|
||||
console.log('sudo nginx -t && sudo nginx -s reload');
|
||||
@@ -1,126 +0,0 @@
|
||||
# 前端API路径修复说明
|
||||
|
||||
## 问题描述
|
||||
- **错误URL**: `https://ad.ningmuyun.com/api/government/government/positions`
|
||||
- **问题**: URL中出现两个`government`,导致路径重复
|
||||
- **影响范围**: 政府端管理系统所有政府相关API接口
|
||||
|
||||
## 问题根因分析
|
||||
|
||||
### 1. 前端API配置问题 ❌
|
||||
在 `government-admin/src/utils/api.js` 中,政府相关的API接口缺少 `/api` 前缀:
|
||||
|
||||
**原始错误配置**:
|
||||
```javascript
|
||||
// 部门管理
|
||||
departments: {
|
||||
getList: (params) => instance.get('/government/departments', { params })
|
||||
},
|
||||
|
||||
// 岗位管理
|
||||
positions: {
|
||||
getList: (params) => instance.get('/government/positions', { params })
|
||||
},
|
||||
|
||||
// 养殖户管理
|
||||
farmers: {
|
||||
getList: (params) => instance.get('/government/farmers', { params }),
|
||||
create: (data) => instance.post('/government/farmers', data),
|
||||
// ... 其他方法
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 路径构造过程
|
||||
1. **前端baseURL**: `http://localhost:5352/api` (开发环境)
|
||||
2. **API调用**: `instance.get('/government/positions')`
|
||||
3. **实际请求**: `http://localhost:5352/api/government/positions` ✅ 正确
|
||||
|
||||
但在生产环境中:
|
||||
1. **前端baseURL**: `https://ad.ningmuyun.com` (生产环境)
|
||||
2. **API调用**: `instance.get('/government/positions')`
|
||||
3. **实际请求**: `https://ad.ningmuyun.com/government/positions` ❌ 缺少 `/api` 前缀
|
||||
4. **nginx匹配**: 匹配到 `location ^~ /government/` (静态文件规则)
|
||||
5. **重定向**: 可能被重写为 `/api/government/government/positions` ❌ 重复
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 修复前端API配置
|
||||
将所有政府相关API接口添加 `/api` 前缀:
|
||||
|
||||
```javascript
|
||||
// 部门管理
|
||||
departments: {
|
||||
getList: (params) => instance.get('/api/government/departments', { params })
|
||||
},
|
||||
|
||||
// 岗位管理
|
||||
positions: {
|
||||
getList: (params) => instance.get('/api/government/positions', { params })
|
||||
},
|
||||
|
||||
// 养殖户管理
|
||||
farmers: {
|
||||
getList: (params) => instance.get('/api/government/farmers', { params }),
|
||||
create: (data) => instance.post('/api/government/farmers', data),
|
||||
update: (id, data) => instance.put(`/api/government/farmers/${id}`, data),
|
||||
delete: (id) => instance.delete(`/api/government/farmers/${id}`),
|
||||
resetPassword: (id) => instance.post(`/api/government/farmers/${id}/reset-password`)
|
||||
},
|
||||
|
||||
// 养殖类型相关
|
||||
farmTypes: {
|
||||
getList: () => instance.get('/api/government/farm-types')
|
||||
},
|
||||
|
||||
// 养殖种类相关
|
||||
animalTypes: {
|
||||
getList: () => instance.get('/api/government/animal-types')
|
||||
},
|
||||
|
||||
// 智能项圈管理
|
||||
collars: {
|
||||
getList: (params) => instance.get('/api/government/collars', { params }),
|
||||
create: (data) => instance.post('/api/government/collars', data),
|
||||
update: (id, data) => instance.put(`/api/government/collars/${id}`, data),
|
||||
delete: (id) => instance.delete(`/api/government/collars/${id}`)
|
||||
}
|
||||
```
|
||||
|
||||
## 修复后的路径映射
|
||||
|
||||
| 前端调用 | 生产环境URL | nginx匹配 | 后端路由 | 状态 |
|
||||
|---------|------------|----------|---------|------|
|
||||
| `/api/government/departments` | `https://ad.ningmuyun.com/api/government/departments` | `^~ /api/government/` | `/api/government/departments` | ✅ 正确 |
|
||||
| `/api/government/positions` | `https://ad.ningmuyun.com/api/government/positions` | `^~ /api/government/` | `/api/government/positions` | ✅ 正确 |
|
||||
| `/api/government/farmers` | `https://ad.ningmuyun.com/api/government/farmers` | `^~ /api/government/` | `/api/government/farmers` | ✅ 正确 |
|
||||
|
||||
## 验证步骤
|
||||
|
||||
1. **重新构建前端项目**:
|
||||
```bash
|
||||
cd government-admin
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. **部署到生产环境**:
|
||||
- 将构建后的文件部署到服务器
|
||||
- 确保nginx配置正确
|
||||
|
||||
3. **测试API接口**:
|
||||
```bash
|
||||
# 测试岗位接口
|
||||
curl https://ad.ningmuyun.com/api/government/positions
|
||||
|
||||
# 测试部门接口
|
||||
curl https://ad.ningmuyun.com/api/government/departments
|
||||
```
|
||||
|
||||
## 相关文件
|
||||
- `government-admin/src/utils/api.js` - 前端API配置文件
|
||||
- `government-backend/_etc_nginx_conf.d_ningmuyun_one.conf` - nginx配置文件
|
||||
|
||||
## 修复时间
|
||||
2024年12月19日
|
||||
|
||||
## 修复状态
|
||||
✅ 已修复 - 前端API配置已更新,添加了正确的 `/api` 前缀
|
||||
@@ -1,149 +0,0 @@
|
||||
# 检查 Nginx 配置的关键步骤
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
根据您的反馈:
|
||||
- 修改 nginx 配置后,所有接口都返回 404
|
||||
- 只有登录接口正常(`/api/government/auth/login`)
|
||||
- 重复路径可以正常工作(`/api/government/government/departments`)
|
||||
|
||||
这说明:
|
||||
1. Nginx 已经重启并读取了新配置
|
||||
2. `/api/government/auth/` 规则工作正常
|
||||
3. `/api/government/` 规则可能有问题
|
||||
|
||||
## 🎯 关键问题
|
||||
|
||||
**重复路径能工作说明了什么?**
|
||||
|
||||
如果 `/api/government/government/departments` 能返回 200,说明:
|
||||
- 请求到达了 nginx
|
||||
- Nginx 将请求代理到了后端
|
||||
- 后端处理了 `/api/government/departments` 路径(去掉了一个 government)
|
||||
|
||||
这意味着当前的 proxy_pass 配置可能是:
|
||||
```nginx
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
```
|
||||
|
||||
这会导致:
|
||||
- 请求:`/api/government/government/departments`
|
||||
- Nginx 匹配:`location ^~ /api/government/`
|
||||
- 代理到:`http://localhost:5352/api/government/ + government/departments`
|
||||
- 实际请求:`http://localhost:5352/api/government/government/departments`
|
||||
|
||||
但是后端路由是 `/api/government/departments`,所以单个 government 的路径会 404。
|
||||
|
||||
## 🔧 正确的解决方案
|
||||
|
||||
需要修改 `proxy_pass` 配置,去掉路径重写:
|
||||
|
||||
```nginx
|
||||
# 错误的配置(当前)
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
# 这会导致路径重复:/api/government/departments → http://localhost:5352/api/government/departments
|
||||
}
|
||||
|
||||
# 正确的配置
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352;
|
||||
# 这会保持原始路径:/api/government/departments → http://localhost:5352/api/government/departments
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 修改步骤
|
||||
|
||||
### 1. 修改 nginx 配置文件
|
||||
|
||||
找到 `_etc_nginx_conf.d_ningmuyun_one.conf` 文件中的这一段:
|
||||
|
||||
```nginx
|
||||
# 政府API代理 - 处理其他政府相关接口
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/; # ❌ 错误
|
||||
# ... 其他配置
|
||||
}
|
||||
```
|
||||
|
||||
修改为:
|
||||
|
||||
```nginx
|
||||
# 政府API代理 - 处理其他政府相关接口
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352; # ✅ 正确
|
||||
# ... 其他配置
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 重启 nginx
|
||||
|
||||
```bash
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### 3. 验证修复
|
||||
|
||||
```bash
|
||||
# 应该返回 200
|
||||
curl -X GET https://ad.ningmuyun.com/api/government/departments
|
||||
|
||||
# 应该返回 404(因为路径不再重复)
|
||||
curl -X GET https://ad.ningmuyun.com/api/government/government/departments
|
||||
```
|
||||
|
||||
## 🎯 proxy_pass 尾部斜杠的区别
|
||||
|
||||
这是一个非常重要的 nginx 配置细节:
|
||||
|
||||
### 有尾部斜杠
|
||||
```nginx
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
}
|
||||
```
|
||||
- 请求:`/api/government/departments`
|
||||
- 匹配部分:`/api/government/`
|
||||
- 剩余部分:`departments`
|
||||
- 代理到:`http://localhost:5352/api/government/departments`
|
||||
|
||||
### 无尾部斜杠
|
||||
```nginx
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352;
|
||||
}
|
||||
```
|
||||
- 请求:`/api/government/departments`
|
||||
- 代理到:`http://localhost:5352/api/government/departments`(保持完整路径)
|
||||
|
||||
## 📊 当前配置应该是
|
||||
|
||||
```nginx
|
||||
# 政府认证API代理
|
||||
location ^~ /api/government/auth/ {
|
||||
proxy_pass http://localhost:5352/api/auth/; # ✅ 正确(需要去掉 government)
|
||||
# ... 其他配置
|
||||
}
|
||||
|
||||
# 政府API代理
|
||||
location ^~ /api/government/ {
|
||||
proxy_pass http://localhost:5352; # ✅ 正确(保持完整路径)
|
||||
# ... 其他配置
|
||||
}
|
||||
```
|
||||
|
||||
## 🚨 总结
|
||||
|
||||
修改配置文件,将:
|
||||
```nginx
|
||||
proxy_pass http://localhost:5352/api/government/;
|
||||
```
|
||||
|
||||
改为:
|
||||
```nginx
|
||||
proxy_pass http://localhost:5352;
|
||||
```
|
||||
|
||||
然后重启 nginx,问题应该就能解决了。
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# 政府端登录接口404错误修复说明
|
||||
|
||||
## 问题描述
|
||||
- **错误URL**: `https://ad.ningmuyun.com/api/government/auth/login`
|
||||
- **错误状态**: 404 Not Found
|
||||
- **影响范围**: 政府端管理系统登录功能
|
||||
|
||||
## 问题根因分析
|
||||
|
||||
### 1. 前端API调用路径
|
||||
- **前端调用**: `https://ad.ningmuyun.com/api/government/auth/login`
|
||||
- **API定义**: `government-admin/src/utils/api.js` 第74行
|
||||
```javascript
|
||||
login: (data) => instance.post('/auth/login', data)
|
||||
```
|
||||
- **baseURL**: `http://localhost:5352/api` (开发环境)
|
||||
- **实际请求**: `http://localhost:5352/api/auth/login`
|
||||
|
||||
### 2. 后端路由配置 ✅
|
||||
- **认证路由**: `government-backend/routes/auth.js` 第6行
|
||||
```javascript
|
||||
router.post('/login', login)
|
||||
```
|
||||
- **应用路由注册**: `government-backend/app.js` 第39行
|
||||
```javascript
|
||||
app.use('/api/auth', require('./routes/auth'));
|
||||
```
|
||||
- **完整路径**: `/api/auth/login`
|
||||
|
||||
### 3. Nginx配置问题 ❌
|
||||
**问题所在**: nginx配置中缺少政府认证API的路径匹配
|
||||
|
||||
**原始配置问题**:
|
||||
- 只有 `/api/government/` 的代理配置
|
||||
- 缺少 `/api/government/auth/` 的专门代理配置
|
||||
- 导致 `/api/government/auth/login` 请求无法正确路由到后端的 `/api/auth/login`
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 修复nginx配置
|
||||
在 `government-backend/_etc_nginx_conf.d_ningmuyun_one.conf` 中添加政府认证API代理配置:
|
||||
|
||||
```nginx
|
||||
# 政府认证API代理 - 处理登录等认证接口
|
||||
location ^~ /api/government/auth/ {
|
||||
proxy_pass http://localhost:5352/api/auth/; # 政府后端认证服务端口
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# CORS配置
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' 'https://ad.ningmuyun.com';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With';
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Content-Type' 'text/plain; charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 路径映射说明
|
||||
- **前端请求**: `/api/government/auth/login`
|
||||
- **nginx匹配**: `location ^~ /api/government/auth/`
|
||||
- **代理转发**: `http://localhost:5352/api/auth/login`
|
||||
- **后端处理**: `/api/auth/login` (authController.login)
|
||||
|
||||
## 验证步骤
|
||||
|
||||
1. **重启nginx服务**:
|
||||
```bash
|
||||
sudo nginx -t # 检查配置语法
|
||||
sudo systemctl reload nginx # 重新加载配置
|
||||
```
|
||||
|
||||
2. **测试登录接口**:
|
||||
```bash
|
||||
curl -X POST https://ad.ningmuyun.com/api/government/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"test","password":"test"}'
|
||||
```
|
||||
|
||||
3. **检查前端登录功能**:
|
||||
- 访问政府端管理系统登录页面
|
||||
- 输入正确的用户名和密码
|
||||
- 确认登录成功
|
||||
|
||||
## 相关文件
|
||||
- `government-backend/_etc_nginx_conf.d_ningmuyun_one.conf` - nginx配置文件
|
||||
- `government-backend/routes/auth.js` - 认证路由
|
||||
- `government-backend/controllers/authController.js` - 认证控制器
|
||||
- `government-admin/src/utils/api.js` - 前端API配置
|
||||
- `government-admin/src/stores/auth.js` - 前端认证状态管理
|
||||
|
||||
## 修复时间
|
||||
2024年12月19日
|
||||
|
||||
## 修复状态
|
||||
✅ 已修复 - nginx配置已更新,添加了政府认证API代理配置
|
||||
|
||||
## 重要说明
|
||||
**配置优先级**: 在nginx中,更具体的location规则会优先匹配。因此:
|
||||
- `/api/government/auth/` 配置必须在 `/api/government/` 配置之前
|
||||
- 这样 `/api/government/auth/login` 会匹配到第一个规则,正确代理到 `/api/auth/login`
|
||||
- 其他 `/api/government/` 开头的请求会匹配到第二个规则
|
||||
|
||||
## 测试方法
|
||||
运行测试脚本验证修复效果:
|
||||
```bash
|
||||
cd government-backend
|
||||
node test-login-api.js
|
||||
```
|
||||
|
||||
## 重启nginx命令
|
||||
```bash
|
||||
sudo nginx -t # 检查配置语法
|
||||
sudo systemctl reload nginx # 重新加载配置
|
||||
```
|
||||
Reference in New Issue
Block a user