补充修改

This commit is contained in:
2025-10-11 08:53:47 +08:00
parent 1a1abf4c26
commit 9b8d177e34
34 changed files with 391 additions and 1882 deletions

View File

@@ -338,7 +338,7 @@ const routes = [
]
const router = createRouter({
history: createWebHistory(),
history: createWebHistory('/government/'), // 设置基础路径
routes
})

View File

@@ -123,10 +123,10 @@ const captchaUrl = ref('')
// 表单数据
const formData = reactive({
username: 'admin',
password: '123456',
username: '',
password: '',
captcha: '',
remember: true
remember: false
})
// 表单验证规则
@@ -212,20 +212,7 @@ onMounted(() => {
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(120, 119, 198, 0.2) 0%, transparent 50%);
}
background: #f5f5f5;
.background-overlay {
position: absolute;
@@ -233,7 +220,7 @@ onMounted(() => {
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
background: rgba(0, 0, 0, 0.02);
}
}

View File

@@ -1,65 +0,0 @@
// 测试行政人员管理API接口
import axios from 'axios';
// 创建axios实例
const instance = axios.create({
baseURL: 'http://localhost:5352/api',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
// 登录获取token
const login = async () => {
try {
const response = await instance.post('/auth/login', {
username: 'admin',
password: '123456'
});
console.log('登录成功获取到token');
return response.data.token;
} catch (error) {
console.error('登录失败:', error.message);
throw error;
}
};
// 测试获取行政人员列表
const testGetAdminStaffList = async (token) => {
try {
instance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
const response = await instance.get('/personnel');
console.log('\n获取行政人员列表成功:');
console.log('- 状态码:', response.status);
console.log('- 返回数据结构:', Object.keys(response.data));
console.log('- 行政人员总数:', response.data.total);
console.log('- 返回的行政人员列表长度:', response.data.data.length);
if (response.data.data.length > 0) {
console.log('- 第一条行政人员数据:', response.data.data[0]);
}
return response.data;
} catch (error) {
console.error('获取行政人员列表失败:', error.message);
throw error;
}
};
// 主测试函数
const runTests = async () => {
console.log('开始测试行政人员管理API...');
try {
// 1. 登录获取token
const token = await login();
// 2. 测试获取行政人员列表
await testGetAdminStaffList(token);
console.log('\n所有测试完成');
} catch (error) {
console.error('测试失败:', error);
}
};
// 运行测试
runTests();

View File

@@ -1,152 +0,0 @@
// 前端组件API测试脚本 - ES模块格式
import axios from 'axios';
// 创建axios实例
const instance = axios.create({
baseURL: 'http://localhost:5352/api',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
});
// 登录获取token
async function login() {
try {
const response = await instance.post('/auth/login', {
username: 'admin',
password: '123456'
});
console.log('登录成功:', response.data);
// 修正token获取路径 - 正确路径是response.data.data.token
return response.data.data?.token || null;
} catch (error) {
console.error('登录失败:', error);
console.error('错误详情:', error.response?.data || error.message);
return null;
}
}
// 测试获取行政人员列表
async function testGetAdminStaffList(token) {
try {
const response = await instance.get('/personnel', {
headers: {
'Authorization': `Bearer ${token}`
},
params: {
page: 1,
pageSize: 10
}
});
console.log('行政人员列表获取成功:');
console.log('- 数据结构:', Object.keys(response.data));
console.log('- 行政人员总数:', response.data.total);
console.log('- 行政人员列表数据长度:', response.data.data?.length || 0);
if (response.data.data && response.data.data.length > 0) {
console.log('- 第一条数据示例:', response.data.data[0]);
}
return response.data;
} catch (error) {
console.error('行政人员列表获取失败:', error);
console.error('错误详情:', error.response?.data || error.message);
return null;
}
}
// 测试获取部门列表
async function testGetDepartmentsList(token) {
try {
const response = await instance.get('/government/departments', {
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('部门列表获取成功:');
console.log('- 数据结构:', Object.keys(response.data));
console.log('- 部门列表数据长度:', response.data.data?.length || 0);
if (response.data.data && response.data.data.length > 0) {
console.log('- 第一条数据示例:', response.data.data[0]);
}
return response.data;
} catch (error) {
console.error('部门列表获取失败:', error);
console.error('错误详情:', error.response?.data || error.message);
return null;
}
}
// 测试获取岗位列表
async function testGetPositionsList(token) {
try {
const response = await instance.get('/government/positions', {
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('岗位列表获取成功:');
console.log('- 数据结构:', Object.keys(response.data));
console.log('- 岗位列表数据长度:', response.data.data?.length || 0);
if (response.data.data && response.data.data.length > 0) {
console.log('- 第一条数据示例:', response.data.data[0]);
}
return response.data;
} catch (error) {
console.error('岗位列表获取失败:', error);
console.error('错误详情:', error.response?.data || error.message);
return null;
}
}
// 主测试函数 - 模拟AdminStaff组件的初始化流程
async function runComponentTest() {
console.log('开始模拟AdminStaff组件初始化测试...');
// 1. 登录获取token
console.log('\n1. 登录认证');
const token = await login();
if (!token) {
console.error('测试失败: 无法获取登录token');
return;
}
// 2. 测试获取部门列表 - 对应组件中的fetchDepartments()
console.log('\n2. 获取部门列表');
const departmentsData = await testGetDepartmentsList(token);
// 3. 测试获取岗位列表 - 对应组件中的fetchPositions()
console.log('\n3. 获取岗位列表');
const positionsData = await testGetPositionsList(token);
// 4. 测试获取行政人员列表 - 对应组件中的fetchAdminStaffList()
console.log('\n4. 获取行政人员列表');
const staffListData = await testGetAdminStaffList(token);
console.log('\n测试完成!');
console.log('----------------------------------------');
console.log('测试结果总结:');
console.log('- 登录:', token ? '成功' : '失败');
console.log('- 部门列表:', departmentsData ? '成功' : '失败');
console.log('- 岗位列表:', positionsData ? '成功' : '失败');
console.log('- 行政人员列表:', staffListData ? '成功' : '失败');
// 分析可能的组件渲染问题
if (staffListData && departmentsData && positionsData) {
console.log('\n所有API调用成功但页面仍显示空白可能的原因:');
console.log('1. 数据格式不匹配 - 检查返回数据结构是否与组件期望的一致');
console.log('2. 组件生命周期问题 - 检查onMounted中是否正确调用initData()');
console.log('3. 数据处理逻辑错误 - 检查staffData.value的赋值和转换逻辑');
console.log('4. 权限问题 - 检查用户角色和权限是否正确');
console.log('5. 前端控制台错误 - 检查浏览器控制台是否有详细错误信息');
} else {
console.log('\nAPI调用失败是页面空白的可能原因请检查:');
console.log('1. 后端接口是否正确实现');
console.log('2. 认证token是否有效');
console.log('3. 网络连接是否正常');
}
}
// 运行测试
runComponentTest().catch(err => {
console.error('测试过程中发生错误:', err);
});

View File

@@ -1,52 +0,0 @@
// 从前端目录测试API访问
const axios = require('axios');
// 创建axios实例使用与前端相同的配置
const api = axios.create({
baseURL: 'http://localhost:5352/api',
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
});
async function testApi() {
try {
console.log('开始从前端目录测试API...');
// 测试行政人员列表API
console.log('\n测试行政人员列表API:');
const adminStaffResponse = await api.get('/government/admin-staff');
console.log(`✅ 行政人员列表API调用成功返回${adminStaffResponse.data.length}条数据`);
// 测试部门列表API
console.log('\n测试部门列表API:');
const departmentResponse = await api.get('/government/departments');
console.log(`✅ 部门列表API调用成功返回${departmentResponse.data.length}条数据`);
// 测试岗位列表API
console.log('\n测试岗位列表API:');
const positionResponse = await api.get('/government/positions');
console.log(`✅ 岗位列表API调用成功返回${positionResponse.data.length}条数据`);
// 测试带有查询参数的API
console.log('\n测试带查询参数的API:');
const filteredResponse = await api.get('/government/admin-staff?page=1&pageSize=3');
console.log(`✅ 带查询参数的API调用成功返回${filteredResponse.data.length}条数据`);
console.log('\n✅ 所有API测试成功完成');
} catch (error) {
console.error('❌ API测试失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
} else if (error.request) {
console.error('没有收到响应:', error.request);
} else {
console.error('请求配置错误:', error.message);
}
console.error('错误详情:', error);
}
}
testApi();

View File

@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/svg+xml" href="/vite.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TextArea 测试页面</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/test-main.js"></script>
</body>
</html>

View File

@@ -1,86 +0,0 @@
// 测试前端认证修复效果的脚本
import axios from 'axios';
import fs from 'fs';
import path from 'path';
// 配置
const BASE_URL = 'http://localhost:5352/api';
const USERNAME = 'admin';
const PASSWORD = '123456';
// 测试函数
async function runTest() {
console.log('===== 开始测试智慧耳标页面认证问题 =====');
try {
// 1. 尝试登录获取token
console.log('1. 尝试登录...');
const loginResponse = await axios.post(`${BASE_URL}/auth/login`, {
username: USERNAME,
password: PASSWORD
});
if (loginResponse.data && loginResponse.data.token) {
const token = loginResponse.data.token;
console.log('登录成功获取到token:', token);
// 2. 使用获取的token尝试访问智能耳标API
console.log('2. 使用token访问智能耳标API...');
const headers = { 'Authorization': `Bearer ${token}` };
const smartEarmarkResponse = await axios.get(`${BASE_URL}/smart-earmark`, { headers });
console.log('智能耳标API访问成功返回状态:', smartEarmarkResponse.status);
console.log('返回数据示例:', JSON.stringify(smartEarmarkResponse.data.slice(0, 1), null, 2));
console.log('\n===== 测试成功!智慧耳标页面认证问题已修复 =====');
} else {
console.error('登录失败未获取到token:', loginResponse.data);
// 如果后端使用模拟数据我们也创建一个模拟token来测试
console.log('\n3. 尝试使用模拟token访问API适用于前端模拟登录场景...');
const mockToken = 'mock-jwt-token-' + Date.now();
const headers = { 'Authorization': `Bearer ${mockToken}` };
try {
const smartEarmarkResponse = await axios.get(`${BASE_URL}/smart-earmark`, {
headers,
timeout: 5000
});
console.log('使用模拟token访问成功状态:', smartEarmarkResponse.status);
} catch (error) {
console.error('使用模拟token访问失败:', error.code || error.message);
if (error.response) {
console.error('错误详情:', error.response.status, error.response.data);
}
// 记录问题以便后续分析
const errorInfo = {
timestamp: new Date().toISOString(),
error: error.message,
response: error.response ? {
status: error.response.status,
data: error.response.data
} : null
};
fs.writeFileSync(
path.join(__dirname, 'auth_error.log'),
JSON.stringify(errorInfo, null, 2) + '\n',
{ flag: 'a' }
);
}
}
} catch (error) {
console.error('测试过程中发生错误:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误详情:', error.response.data);
} else if (error.request) {
console.error('未收到响应:', error.request);
console.error('请检查后端服务是否正常运行在端口5352');
}
}
}
// 运行测试
runTest();

View File

@@ -1,66 +0,0 @@
// 简化的测试脚本专门验证智慧耳标API访问
import axios from 'axios';
// 配置
const API_BASE_URL = 'http://localhost:5352/api';
const TEST_USERNAME = 'admin';
const TEST_PASSWORD = '123456';
// 创建axios实例
const apiClient = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// 测试函数
async function testEarmarkApi() {
try {
console.log('===== 开始测试智慧耳标API =====');
// 1. 尝试登录获取真实token
console.log('1. 登录获取token...');
const loginResponse = await apiClient.post('/auth/login', {
username: TEST_USERNAME,
password: TEST_PASSWORD
});
if (loginResponse.status === 200 && loginResponse.data.code === 200) {
const token = loginResponse.data.data.token;
console.log('登录成功获取到token');
// 2. 使用获取的token访问智慧耳标API
console.log('2. 使用token访问智慧耳标API...');
apiClient.defaults.headers.common['Authorization'] = `Bearer ${token}`;
const earmarkResponse = await apiClient.get('/smart-earmark');
if (earmarkResponse.status === 200) {
console.log('智慧耳标API访问成功');
console.log('响应状态码:', earmarkResponse.status);
console.log('数据总量:', earmarkResponse.data.data?.length || '无数据');
console.log('\n===== 测试成功 =====');
console.log('修复总结:');
console.log('1. 前端修复了api.js中缺失的message组件导入');
console.log('2. 前端修复了authStore中认证状态判断问题');
console.log('3. 后端修复了auth.js中JWT验证相关的导入问题');
console.log('4. 后端:修复了重复声明的变量问题');
console.log('\n结论点击智慧耳标页面自动退出到登录页的问题已解决');
} else {
console.error('智慧耳标API访问失败状态码:', earmarkResponse.status);
}
} else {
console.error('登录失败:', loginResponse.data?.message || '未知错误');
}
} catch (error) {
console.error('测试过程中发生错误:', error.message);
if (error.response) {
console.error('错误详情:', error.response.status, error.response.data);
}
}
}
// 运行测试
testEarmarkApi();

View File

@@ -4,6 +4,7 @@ import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
base: '/government/', // 设置基础路径
resolve: {
alias: {
'@': '/src',
@@ -18,5 +19,18 @@ export default defineConfig({
changeOrigin: true
}
}
},
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'ant-design-vue'],
echarts: ['echarts', 'vue-echarts']
}
}
}
}
})

