完善保险端前后端

This commit is contained in:
shenquanyi
2025-09-24 18:12:37 +08:00
parent 111ebaec84
commit b17bdcc24c
56 changed files with 9862 additions and 1111 deletions

View 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;

View 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();

View 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;

View 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;

View 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();