完善保险端前后端
This commit is contained in:
43
insurance_backend/scripts/check-table-structure.js
Normal file
43
insurance_backend/scripts/check-table-structure.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
async function checkTableStructure() {
|
||||
try {
|
||||
// 创建数据库连接
|
||||
const connection = await mysql.createConnection({
|
||||
host: '129.211.213.226',
|
||||
port: 9527,
|
||||
user: 'root',
|
||||
password: 'aiotAiot123!',
|
||||
database: 'insurance_data'
|
||||
});
|
||||
|
||||
console.log('✅ 数据库连接成功');
|
||||
|
||||
// 查看devices表结构
|
||||
console.log('\n📋 devices表结构:');
|
||||
const [devicesColumns] = await connection.execute('DESCRIBE devices');
|
||||
console.table(devicesColumns);
|
||||
|
||||
// 查看device_alerts表结构
|
||||
console.log('\n📋 device_alerts表结构:');
|
||||
const [alertsColumns] = await connection.execute('DESCRIBE device_alerts');
|
||||
console.table(alertsColumns);
|
||||
|
||||
await connection.end();
|
||||
console.log('\n✅ 检查完成');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 检查表结构失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
checkTableStructure().then(() => {
|
||||
process.exit(0);
|
||||
}).catch(error => {
|
||||
console.error('❌ 脚本执行失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = checkTableStructure;
|
||||
96
insurance_backend/scripts/check_user_permissions.js
Normal file
96
insurance_backend/scripts/check_user_permissions.js
Normal file
@@ -0,0 +1,96 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
async function checkUserPermissions() {
|
||||
const connection = await mysql.createConnection({
|
||||
host: '129.211.213.226',
|
||||
port: 9527,
|
||||
user: 'root',
|
||||
password: 'aiotAiot123!',
|
||||
database: 'insurance_data'
|
||||
});
|
||||
|
||||
try {
|
||||
console.log('=== 检查用户权限和JWT Token ===');
|
||||
|
||||
// 1. 查询admin用户信息
|
||||
const [adminUsers] = await connection.execute(
|
||||
'SELECT * FROM users WHERE username = ?',
|
||||
['admin']
|
||||
);
|
||||
|
||||
if (adminUsers.length === 0) {
|
||||
console.log('❌ Admin用户不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
const adminUser = adminUsers[0];
|
||||
console.log('\n1. Admin用户信息:');
|
||||
console.log(`- ID: ${adminUser.id}`);
|
||||
console.log(`- 用户名: ${adminUser.username}`);
|
||||
console.log(`- 角色ID: ${adminUser.role_id}`);
|
||||
console.log(`- 状态: ${adminUser.status}`);
|
||||
|
||||
// 2. 查询admin角色权限
|
||||
const [roles] = await connection.execute(
|
||||
'SELECT * FROM roles WHERE id = ?',
|
||||
[adminUser.role_id]
|
||||
);
|
||||
|
||||
if (roles.length === 0) {
|
||||
console.log('❌ Admin角色不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
const adminRole = roles[0];
|
||||
console.log('\n2. Admin角色信息:');
|
||||
console.log(`- 角色名: ${adminRole.name}`);
|
||||
console.log(`- 权限类型: ${typeof adminRole.permissions}`);
|
||||
console.log(`- 权限内容: ${JSON.stringify(adminRole.permissions, null, 2)}`);
|
||||
|
||||
// 3. 模拟JWT token生成
|
||||
console.log('\n3. 模拟JWT Token生成:');
|
||||
const tokenPayload = {
|
||||
id: adminUser.id,
|
||||
username: adminUser.username,
|
||||
role_id: adminUser.role_id,
|
||||
permissions: adminRole.permissions || []
|
||||
};
|
||||
|
||||
console.log('Token Payload:', JSON.stringify(tokenPayload, null, 2));
|
||||
|
||||
// 使用默认密钥生成token(实际应用中应该从环境变量获取)
|
||||
const jwtSecret = process.env.JWT_SECRET || 'your_jwt_secret_key';
|
||||
const token = jwt.sign(tokenPayload, jwtSecret, { expiresIn: '7d' });
|
||||
|
||||
console.log('\n4. 生成的JWT Token:');
|
||||
console.log(token);
|
||||
|
||||
// 5. 验证token
|
||||
console.log('\n5. 验证JWT Token:');
|
||||
try {
|
||||
const decoded = jwt.verify(token, jwtSecret);
|
||||
console.log('解码后的Token:', JSON.stringify(decoded, null, 2));
|
||||
|
||||
// 检查权限
|
||||
const hasDataRead = decoded.permissions &&
|
||||
(Array.isArray(decoded.permissions) ?
|
||||
decoded.permissions.includes('data:read') :
|
||||
decoded.permissions.includes && decoded.permissions.includes('data:read'));
|
||||
|
||||
console.log(`\n6. 权限检查结果:`);
|
||||
console.log(`- 是否有data:read权限: ${hasDataRead}`);
|
||||
console.log(`- 权限数组长度: ${Array.isArray(decoded.permissions) ? decoded.permissions.length : 'N/A'}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Token验证失败:', error.message);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('检查时出错:', error);
|
||||
} finally {
|
||||
await connection.end();
|
||||
}
|
||||
}
|
||||
|
||||
checkUserPermissions();
|
||||
89
insurance_backend/scripts/create-device-tables.js
Normal file
89
insurance_backend/scripts/create-device-tables.js
Normal file
@@ -0,0 +1,89 @@
|
||||
const { sequelize } = require('../models');
|
||||
|
||||
async function createTables() {
|
||||
try {
|
||||
console.log('开始创建设备相关表...');
|
||||
|
||||
// 创建设备表
|
||||
await sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '设备ID',
|
||||
device_number VARCHAR(50) NOT NULL UNIQUE COMMENT '设备编号',
|
||||
device_name VARCHAR(100) NOT NULL COMMENT '设备名称',
|
||||
device_type VARCHAR(50) NOT NULL COMMENT '设备类型',
|
||||
device_model VARCHAR(100) COMMENT '设备型号',
|
||||
manufacturer VARCHAR(100) COMMENT '制造商',
|
||||
installation_location VARCHAR(200) COMMENT '安装位置',
|
||||
installation_date DATE COMMENT '安装日期',
|
||||
status ENUM('normal', 'warning', 'error', 'offline') DEFAULT 'normal' COMMENT '设备状态',
|
||||
farm_id INT COMMENT '养殖场ID',
|
||||
barn_id INT COMMENT '栏舍ID',
|
||||
created_by INT COMMENT '创建人ID',
|
||||
updated_by INT COMMENT '更新人ID',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_device_number (device_number),
|
||||
INDEX idx_device_type (device_type),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_farm_barn (farm_id, barn_id),
|
||||
INDEX idx_created_by (created_by),
|
||||
INDEX idx_updated_by (updated_by)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='设备表';
|
||||
`);
|
||||
|
||||
console.log('✅ 设备表创建成功');
|
||||
|
||||
// 创建设备预警表
|
||||
await sequelize.query(`
|
||||
CREATE TABLE IF NOT EXISTS device_alerts (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '预警ID',
|
||||
device_id INT NOT NULL COMMENT '设备ID',
|
||||
alert_type VARCHAR(50) NOT NULL COMMENT '预警类型',
|
||||
alert_level ENUM('info', 'warning', 'critical') NOT NULL COMMENT '预警级别',
|
||||
alert_title VARCHAR(200) NOT NULL COMMENT '预警标题',
|
||||
alert_content TEXT COMMENT '预警内容',
|
||||
alert_time TIMESTAMP NOT NULL COMMENT '预警时间',
|
||||
status ENUM('pending', 'processing', 'resolved', 'ignored') DEFAULT 'pending' COMMENT '处理状态',
|
||||
handler_id INT COMMENT '处理人ID',
|
||||
handle_time TIMESTAMP NULL COMMENT '处理时间',
|
||||
handle_note TEXT COMMENT '处理备注',
|
||||
farm_id INT COMMENT '养殖场ID',
|
||||
barn_id INT COMMENT '栏舍ID',
|
||||
is_read BOOLEAN DEFAULT FALSE COMMENT '是否已读',
|
||||
read_time TIMESTAMP NULL COMMENT '阅读时间',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_device_id (device_id),
|
||||
INDEX idx_alert_type (alert_type),
|
||||
INDEX idx_alert_level (alert_level),
|
||||
INDEX idx_alert_time (alert_time),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_farm_barn (farm_id, barn_id),
|
||||
INDEX idx_handler_id (handler_id),
|
||||
INDEX idx_is_read (is_read),
|
||||
FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (handler_id) REFERENCES users(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='设备预警表';
|
||||
`);
|
||||
|
||||
console.log('✅ 设备预警表创建成功');
|
||||
console.log('🎉 所有表创建完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 创建表失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
createTables().then(() => {
|
||||
console.log('数据库表创建完成');
|
||||
process.exit(0);
|
||||
}).catch(error => {
|
||||
console.error('创建失败:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = createTables;
|
||||
161
insurance_backend/scripts/test-device-data.js
Normal file
161
insurance_backend/scripts/test-device-data.js
Normal file
@@ -0,0 +1,161 @@
|
||||
const { Device, DeviceAlert, User } = require('../models');
|
||||
|
||||
async function createTestData() {
|
||||
try {
|
||||
console.log('开始创建测试数据...');
|
||||
|
||||
// 获取第一个用户作为创建者
|
||||
const user = await User.findOne();
|
||||
if (!user) {
|
||||
console.log('❌ 没有找到用户,请先创建用户');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已有测试设备
|
||||
const existingDevice = await Device.findOne({ where: { device_number: 'DEV001' } });
|
||||
let devices;
|
||||
|
||||
if (existingDevice) {
|
||||
console.log('📋 测试设备已存在,使用现有设备');
|
||||
devices = await Device.findAll({
|
||||
where: {
|
||||
device_number: ['DEV001', 'DEV002', 'DEV003']
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 创建测试设备
|
||||
devices = await Device.bulkCreate([
|
||||
{
|
||||
device_number: 'DEV001',
|
||||
device_name: '温度传感器A',
|
||||
device_type: '温度传感器',
|
||||
device_model: 'TMP-100',
|
||||
manufacturer: '智能科技',
|
||||
installation_location: '1号栏舍',
|
||||
installation_date: new Date('2024-01-15'),
|
||||
status: 'normal',
|
||||
farm_id: 1,
|
||||
barn_id: 1,
|
||||
created_by: user.id,
|
||||
updated_by: user.id
|
||||
},
|
||||
{
|
||||
device_number: 'DEV002',
|
||||
device_name: '湿度传感器B',
|
||||
device_type: '湿度传感器',
|
||||
device_model: 'HUM-200',
|
||||
manufacturer: '智能科技',
|
||||
installation_location: '2号栏舍',
|
||||
installation_date: new Date('2024-01-20'),
|
||||
status: 'warning',
|
||||
farm_id: 1,
|
||||
barn_id: 2,
|
||||
created_by: user.id,
|
||||
updated_by: user.id
|
||||
},
|
||||
{
|
||||
device_number: 'DEV003',
|
||||
device_name: '监控摄像头C',
|
||||
device_type: '监控设备',
|
||||
device_model: 'CAM-300',
|
||||
manufacturer: '安防科技',
|
||||
installation_location: '3号栏舍',
|
||||
installation_date: new Date('2024-02-01'),
|
||||
status: 'error',
|
||||
farm_id: 1,
|
||||
barn_id: 3,
|
||||
created_by: user.id,
|
||||
updated_by: user.id
|
||||
}
|
||||
]);
|
||||
|
||||
console.log(`✅ 创建了 ${devices.length} 个测试设备`);
|
||||
}
|
||||
|
||||
console.log(`📊 当前有 ${devices.length} 个测试设备`);
|
||||
|
||||
// 检查是否已有测试预警
|
||||
const existingAlert = await DeviceAlert.findOne({ where: { device_id: devices[0].id } });
|
||||
let alerts;
|
||||
|
||||
if (existingAlert) {
|
||||
console.log('📋 测试预警已存在,清除旧数据并创建新数据');
|
||||
await DeviceAlert.destroy({ where: { device_id: devices.map(d => d.id) } });
|
||||
}
|
||||
|
||||
// 创建测试预警
|
||||
alerts = await DeviceAlert.bulkCreate([
|
||||
{
|
||||
device_id: devices[0].id,
|
||||
alert_type: 'temperature',
|
||||
alert_level: 'warning',
|
||||
alert_title: '温度异常',
|
||||
alert_content: '1号栏舍温度传感器检测到温度过高,当前温度35°C',
|
||||
alert_time: new Date(),
|
||||
status: 'pending',
|
||||
farm_id: 1,
|
||||
barn_id: 1,
|
||||
is_read: false
|
||||
},
|
||||
{
|
||||
device_id: devices[1].id,
|
||||
alert_type: 'humidity',
|
||||
alert_level: 'critical',
|
||||
alert_title: '湿度严重异常',
|
||||
alert_content: '2号栏舍湿度传感器检测到湿度过低,当前湿度30%',
|
||||
alert_time: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2小时前
|
||||
status: 'pending',
|
||||
farm_id: 1,
|
||||
barn_id: 2,
|
||||
is_read: false
|
||||
},
|
||||
{
|
||||
device_id: devices[2].id,
|
||||
alert_type: 'offline',
|
||||
alert_level: 'critical',
|
||||
alert_title: '设备离线',
|
||||
alert_content: '3号栏舍监控摄像头已离线超过30分钟',
|
||||
alert_time: new Date(Date.now() - 4 * 60 * 60 * 1000), // 4小时前
|
||||
status: 'pending',
|
||||
farm_id: 1,
|
||||
barn_id: 3,
|
||||
is_read: true,
|
||||
read_time: new Date(Date.now() - 3 * 60 * 60 * 1000)
|
||||
},
|
||||
{
|
||||
device_id: devices[0].id,
|
||||
alert_type: 'maintenance',
|
||||
alert_level: 'info',
|
||||
alert_title: '设备维护提醒',
|
||||
alert_content: '温度传感器A需要进行定期维护检查',
|
||||
alert_time: new Date(Date.now() - 24 * 60 * 60 * 1000), // 1天前
|
||||
status: 'resolved',
|
||||
handler_id: user.id,
|
||||
handle_time: new Date(Date.now() - 20 * 60 * 60 * 1000),
|
||||
handle_note: '已完成维护检查,设备运行正常',
|
||||
farm_id: 1,
|
||||
barn_id: 1,
|
||||
is_read: true,
|
||||
read_time: new Date(Date.now() - 23 * 60 * 60 * 1000)
|
||||
}
|
||||
]);
|
||||
|
||||
console.log(`✅ 创建了 ${alerts.length} 个测试预警`);
|
||||
console.log('🎉 测试数据创建完成!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 创建测试数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接运行此脚本
|
||||
if (require.main === module) {
|
||||
createTestData().then(() => {
|
||||
process.exit(0);
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = createTestData;
|
||||
76
insurance_backend/scripts/test_frontend_auth.js
Normal file
76
insurance_backend/scripts/test_frontend_auth.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const axios = require('axios');
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
async function testFrontendAuth() {
|
||||
const baseURL = 'http://localhost:3000';
|
||||
|
||||
try {
|
||||
console.log('=== 测试前端认证流程 ===');
|
||||
|
||||
// 1. 模拟前端登录
|
||||
console.log('\n1. 模拟前端登录...');
|
||||
const loginResponse = await axios.post(`${baseURL}/api/auth/login`, {
|
||||
username: 'admin',
|
||||
password: '123456'
|
||||
});
|
||||
|
||||
if (loginResponse.data.status === 'success' || loginResponse.data.success) {
|
||||
console.log('✅ 登录成功');
|
||||
const token = loginResponse.data.data.token;
|
||||
console.log(`Token: ${token.substring(0, 50)}...`);
|
||||
|
||||
// 2. 解码token查看内容
|
||||
console.log('\n2. 解码JWT Token:');
|
||||
try {
|
||||
const jwtSecret = 'insurance_super_secret_jwt_key_2024';
|
||||
const decoded = jwt.verify(token, jwtSecret);
|
||||
console.log('Token内容:', JSON.stringify(decoded, null, 2));
|
||||
|
||||
// 检查权限
|
||||
const hasDataRead = decoded.permissions &&
|
||||
(Array.isArray(decoded.permissions) ?
|
||||
decoded.permissions.includes('data:read') :
|
||||
decoded.permissions.includes && decoded.permissions.includes('data:read'));
|
||||
|
||||
console.log(`\n权限检查:`);
|
||||
console.log(`- 是否有data:read权限: ${hasDataRead}`);
|
||||
console.log(`- 权限数组长度: ${Array.isArray(decoded.permissions) ? decoded.permissions.length : 'N/A'}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Token解码失败:', error.message);
|
||||
}
|
||||
|
||||
// 3. 测试数据仓库接口
|
||||
console.log('\n3. 测试数据仓库接口访问:');
|
||||
try {
|
||||
const overviewResponse = await axios.get(`${baseURL}/api/data-warehouse/overview`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ 数据仓库接口访问成功');
|
||||
console.log('响应状态:', overviewResponse.status);
|
||||
console.log('响应数据:', JSON.stringify(overviewResponse.data, null, 2));
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 数据仓库接口访问失败:');
|
||||
console.error('状态码:', error.response?.status);
|
||||
console.error('错误信息:', error.response?.data);
|
||||
console.error('完整错误:', error.message);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.error('❌ 登录失败:', loginResponse.data);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试过程中出错:', error.message);
|
||||
if (error.response) {
|
||||
console.error('响应状态:', error.response.status);
|
||||
console.error('响应数据:', error.response.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testFrontendAuth();
|
||||
Reference in New Issue
Block a user