View File

@@ -1,18 +0,0 @@
// 直接检查slaughter路由模块的导出内容
const slaughterRoutes = require('./routes/slaughter');
console.log('模块类型:', typeof slaughterRoutes);
console.log('是否为Express Router:', slaughterRoutes && slaughterRoutes.constructor && slaughterRoutes.constructor.name);
console.log('是否有stack属性:', 'stack' in slaughterRoutes);
if (slaughterRoutes && slaughterRoutes.stack) {
console.log('stack长度:', slaughterRoutes.stack.length);
slaughterRoutes.stack.forEach((layer, index) => {
console.log(`Layer ${index}:`, layer);
});
}
// 也检查另一个已知正常的路由模块比如auth.js
const authRoutes = require('./routes/auth');
console.log('\nauth路由模块类型:', typeof authRoutes);
console.log('auth路由模块构造函数:', authRoutes && authRoutes.constructor && authRoutes.constructor.name);

View File

@@ -1,31 +0,0 @@
// 测试HarmlessPlace模型的导出和方法
const HarmlessPlace = require('./models/HarmlessPlace');
const User = require('./models/User');
console.log('=== 检查HarmlessPlace模型 ===');
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
console.log('HarmlessPlace是否为对象:', typeof HarmlessPlace === 'object' && HarmlessPlace !== null);
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
if (HarmlessPlace.findAndCountAll) {
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
}
console.log('\nHarmlessPlace对象的所有属性和方法:');
console.log(Object.keys(HarmlessPlace));
console.log('\n=== 检查User模型作为对比===');
console.log('User的类型:', typeof User);
console.log('User是否为对象:', typeof User === 'object' && User !== null);
console.log('User是否有findAndCountAll方法:', typeof User.findAndCountAll !== 'undefined');
if (User.findAndCountAll) {
console.log('findAndCountAll的类型:', typeof User.findAndCountAll);
}
console.log('\nUser对象的所有属性和方法:');
console.log(Object.keys(User));
// 检查是否存在循环引用或其他问题
console.log('\n=== 检查模型实例化 ===');
try {
console.log('尝试实例化HarmlessPlace:', new HarmlessPlace());
} catch (error) {
console.log('实例化HarmlessPlace错误:', error.message);
}

View File

@@ -1,6 +1,6 @@
const DeviceWarning = require('../models/DeviceWarning');
const { Op, fn, col } = require('sequelize');
const sequelize = require('../config/database');
const { QueryTypes } = require('sequelize');
// 获取设备预警列表
exports.getDeviceWarnings = async (req, res) => {
@@ -9,25 +9,52 @@ exports.getDeviceWarnings = async (req, res) => {
const limit = parseInt(pageSize);
const offset = (parseInt(page) - 1) * limit;
const where = {};
// 构建WHERE条件
let whereConditions = [];
let whereParams = {};
if (deviceType) {
where.deviceType = deviceType;
whereConditions.push('deviceType = :deviceType');
whereParams.deviceType = deviceType;
}
if (alertType) {
where.alertType = alertType;
whereConditions.push('alertType = :alertType');
whereParams.alertType = alertType;
}
if (status) {
where.status = status;
whereConditions.push('status = :status');
whereParams.status = status;
}
if (farmerName) {
where.farmerName = { [Op.like]: `%${farmerName}%` };
whereConditions.push('farmerName LIKE :farmerName');
whereParams.farmerName = `%${farmerName}%`;
}
const { count, rows } = await DeviceWarning.findAndCountAll({
where,
limit,
offset,
order: [['alertTime', 'DESC']],
const whereClause = whereConditions.length > 0 ? 'WHERE ' + whereConditions.join(' AND ') : '';
// 查询总数
const countQuery = `SELECT COUNT(*) as count FROM device_warnings ${whereClause}`;
const countResult = await DeviceWarning.sequelize.query(countQuery, {
replacements: whereParams,
type: QueryTypes.SELECT
});
const total = countResult[0].count;
// 查询数据
const dataQuery = `
SELECT id, farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel, alertTime, status, description,
location, batteryLevel, signalStrength, temperature,
resolvedBy, resolvedAt, remarks, createdAt, updatedAt
FROM device_warnings
${whereClause}
ORDER BY alertTime DESC
LIMIT :limit OFFSET :offset
`;
const rows = await DeviceWarning.sequelize.query(dataQuery, {
replacements: { ...whereParams, limit, offset },
type: QueryTypes.SELECT
});
res.status(200).json({
@@ -35,7 +62,7 @@ exports.getDeviceWarnings = async (req, res) => {
message: '获取成功',
data: {
list: rows,
total: count,
total: total,
page: parseInt(page),
pageSize: limit,
},
@@ -50,13 +77,26 @@ exports.getDeviceWarnings = async (req, res) => {
exports.getDeviceWarningById = async (req, res) => {
try {
const { id } = req.params;
const warning = await DeviceWarning.findByPk(id);
const query = `
SELECT id, farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel, alertTime, status, description,
location, batteryLevel, signalStrength, temperature,
resolvedBy, resolvedAt, remarks, createdAt, updatedAt
FROM device_warnings
WHERE id = :id
`;
const results = await DeviceWarning.sequelize.query(query, {
replacements: { id },
type: QueryTypes.SELECT
});
if (!warning) {
if (results.length === 0) {
return res.status(404).json({ code: 404, message: '设备预警未找到' });
}
res.status(200).json({ code: 200, message: '获取成功', data: warning });
res.status(200).json({ code: 200, message: '获取成功', data: results[0] });
} catch (error) {
console.error('获取设备预警详情失败:', error);
res.status(500).json({ code: 500, message: '获取设备预警详情失败', error: error.message });
@@ -66,8 +106,53 @@ exports.getDeviceWarningById = async (req, res) => {
// 创建新的设备预警
exports.createDeviceWarning = async (req, res) => {
try {
const newWarning = await DeviceWarning.create(req.body);
res.status(201).json({ code: 201, message: '创建成功', data: newWarning });
const {
farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel = 'medium', description, location, batteryLevel,
signalStrength, temperature, remarks
} = req.body;
const insertQuery = `
INSERT INTO device_warnings
(farmName, farmerName, phone, deviceType, deviceNumber, alertType, alertLevel,
description, location, batteryLevel, signalStrength, temperature, remarks,
alertTime, status, createdAt, updatedAt)
VALUES
(:farmName, :farmerName, :phone, :deviceType, :deviceNumber, :alertType, :alertLevel,
:description, :location, :batteryLevel, :signalStrength, :temperature, :remarks,
NOW(), 'active', NOW(), NOW())
`;
await DeviceWarning.sequelize.query(insertQuery, {
replacements: {
farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel,
description: description || null,
location: location || null,
batteryLevel: batteryLevel || null,
signalStrength: signalStrength || null,
temperature: temperature || null,
remarks: remarks || null
},
type: QueryTypes.INSERT
});
// 获取刚插入的记录
const selectQuery = `
SELECT id, farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel, alertTime, status, description,
location, batteryLevel, signalStrength, temperature,
resolvedBy, resolvedAt, remarks, createdAt, updatedAt
FROM device_warnings
ORDER BY id DESC
LIMIT 1
`;
const results = await DeviceWarning.sequelize.query(selectQuery, {
type: QueryTypes.SELECT
});
res.status(201).json({ code: 201, message: '创建成功', data: results[0] });
} catch (error) {
console.error('创建设备预警失败:', error);
res.status(500).json({ code: 500, message: '创建设备预警失败', error: error.message });
@@ -78,16 +163,60 @@ exports.createDeviceWarning = async (req, res) => {
exports.updateDeviceWarning = async (req, res) => {
try {
const { id } = req.params;
const [updatedRows] = await DeviceWarning.update(req.body, {
where: { id },
const updateFields = [];
const replacements = { id };
// 动态构建更新字段
const allowedFields = [
'farmName', 'farmerName', 'phone', 'deviceType', 'deviceNumber',
'alertType', 'alertLevel', 'description', 'location', 'batteryLevel',
'signalStrength', 'temperature', 'remarks', 'status', 'resolvedBy', 'resolvedAt'
];
for (const field of allowedFields) {
if (req.body[field] !== undefined) {
updateFields.push(`${field} = :${field}`);
replacements[field] = req.body[field];
}
}
if (updateFields.length === 0) {
return res.status(400).json({ code: 400, message: '没有需要更新的字段' });
}
updateFields.push('updatedAt = NOW()');
const updateQuery = `
UPDATE device_warnings
SET ${updateFields.join(', ')}
WHERE id = :id
`;
const [result] = await DeviceWarning.sequelize.query(updateQuery, {
replacements,
type: QueryTypes.UPDATE
});
if (updatedRows === 0) {
if (result === 0) {
return res.status(404).json({ code: 404, message: '设备预警未找到或无更新' });
}
const updatedWarning = await DeviceWarning.findByPk(id);
res.status(200).json({ code: 200, message: '更新成功', data: updatedWarning });
// 获取更新后的记录
const selectQuery = `
SELECT id, farmName, farmerName, phone, deviceType, deviceNumber,
alertType, alertLevel, alertTime, status, description,
location, batteryLevel, signalStrength, temperature,
resolvedBy, resolvedAt, remarks, createdAt, updatedAt
FROM device_warnings
WHERE id = :id
`;
const results = await DeviceWarning.sequelize.query(selectQuery, {
replacements: { id },
type: QueryTypes.SELECT
});
res.status(200).json({ code: 200, message: '更新成功', data: results[0] });
} catch (error) {
console.error('更新设备预警失败:', error);
res.status(500).json({ code: 500, message: '更新设备预警失败', error: error.message });
@@ -98,11 +227,14 @@ exports.updateDeviceWarning = async (req, res) => {
exports.deleteDeviceWarning = async (req, res) => {
try {
const { id } = req.params;
const deletedRows = await DeviceWarning.destroy({
where: { id },
const deleteQuery = 'DELETE FROM device_warnings WHERE id = :id';
const [result] = await DeviceWarning.sequelize.query(deleteQuery, {
replacements: { id },
type: QueryTypes.DELETE
});
if (deletedRows === 0) {
if (result === 0) {
return res.status(404).json({ code: 404, message: '设备预警未找到' });
}
@@ -141,32 +273,27 @@ exports.updateWarningStatus = async (req, res) => {
// 获取预警统计
exports.getWarningStats = async (req, res) => {
try {
// 分别查询每种设备类型的活跃预警数量
const earTagCount = await DeviceWarning.count({
where: {
deviceType: '智能耳标',
status: 'active'
}
// 使用原始SQL查询每种设备类型的活跃预警数量
const earTagQuery = 'SELECT COUNT(*) as count FROM device_warnings WHERE deviceType = :deviceType AND status = :status';
const earTagResult = await DeviceWarning.sequelize.query(earTagQuery, {
replacements: { deviceType: '智能耳标', status: 'active' },
type: QueryTypes.SELECT
});
const neckbandCount = await DeviceWarning.count({
where: {
deviceType: '智能项圈',
status: 'active'
}
const neckbandResult = await DeviceWarning.sequelize.query(earTagQuery, {
replacements: { deviceType: '智能项圈', status: 'active' },
type: QueryTypes.SELECT
});
const hostCount = await DeviceWarning.count({
where: {
deviceType: '智能主机',
status: 'active'
}
const hostResult = await DeviceWarning.sequelize.query(earTagQuery, {
replacements: { deviceType: '智能主机', status: 'active' },
type: QueryTypes.SELECT
});
const result = {
earTag: earTagCount,
neckband: neckbandCount,
host: hostCount
earTag: earTagResult[0].count,
neckband: neckbandResult[0].count,
host: hostResult[0].count
};
res.status(200).json({ code: 200, message: '获取成功', data: result });

View File

@@ -1,96 +0,0 @@
// 完整模型测试脚本
const sequelize = require('./config/database');
// 确保先导入所有依赖模型
const Department = require('./models/Department');
const Position = require('./models/Position');
const AdminStaff = require('./models/AdminStaff');
async function fullModelTest() {
try {
console.log('开始完整模型测试...');
// 测试数据库连接
await sequelize.authenticate();
console.log('✅ 数据库连接成功');
// 检查模型是否被正确导入
console.log('\n检查模型导入状态:');
console.log('Department 模型:', Department ? '✅ 已导入' : '❌ 未导入');
console.log('Position 模型:', Position ? '✅ 已导入' : '❌ 未导入');
console.log('AdminStaff 模型:', AdminStaff ? '✅ 已导入' : '❌ 未导入');
// 测试基本的查询功能
console.log('\n测试基本查询功能:');
// 查询部门表
console.log('\n查询部门表:');
try {
const departments = await Department.findAll({ limit: 5 });
console.log(`找到 ${departments.length} 个部门`);
if (departments.length > 0) {
console.log('示例部门:', departments[0].dataValues);
}
} catch (error) {
console.error('部门查询失败:', error.message);
}
// 查询岗位表
console.log('\n查询岗位表:');
try {
const positions = await Position.findAll({ limit: 5 });
console.log(`找到 ${positions.length} 个岗位`);
if (positions.length > 0) {
console.log('示例岗位:', positions[0].dataValues);
}
} catch (error) {
console.error('岗位查询失败:', error.message);
}
// 查询行政人员表
console.log('\n查询行政人员表:');
try {
const adminStaffs = await AdminStaff.findAll({ limit: 5 });
console.log(`找到 ${adminStaffs.length} 个行政人员`);
if (adminStaffs.length > 0) {
console.log('示例行政人员:', adminStaffs[0].dataValues);
}
} catch (error) {
console.error('行政人员查询失败:', error.message);
console.error('错误详情:', error);
}
// 测试关联查询
console.log('\n测试关联查询:');
try {
const adminStaffWithRelations = await AdminStaff.findAll({
include: [
{ model: Department, as: 'department' },
{ model: Position, as: 'position' }
],
limit: 1
});
console.log('关联查询结果数量:', adminStaffWithRelations.length);
if (adminStaffWithRelations.length > 0) {
console.log('关联查询成功,已获取到关联数据');
// 只打印部分数据以避免输出过多
const staff = adminStaffWithRelations[0];
console.log('姓名:', staff.name);
console.log('部门:', staff.department?.name || '未知');
console.log('岗位:', staff.position?.name || '未知');
}
} catch (error) {
console.error('关联查询失败:', error.message);
console.error('错误详情:', error);
}
console.log('\n✅ 完整模型测试完成');
} catch (error) {
console.error('❌ 完整模型测试失败:', error.message);
console.error('错误详情:', error);
} finally {
await sequelize.close();
}
}
fullModelTest();

View File

@@ -1,99 +0,0 @@
// 模型导入测试脚本
const sequelize = require('./config/database');
const { DataTypes } = require('sequelize');
async function modelImportTest() {
try {
console.log('开始模型导入测试...');
// 测试数据库连接
await sequelize.authenticate();
console.log('✅ 数据库连接成功');
// 测试直接导入模型
console.log('\n测试直接导入模型:');
// 先测试 Department 模型
console.log('\n测试 Department 模型导入:');
try {
const Department = require('./models/Department');
console.log('Department 模型导入:', Department ? '✅ 成功' : '❌ 失败');
// 测试 Department 模型的结构
if (Department) {
console.log('Department 模型是否有 define 方法:', typeof Department.define === 'function' ? '✅ 是' : '❌ 否');
console.log('Department 模型的 tableName:', Department.tableName || Department.options?.tableName || '未定义');
}
} catch (error) {
console.error('Department 模型导入失败:', error.message);
}
// 测试 Position 模型
console.log('\n测试 Position 模型导入:');
try {
const Position = require('./models/Position');
console.log('Position 模型导入:', Position ? '✅ 成功' : '❌ 失败');
// 测试 Position 模型的结构
if (Position) {
console.log('Position 模型是否有 define 方法:', typeof Position.define === 'function' ? '✅ 是' : '❌ 否');
console.log('Position 模型的 tableName:', Position.tableName || Position.options?.tableName || '未定义');
}
} catch (error) {
console.error('Position 模型导入失败:', error.message);
}
// 测试 AdminStaff 模型
console.log('\n测试 AdminStaff 模型导入:');
try {
// 先导入依赖模型
require('./models/Department');
require('./models/Position');
const AdminStaff = require('./models/AdminStaff');
console.log('AdminStaff 模型导入:', AdminStaff ? '✅ 成功' : '❌ 失败');
// 测试 AdminStaff 模型的结构
if (AdminStaff) {
console.log('AdminStaff 模型是否有 define 方法:', typeof AdminStaff.define === 'function' ? '✅ 是' : '❌ 否');
console.log('AdminStaff 模型的 tableName:', AdminStaff.tableName || AdminStaff.options?.tableName || '未定义');
}
} catch (error) {
console.error('AdminStaff 模型导入失败:', error.message);
console.error('错误详情:', error);
}
// 测试创建一个简单的新模型
console.log('\n测试创建新模型:');
try {
const TestModel = sequelize.define('TestModel', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false
}
}, {
tableName: 'test_models',
timestamps: false,
paranoid: false
});
console.log('新模型创建:', TestModel ? '✅ 成功' : '❌ 失败');
} catch (error) {
console.error('新模型创建失败:', error.message);
}
console.log('\n✅ 模型导入测试完成');
} catch (error) {
console.error('❌ 模型导入测试失败:', error.message);
console.error('错误详情:', error);
} finally {
await sequelize.close();
}
}
modelImportTest();

View File

@@ -1,5 +1,25 @@
const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');
const { DataTypes, Sequelize } = require('sequelize');
const config = require('../config/index.js');
// 创建专门的Sequelize实例不使用underscored
const sequelize = new Sequelize(
config.DB_CONFIG.database,
config.DB_CONFIG.user,
config.DB_CONFIG.password,
{
host: config.DB_CONFIG.host,
port: config.DB_CONFIG.port,
dialect: config.DB_CONFIG.dialect,
logging: console.log,
define: {
timestamps: true,
paranoid: false,
underscored: false, // 明确设置为false
freezeTableName: true
},
timezone: '+08:00'
}
);
const DeviceWarning = sequelize.define('DeviceWarning', {
id: {
@@ -67,34 +87,42 @@ const DeviceWarning = sequelize.define('DeviceWarning', {
description: {
type: DataTypes.TEXT,
comment: '预警描述',
field: 'description'
},
location: {
type: DataTypes.STRING,
comment: '设备位置',
field: 'location'
},
batteryLevel: {
type: DataTypes.INTEGER,
comment: '电池电量百分比',
field: 'batteryLevel'
},
signalStrength: {
type: DataTypes.INTEGER,
comment: '信号强度',
field: 'signalStrength'
},
temperature: {
type: DataTypes.FLOAT,
comment: '温度值',
field: 'temperature'
},
resolvedBy: {
type: DataTypes.STRING,
comment: '解决人',
field: 'resolvedBy'
},
resolvedAt: {
type: DataTypes.DATE,
comment: '解决时间',
field: 'resolvedAt'
},
remarks: {
type: DataTypes.TEXT,
comment: '备注',
field: 'remarks'
},
}, {
tableName: 'device_warnings',
@@ -102,6 +130,7 @@ const DeviceWarning = sequelize.define('DeviceWarning', {
createdAt: 'createdAt',
updatedAt: 'updatedAt',
paranoid: false,
underscored: false, // 覆盖全局配置,不使用下划线命名
});
module.exports = DeviceWarning;

View File

@@ -0,0 +1,119 @@
server {
listen 443 ssl http2;
server_name ad.ningmuyun.com;
# SSL证书配置需要替换为实际的证书路径
ssl_certificate /etc/ssl/certs/ad.ningmuyun.com.crt;
ssl_certificate_key /etc/ssl/private/ad.ningmuyun.com.key;
# SSL配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# 政府端前端静态文件
location /government/ {
alias /var/www/government-admin-system/dist/;
try_files $uri $uri/ /government/index.html;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# 政府端后端API代理
location /api/government/ {
proxy_pass http://127.0.0.1:5352/api/government/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
# CORS headers
add_header Access-Control-Allow-Origin https://ad.ningmuyun.com;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
add_header Access-Control-Allow-Credentials true;
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin https://ad.ningmuyun.com;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
add_header Access-Control-Allow-Credentials true;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
}
# 保险端前端静态文件
location /insurance/ {
alias /var/www/insurance-admin-system/dist/;
try_files $uri $uri/ /insurance/index.html;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# 保险端后端API代理
location /insurance/api/ {
proxy_pass http://127.0.0.1:3000/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
# CORS headers
add_header Access-Control-Allow-Origin https://ad.ningmuyun.com;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
add_header Access-Control-Allow-Credentials true;
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin https://ad.ningmuyun.com;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
add_header Access-Control-Allow-Credentials true;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
}
# 健康检查
location /health {
proxy_pass http://127.0.0.1:5352/health;
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;
}
# 根路径重定向到政府端
location = / {
return 301 /government/;
}
}
# HTTP重定向到HTTPS
server {
listen 80;
server_name ad.ningmuyun.com;
return 301 https://$server_name$request_uri;
}

View File

@@ -1,24 +0,0 @@
// 简洁地检查路由模块的基本信息
const express = require('express');
const slaughterRoutes = require('./routes/slaughter');
const authRoutes = require('./routes/auth');
console.log('=== slaughter路由模块 ===');
console.log('类型:', typeof slaughterRoutes);
console.log('构造函数:', slaughterRoutes && slaughterRoutes.constructor && slaughterRoutes.constructor.name);
console.log('是否有stack:', 'stack' in slaughterRoutes);
console.log('是否有get方法:', 'get' in slaughterRoutes);
console.log('\n=== auth路由模块 ===');
console.log('类型:', typeof authRoutes);
console.log('构造函数:', authRoutes && authRoutes.constructor && authRoutes.constructor.name);
console.log('是否有stack:', 'stack' in authRoutes);
console.log('是否有get方法:', 'get' in authRoutes);
// 创建一个新的Router实例进行比较
const newRouter = express.Router();
console.log('\n=== 新创建的Router实例 ===');
console.log('类型:', typeof newRouter);
console.log('构造函数:', newRouter && newRouter.constructor && newRouter.constructor.name);
console.log('是否有stack:', 'stack' in newRouter);
console.log('是否有get方法:', 'get' in newRouter);

View File

@@ -1,37 +0,0 @@
// 简单测试脚本
const sequelize = require('./config/database');
const { DataTypes } = require('sequelize');
async function simpleTest() {
try {
console.log('开始简单测试...');
// 测试数据库连接
await sequelize.authenticate();
console.log('✅ 数据库连接成功');
// 测试DataTypes是否可用
console.log('\n测试DataTypes:');
console.log('DataTypes.INTEGER:', DataTypes.INTEGER ? '✅ 可用' : '❌ 不可用');
console.log('DataTypes.STRING:', DataTypes.STRING ? '✅ 可用' : '❌ 不可用');
console.log('DataTypes.BOOLEAN:', DataTypes.BOOLEAN ? '✅ 可用' : '❌ 不可用');
// 测试sequelize实例是否可用
console.log('\n测试sequelize实例:');
console.log('sequelize实例:', sequelize ? '✅ 可用' : '❌ 不可用');
// 测试直接查询数据库
console.log('\n测试直接查询数据库:');
const [results] = await sequelize.query('SELECT 1+1 AS result');
console.log('查询结果:', results);
console.log('\n✅ 简单测试完成');
} catch (error) {
console.error('❌ 简单测试失败:', error.message);
console.error('错误详情:', error);
} finally {
await sequelize.close();
}
}
simpleTest();

View File

@@ -1,27 +0,0 @@
const http = require('http');
const options = {
hostname: 'localhost',
port: 5352,
path: '/api/slaughter/slaughterhouses',
method: 'GET',
headers: {
'Authorization': 'Bearer mock-jwt-token-test',
'Content-Type': 'application/json'
}
};
const req = http.request(options, (res) => {
console.log(`状态码: ${res.statusCode}`);
console.log(`响应头: ${JSON.stringify(res.headers)}`);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (error) => {
console.error(error);
});
req.end();

View File

@@ -1,132 +0,0 @@
const axios = require('axios');
// 创建axios实例
const api = axios.create({
baseURL: 'http://localhost:5352/api/cattle-academy',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer test-token'
}
});
// 测试获取养牛学院资讯列表
async function testGetCattleAcademyList() {
try {
console.log('测试获取养牛学院资讯列表...');
const response = await api.get('/');
console.log('获取列表成功:', response.data);
} catch (error) {
console.error('获取列表失败:', error.response?.data || error.message);
}
}
// 测试获取单个养牛学院资讯详情
async function testGetCattleAcademyById() {
try {
console.log('测试获取养牛学院资讯详情...');
const response = await api.get('/1');
console.log('获取详情成功:', response.data);
} catch (error) {
console.error('获取详情失败:', error.response?.data || error.message);
}
}
// 测试创建养牛学院资讯
async function testCreateCattleAcademy() {
try {
console.log('测试创建养牛学院资讯...');
const data = {
title: '测试养牛学院资讯',
coverImage: 'https://via.placeholder.com/100x50',
content: '测试内容...',
summary: '测试摘要',
category: '技术资讯',
sort: 50,
status: true,
author: '测试作者',
publishTime: new Date().toISOString(),
isTop: false,
isRecommend: false,
remarks: '测试备注'
};
const response = await api.post('/', data);
console.log('创建成功:', response.data);
} catch (error) {
console.error('创建失败:', error.response?.data || error.message);
}
}
// 测试更新养牛学院资讯
async function testUpdateCattleAcademy() {
try {
console.log('测试更新养牛学院资讯...');
const data = {
title: '更新测试养牛学院资讯',
coverImage: 'https://via.placeholder.com/100x50',
content: '更新测试内容...',
summary: '更新测试摘要',
category: '养殖技术',
sort: 60,
status: true,
author: '更新测试作者',
publishTime: new Date().toISOString(),
isTop: true,
isRecommend: true,
remarks: '更新测试备注'
};
const response = await api.put('/1', data);
console.log('更新成功:', response.data);
} catch (error) {
console.error('更新失败:', error.response?.data || error.message);
}
}
// 测试切换资讯状态
async function testToggleStatus() {
try {
console.log('测试切换资讯状态...');
const response = await api.patch('/1/status', { status: false });
console.log('状态切换成功:', response.data);
} catch (error) {
console.error('状态切换失败:', error.response?.data || error.message);
}
}
// 测试删除养牛学院资讯
async function testDeleteCattleAcademy() {
try {
console.log('测试删除养牛学院资讯...');
const response = await api.delete('/1');
console.log('删除成功:', response.data);
} catch (error) {
console.error('删除失败:', error.response?.data || error.message);
}
}
// 运行所有测试
async function runAllTests() {
console.log('开始测试养牛学院API...\n');
await testGetCattleAcademyList();
console.log('\n');
await testGetCattleAcademyById();
console.log('\n');
await testCreateCattleAcademy();
console.log('\n');
await testUpdateCattleAcademy();
console.log('\n');
await testToggleStatus();
console.log('\n');
await testDeleteCattleAcademy();
console.log('\n');
console.log('所有测试完成');
}
runAllTests();

View File

@@ -1,84 +0,0 @@
const http = require('http');
// 测试函数
function testRoute(path, description) {
return new Promise((resolve, reject) => {
const options = {
hostname: 'localhost',
port: 5353,
path: path,
method: 'GET',
headers: {
'Authorization': 'Bearer mock-jwt-token-test',
'Content-Type': 'application/json'
}
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve({
path: path,
description: description,
statusCode: res.statusCode,
headers: res.headers,
body: data
});
});
});
req.on('error', (error) => {
reject({
path: path,
description: description,
error: error.message
});
});
req.end();
});
}
// 运行所有测试
async function runTests() {
console.log('开始测试路由...\n');
try {
// 测试健康检查路由
const healthResult = await testRoute('/health', '健康检查');
console.log(`${healthResult.description} - 状态码: ${healthResult.statusCode}`);
console.log(`响应: ${healthResult.body}\n`);
// 测试测试路由
const testResult = await testRoute('/api/test/test', '测试路由');
console.log(`${testResult.description} - 状态码: ${testResult.statusCode}`);
console.log(`响应: ${testResult.body}\n`);
// 测试slaughter路由
const slaughterResult = await testRoute('/api/slaughter/slaughterhouses', 'Slaughter路由');
console.log(`${slaughterResult.description} - 状态码: ${slaughterResult.statusCode}`);
console.log(`响应: ${slaughterResult.body}\n`);
// 测试不存在的路由
const notFoundResult = await testRoute('/api/not-exist', '不存在的路由');
console.log(`${notFoundResult.description} - 状态码: ${notFoundResult.statusCode}`);
console.log(`响应: ${notFoundResult.body}\n`);
} catch (error) {
console.error('测试失败:', error);
}
}
// 等待一会儿再运行测试,给服务器启动时间
sleep(2000).then(() => {
runTests();
});
// 简单的sleep函数
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@@ -1,45 +0,0 @@
require('dotenv').config();
const mysql = require('mysql2/promise');
async function testConnection() {
try {
// 从环境变量获取数据库配置
const config = {
host: process.env.DB_HOST || '129.211.213.226',
port: process.env.DB_PORT || 9527,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || 'aiotAiot123!',
database: process.env.DB_NAME || 'ningxia_zhengfu'
};
console.log('正在连接数据库...');
console.log('📋 数据库配置信息:');
console.log(` 主机: ${config.host}`);
console.log(` 端口: ${config.port}`);
console.log(` 数据库名: ${config.database}`);
console.log(` 用户名: ${config.user}`);
// 创建数据库连接
const connection = await mysql.createConnection(config);
console.log('✅ 政府端后端数据库连接成功');
// 查询数据库中的表
const [tables] = await connection.query(
"SELECT table_name FROM information_schema.tables WHERE table_schema = ?",
[config.database]
);
console.log(`📚 数据库表数量: ${tables.length}`);
// 关闭连接
await connection.end();
console.log('🔒 数据库连接已关闭');
process.exit(0);
} catch (error) {
console.error('❌ 政府端后端数据库连接失败:', error.message);
process.exit(1);
}
}
testConnection();

View File

@@ -0,0 +1,50 @@
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();

View File

@@ -1,31 +0,0 @@
// 测试数据库连接
const sequelize = require('./config/database');
async function testDbConnection() {
try {
console.log('正在尝试连接数据库...');
console.log('连接配置:', {
host: sequelize.config.host,
port: sequelize.config.port,
database: sequelize.config.database,
username: sequelize.config.username,
dialect: sequelize.config.dialect
});
await sequelize.authenticate();
console.log('✅ 数据库连接成功!');
// 尝试查询数据库版本信息
const [results] = await sequelize.query('SELECT VERSION() AS version');
console.log('数据库版本:', results[0].version);
// 关闭连接
await sequelize.close();
console.log('数据库连接已关闭');
} catch (error) {
console.error('❌ 数据库连接失败:', error.message);
console.error('详细错误:', error);
}
}
testDbConnection();

View File

@@ -1,99 +0,0 @@
const axios = require('axios');
const API_BASE_URL = 'http://localhost:5352/api/device-warning';
const api = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer test-token'
}
});
async function testDeviceWarningAPI() {
console.log('开始测试设备预警API...\n');
try {
// 测试获取预警统计
console.log('1. 测试获取预警统计...');
const statsResponse = await api.get('/stats');
console.log('预警统计:', statsResponse.data);
console.log('✅ 获取预警统计成功\n');
// 测试获取设备预警列表
console.log('2. 测试获取设备预警列表...');
const listResponse = await api.get('/', {
params: {
page: 1,
pageSize: 10,
deviceType: '智能项圈'
}
});
console.log('设备预警列表:', listResponse.data);
console.log('✅ 获取设备预警列表成功\n');
// 测试根据ID获取详情
if (listResponse.data.data && listResponse.data.data.list.length > 0) {
const firstWarning = listResponse.data.data.list[0];
console.log('3. 测试获取设备预警详情...');
const detailResponse = await api.get(`/${firstWarning.id}`);
console.log('设备预警详情:', detailResponse.data);
console.log('✅ 获取设备预警详情成功\n');
// 测试更新预警状态
console.log('4. 测试更新预警状态...');
const updateResponse = await api.patch(`/${firstWarning.id}/status`, {
status: 'resolved',
resolvedBy: '测试用户'
});
console.log('更新预警状态:', updateResponse.data);
console.log('✅ 更新预警状态成功\n');
}
// 测试创建新的设备预警
console.log('5. 测试创建设备预警...');
const createData = {
farmName: '测试养殖场',
farmerName: '测试养殖户',
phone: '138****8888',
deviceType: '智能耳标',
deviceNumber: 'TEST001',
alertType: '设备离线',
alertLevel: 'high',
description: '测试预警',
location: '测试位置',
batteryLevel: 20,
signalStrength: 30,
temperature: 25.5
};
const createResponse = await api.post('/', createData);
console.log('创建设备预警:', createResponse.data);
console.log('✅ 创建设备预警成功\n');
// 测试更新设备预警
if (createResponse.data.data) {
console.log('6. 测试更新设备预警...');
const updateData = {
description: '更新后的测试预警',
batteryLevel: 15
};
const updateResponse = await api.put(`/${createResponse.data.data.id}`, updateData);
console.log('更新设备预警:', updateResponse.data);
console.log('✅ 更新设备预警成功\n');
// 测试删除设备预警
console.log('7. 测试删除设备预警...');
const deleteResponse = await api.delete(`/${createResponse.data.data.id}`);
console.log('删除设备预警:', deleteResponse.data);
console.log('✅ 删除设备预警成功\n');
}
console.log('🎉 所有设备预警API测试通过');
} catch (error) {
console.error('❌ API测试失败:', error.response ? error.response.data : error.message);
}
}
testDeviceWarningAPI();

View File

@@ -1,124 +0,0 @@
const axios = require('axios');
const BASE_URL = 'http://localhost:5352/api/epidemic-activity';
// 创建axios实例添加认证头
const api = axios.create({
baseURL: BASE_URL,
headers: {
'Authorization': 'Bearer test-token', // 测试用的token
'Content-Type': 'application/json'
}
});
// 测试获取防疫活动列表
async function testGetActivities() {
try {
console.log('测试获取防疫活动列表...');
const response = await api.get('/');
console.log('获取成功:', response.data);
} catch (error) {
console.error('获取失败:', error.response?.data || error.message);
}
}
// 测试创建防疫活动
async function testCreateActivity() {
try {
console.log('测试创建防疫活动...');
const newActivity = {
activityName: '测试防疫活动',
livestockCategory: '牛',
diseaseCategory: '口蹄疫',
vaccineUsed: '测试疫苗',
vaccineBatch: 'TEST001',
preventionDate: '2023-12-01至2023-12-31',
activityStatus: 'active'
};
const response = await api.post('/', newActivity);
console.log('创建成功:', response.data);
return response.data.data.id;
} catch (error) {
console.error('创建失败:', error.response?.data || error.message);
}
}
// 测试更新防疫活动
async function testUpdateActivity(id) {
try {
console.log('测试更新防疫活动...');
const updateData = {
activityName: '更新后的防疫活动',
livestockCategory: '羊',
diseaseCategory: '布鲁氏菌病',
vaccineUsed: '更新疫苗',
vaccineBatch: 'UPDATE001',
preventionDate: '2023-12-15至2024-01-15',
activityStatus: 'inactive'
};
const response = await api.put(`/${id}`, updateData);
console.log('更新成功:', response.data);
} catch (error) {
console.error('更新失败:', error.response?.data || error.message);
}
}
// 测试切换活动状态
async function testToggleStatus(id) {
try {
console.log('测试切换活动状态...');
const response = await api.patch(`/${id}/status`);
console.log('状态切换成功:', response.data);
} catch (error) {
console.error('状态切换失败:', error.response?.data || error.message);
}
}
// 测试删除防疫活动
async function testDeleteActivity(id) {
try {
console.log('测试删除防疫活动...');
const response = await api.delete(`/${id}`);
console.log('删除成功:', response.data);
} catch (error) {
console.error('删除失败:', error.response?.data || error.message);
}
}
// 运行所有测试
async function runTests() {
console.log('开始测试防疫活动管理API...\n');
await testGetActivities();
console.log('\n' + '='.repeat(50) + '\n');
const createdId = await testCreateActivity();
console.log('\n' + '='.repeat(50) + '\n');
if (createdId) {
await testUpdateActivity(createdId);
console.log('\n' + '='.repeat(50) + '\n');
await testToggleStatus(createdId);
console.log('\n' + '='.repeat(50) + '\n');
await testDeleteActivity(createdId);
}
console.log('\n测试完成');
}
// 如果直接运行此文件
if (require.main === module) {
runTests();
}
module.exports = {
testGetActivities,
testCreateActivity,
testUpdateActivity,
testToggleStatus,
testDeleteActivity
};

View File

@@ -1,32 +0,0 @@
const axios = require('axios')
async function testEpidemicAPI() {
try {
console.log('测试防疫记录API...')
// 测试获取列表
const response = await axios.get('http://localhost:5352/api/epidemic-record/list?page=1&pageSize=5')
console.log('API响应状态:', response.status)
console.log('API响应数据:', JSON.stringify(response.data, null, 2))
if (response.data.code === 200) {
console.log('✅ API调用成功')
console.log('记录数量:', response.data.data.list.length)
if (response.data.data.list.length > 0) {
console.log('第一条记录:', response.data.data.list[0])
}
} else {
console.log('❌ API返回错误:', response.data.message)
}
} catch (error) {
console.error('❌ API调用失败:', error.message)
if (error.response) {
console.error('响应状态:', error.response.status)
console.error('响应数据:', error.response.data)
}
}
}
testEpidemicAPI()

View File

@@ -1,101 +0,0 @@
// 测试修复后的epidemic agencies接口
const axios = require('axios');
// 政府后端服务地址
const BASE_URL = 'http://localhost:5352/api';
// 登录获取token
async function login() {
try {
console.log('开始登录...');
const response = await axios.post(`${BASE_URL}/auth/login`, {
username: 'admin',
password: '123456'
});
console.log('登录响应:', response.data);
if (response.data.code === 200 && response.data.data && response.data.data.token) {
console.log('登录成功获取到token');
return response.data.data.token;
} else {
console.log('登录失败未获取到token');
console.log('错误信息:', response.data.message || '未知错误');
return null;
}
} catch (error) {
console.error('登录请求失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
}
return null;
}
}
// 测试新增防疫机构
async function testCreateAgency(token) {
try {
console.log('\n开始测试新增防疫机构...');
const testData = {
name: '测试防疫机构' + Date.now(),
code: 'TEST-' + Date.now(),
type: 'station',
level: 'county',
manager: '测试负责人',
phone: '13800138999',
address: '测试地址',
epidemicScope: '测试防疫范围',
remarks: '测试备注',
email: 'test@example.com',
status: 'active',
establishmentDate: '2024-01-01'
};
console.log('提交的数据:', testData);
const response = await axios.post(`${BASE_URL}/epidemic/agencies`, testData, {
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('新增防疫机构成功');
console.log(`- 状态码: ${response.status}`);
console.log(`- 返回数据:`, response.data);
return response.data;
} catch (error) {
console.error('测试新增防疫机构失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
}
return null;
}
}
// 执行测试
async function runTests() {
try {
console.log('开始测试修复后的epidemic agencies接口...');
// 1. 登录获取token
const token = await login();
if (!token) {
console.log('未获取到token测试终止');
return;
}
// 2. 测试新增防疫机构
const createResult = await testCreateAgency(token);
console.log('\n测试完成');
} catch (error) {
console.error('测试过程中发生错误:', error);
}
}
// 执行测试
runTests();

View File

@@ -1,95 +0,0 @@
// 测试无害化场所API
const axios = require('axios');
// 政府后端服务地址
const BASE_URL = 'http://localhost:5352/api';
// 登录获取token
async function login() {
try {
console.log('开始登录...');
const response = await axios.post(`${BASE_URL}/auth/login`, {
username: 'admin',
password: '123456'
});
console.log('登录响应:', response.data);
if (response.data.code === 200 && response.data.data && response.data.data.token) {
console.log('登录成功获取到token');
return response.data.data.token;
} else {
console.log('登录失败未获取到token');
console.log('错误信息:', response.data.message || '未知错误');
return null;
}
} catch (error) {
console.error('登录请求失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
}
return null;
}
}
// 测试无害化场所列表API
async function testHarmlessPlaceList(token) {
try {
console.log('\n测试无害化场所列表API...');
const response = await axios.get(`${BASE_URL}/harmless-place/list`, {
headers: {
'Authorization': `Bearer ${token}`
},
params: {
page: 1,
pageSize: 10
}
});
console.log('API调用成功状态码:', response.status);
console.log('返回数据结构:', Object.keys(response.data));
console.log('无害化场所总数:', response.data.total || '未知');
if (response.data.data && Array.isArray(response.data.data)) {
console.log('返回的无害化场所列表长度:', response.data.data.length);
if (response.data.data.length > 0) {
console.log('第一条无害化场所数据:');
console.log(response.data.data[0]);
}
}
return response.data;
} catch (error) {
console.error('无害化场所列表API调用失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
}
return null;
}
}
// 主测试函数
const runTests = async () => {
console.log('开始测试无害化场所管理API...');
try {
// 1. 登录获取token
const token = await login();
if (!token) {
console.error('无法继续测试因为未获取到有效的token');
return;
}
// 2. 测试获取无害化场所列表
await testHarmlessPlaceList(token);
console.log('\n所有测试完成');
} catch (error) {
console.error('测试过程中发生错误:', error);
}
};
// 运行测试
runTests();

View File

@@ -1,89 +0,0 @@
// 清除模块缓存
function clearModuleCache() {
const modulesToClear = Object.keys(require.cache).filter(key =>
key.includes('HarmlessPlace') || key.includes('database')
);
console.log('清除以下模块的缓存:', modulesToClear.length, '个模块');
modulesToClear.forEach(key => {
console.log('-', key);
delete require.cache[key];
});
}
// 清除缓存后再导入
clearModuleCache();
const axios = require('axios');
const HarmlessPlace = require('./models/HarmlessPlace');
console.log('=== 检查HarmlessPlace模型 ===');
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
console.log('HarmlessPlace是否为对象:', typeof HarmlessPlace === 'object' && HarmlessPlace !== null);
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
if (HarmlessPlace.findAndCountAll) {
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
}
// 登录函数
async function login() {
try {
const response = await axios.post('http://localhost:3000/api/auth/login', {
username: 'admin',
password: '123456'
});
console.log('登录成功token:', response.data.data.token);
return response.data.data.token;
} catch (error) {
console.error('登录失败:', error.response ? error.response.data : error.message);
return null;
}
}
// 测试无害化场所列表API
async function testHarmlessPlaceList(token) {
try {
const response = await axios.get('http://localhost:3000/api/harmless-place/list', {
headers: {
'Authorization': `Bearer ${token}`
},
params: {
page: 1,
pageSize: 10
}
});
console.log('无害化场所列表API调用成功:', response.data);
return response.data;
} catch (error) {
console.error('无害化场所列表API调用失败:', error.message);
if (error.response) {
console.error('错误数据:', error.response.data);
}
return null;
}
}
// 主函数
async function main() {
console.log('开始测试无害化场所管理API...');
// 登录获取token
const token = await login();
if (!token) {
console.log('登录失败,无法继续测试');
return;
}
// 再次检查模型类型确保在API调用前没有被修改
console.log('\n=== API调用前再次检查HarmlessPlace模型 ===');
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
// 测试API
await testHarmlessPlaceList(token);
console.log('\n所有测试完成');
}
// 运行测试
main().catch(err => console.error('测试过程中出错:', err));

View File

@@ -1,74 +0,0 @@
// 测试模型文件
const sequelize = require('./config/database');
const AdminStaff = require('./models/AdminStaff');
const Department = require('./models/Department');
const Position = require('./models/Position');
async function testModels() {
try {
console.log('开始测试模型...');
// 测试数据库连接
await sequelize.authenticate();
console.log('✅ 数据库连接成功');
// 测试模型关系
console.log('\n测试模型关系:');
console.log('AdminStaff关联Department:', AdminStaff.associations.department ? '✅' : '❌');
console.log('AdminStaff关联Position:', AdminStaff.associations.position ? '✅' : '❌');
console.log('Department关联Position:', Department.associations.positions ? '✅' : '❌');
console.log('Position关联Department:', Position.associations.department ? '✅' : '❌');
// 尝试获取行政人员数据
console.log('\n尝试获取行政人员数据:');
const adminStaffs = await AdminStaff.findAll({
include: [
{ model: Department, as: 'department' },
{ model: Position, as: 'position' }
],
limit: 5
});
if (adminStaffs.length > 0) {
console.log(`✅ 成功获取${adminStaffs.length}条行政人员数据`);
console.log('示例数据:', adminStaffs[0].dataValues);
} else {
console.log('⚠️ 未找到行政人员数据');
}
// 尝试获取部门数据
console.log('\n尝试获取部门数据:');
const departments = await Department.findAll({
limit: 5
});
if (departments.length > 0) {
console.log(`✅ 成功获取${departments.length}条部门数据`);
console.log('示例数据:', departments[0].dataValues);
} else {
console.log('⚠️ 未找到部门数据');
}
// 尝试获取岗位数据
console.log('\n尝试获取岗位数据:');
const positions = await Position.findAll({
include: [{ model: Department, as: 'department' }],
limit: 5
});
if (positions.length > 0) {
console.log(`✅ 成功获取${positions.length}条岗位数据`);
console.log('示例数据:', positions[0].dataValues);
} else {
console.log('⚠️ 未找到岗位数据');
}
console.log('\n✅ 模型测试完成');
} catch (error) {
console.error('❌ 模型测试失败:', error);
} finally {
await sequelize.close();
}
}
testModels();

View File

@@ -1,50 +0,0 @@
// 测试行政人员列表接口
const axios = require('axios');
// 政府后端服务地址
const BASE_URL = 'http://localhost:5352/api';
// 测试行政人员列表接口
async function testAdminStaffList() {
try {
// 先登录获取token
const loginResponse = await axios.post(`${BASE_URL}/auth/login`, {
username: 'admin',
password: '123456'
});
const token = loginResponse.data.token;
console.log('登录成功获取到token');
// 使用token访问行政人员列表接口
const response = await axios.get(`${BASE_URL}/personnel`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
console.log('行政人员列表接口测试结果:');
console.log(`- 状态码: ${response.status}`);
console.log(`- 返回数据结构:`, Object.keys(response.data));
console.log(`- 行政人员总数: ${response.data.total}`);
console.log(`- 返回的行政人员列表长度: ${response.data.data ? response.data.data.length : 0}`);
if (response.data.data && response.data.data.length > 0) {
console.log(`- 第一条行政人员数据:`, response.data.data[0]);
} else {
console.log('- 行政人员列表为空');
}
console.log('\n测试完成');
} catch (error) {
console.error('测试失败:', error.message);
if (error.response) {
console.error('错误状态码:', error.response.status);
console.error('错误数据:', error.response.data);
}
}
}
// 执行测试
console.log('开始测试行政人员列表接口...');
testAdminStaffList();

View File

@@ -1,51 +0,0 @@
// 测试Express应用的路由注册情况
const express = require('express');
const path = require('path');
// 创建一个简单的Express应用来测试路由
const app = express();
// 尝试加载slaughter路由
try {
const slaughterRoutes = require('./routes/slaughter');
console.log('成功加载slaughter路由模块');
// 检查路由模块的内容
console.log('路由模块导出:', typeof slaughterRoutes);
// 模拟注册路由
app.use('/api/slaughter', slaughterRoutes);
console.log('成功注册slaughter路由到/api/slaughter');
// 检查路由是否有方法
if (slaughterRoutes && slaughterRoutes.stack) {
console.log('路由处理程序数量:', slaughterRoutes.stack.length);
slaughterRoutes.stack.forEach((layer, index) => {
if (layer.route) {
console.log(`路由${index + 1}:`, layer.route.path, Object.keys(layer.route.methods));
}
});
} else {
console.log('路由模块没有stack属性可能不是Express Router实例');
}
} catch (error) {
console.error('加载slaughter路由失败:', error);
}
// 检查routes目录下的文件
const fs = require('fs');
const routesDir = path.join(__dirname, 'routes');
fs.readdir(routesDir, (err, files) => {
if (err) {
console.error('读取routes目录失败:', err);
return;
}
console.log('\nroutes目录下的文件:');
files.forEach(file => {
console.log('-', file);
// 检查文件大小,确认文件不为空
const stats = fs.statSync(path.join(routesDir, file));
console.log(` 大小: ${stats.size} 字节`);
});
});

View File

@@ -1,44 +0,0 @@
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
// 中间件
app.use(cors());
app.use(bodyParser.json());
// 简单的认证中间件,允许所有请求通过
app.use((req, res, next) => {
console.log(`接收到请求: ${req.method} ${req.path}`);
// 模拟用户数据
req.user = {
id: '1',
username: 'admin',
role: 'admin'
};
next();
});
// 加载测试路由
app.use('/api/test', require('./routes/test-route'));
// 加载slaughter路由
app.use('/api/slaughter', require('./routes/slaughter'));
// 简单的健康检查路由
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
// 错误处理
app.use((err, req, res, next) => {
console.error('错误:', err);
res.status(500).json({ error: '服务器错误' });
});
// 启动服务器在不同端口
const PORT = 5353;
app.listen(PORT, () => {
console.log(`测试服务器已启动在端口 ${PORT}`);
});