Initial commit: 宁夏智慧养殖监管平台

This commit is contained in:
shenquanyi
2025-08-25 15:00:46 +08:00
commit ec72c6a8b5
177 changed files with 37263 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
/**
* 种子数据: initial_data
* 创建时间: 2023-01-01T00:00:00.000Z
* 描述: 初始化基础数据
*/
'use strict';
const bcrypt = require('bcrypt');
module.exports = {
up: async (queryInterface, Sequelize) => {
// 插入基础角色数据
await queryInterface.bulkInsert('roles', [
{
name: 'admin',
description: '系统管理员',
created_at: new Date()
},
{
name: 'user',
description: '普通用户',
created_at: new Date()
},
{
name: 'guest',
description: '访客',
created_at: new Date()
}
]);
// 生成密码哈希
const passwordHash = await bcrypt.hash('123456', 10);
// 插入示例用户数据
await queryInterface.bulkInsert('users', [
{
username: 'admin',
email: 'admin@example.com',
password: passwordHash,
created_at: new Date(),
updated_at: new Date()
},
{
username: 'john_doe',
email: 'john@example.com',
password: passwordHash,
created_at: new Date(),
updated_at: new Date()
}
]);
// 获取用户和角色的ID
const users = await queryInterface.sequelize.query(
'SELECT id, username FROM users',
{ type: Sequelize.QueryTypes.SELECT }
);
const roles = await queryInterface.sequelize.query(
'SELECT id, name FROM roles',
{ type: Sequelize.QueryTypes.SELECT }
);
const adminUser = users.find(user => user.username === 'admin');
const johnUser = users.find(user => user.username === 'john_doe');
const adminRole = roles.find(role => role.name === 'admin');
const userRole = roles.find(role => role.name === 'user');
// 为用户分配角色
if (adminUser && adminRole) {
await queryInterface.bulkInsert('user_roles', [{
user_id: adminUser.id,
role_id: adminRole.id,
assigned_at: new Date()
}]);
}
if (johnUser && userRole) {
await queryInterface.bulkInsert('user_roles', [{
user_id: johnUser.id,
role_id: userRole.id,
assigned_at: new Date()
}]);
}
// 插入示例产品数据
await queryInterface.bulkInsert('products', [
{
name: '示例产品1',
description: '这是一个示例产品',
price: 99.99,
stock: 100,
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '示例产品2',
description: '这是另一个示例产品',
price: 149.99,
stock: 50,
status: 'active',
created_at: new Date(),
updated_at: new Date()
}
]);
},
down: async (queryInterface, Sequelize) => {
// 按照依赖关系的相反顺序删除数据
await queryInterface.bulkDelete('user_roles', null, {});
await queryInterface.bulkDelete('products', null, {});
await queryInterface.bulkDelete('users', null, {});
await queryInterface.bulkDelete('roles', null, {});
}
};

View File

@@ -0,0 +1,204 @@
/**
* 种子数据: farm_data
* 创建时间: 2023-01-02T00:00:00.000Z
* 描述: 农场、动物、设备和预警数据
*/
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
// 插入农场数据
await queryInterface.bulkInsert('farms', [
{
name: '阳光农场',
type: '养猪场',
location: JSON.stringify({ lat: 39.9042, lng: 116.4074 }),
address: '北京市朝阳区农场路1号',
contact: '张三',
phone: '13800138001',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '绿野牧场',
type: '养牛场',
location: JSON.stringify({ lat: 31.2304, lng: 121.4737 }),
address: '上海市浦东新区牧场路2号',
contact: '李四',
phone: '13800138002',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '山谷羊场',
type: '养羊场',
location: JSON.stringify({ lat: 23.1291, lng: 113.2644 }),
address: '广州市天河区山谷路3号',
contact: '王五',
phone: '13800138003',
status: 'active',
created_at: new Date(),
updated_at: new Date()
}
]);
// 获取农场ID
const farms = await queryInterface.sequelize.query(
'SELECT id, name FROM farms',
{ type: Sequelize.QueryTypes.SELECT }
);
const sunnyFarm = farms.find(farm => farm.name === '阳光农场');
const greenFarm = farms.find(farm => farm.name === '绿野牧场');
const valleyFarm = farms.find(farm => farm.name === '山谷羊场');
// 插入动物数据
const animalData = [];
if (sunnyFarm) {
animalData.push(
{
type: '猪',
count: 1500,
farmId: sunnyFarm.id,
health_status: 'healthy',
last_inspection: new Date(),
notes: '生长良好',
created_at: new Date(),
updated_at: new Date()
},
{
type: '猪',
count: 300,
farmId: sunnyFarm.id,
health_status: 'sick',
last_inspection: new Date(),
notes: '需要治疗',
created_at: new Date(),
updated_at: new Date()
}
);
}
if (greenFarm) {
animalData.push(
{
type: '牛',
count: 800,
farmId: greenFarm.id,
health_status: 'healthy',
last_inspection: new Date(),
notes: '健康状况良好',
created_at: new Date(),
updated_at: new Date()
},
{
type: '牛',
count: 50,
farmId: greenFarm.id,
health_status: 'quarantine',
last_inspection: new Date(),
notes: '隔离观察',
created_at: new Date(),
updated_at: new Date()
}
);
}
if (valleyFarm) {
animalData.push(
{
type: '羊',
count: 600,
farmId: valleyFarm.id,
health_status: 'healthy',
last_inspection: new Date(),
notes: '状态良好',
created_at: new Date(),
updated_at: new Date()
}
);
}
await queryInterface.bulkInsert('animals', animalData);
// 插入设备数据
const deviceData = [];
const deviceTypes = ['温度传感器', '湿度传感器', '摄像头', '喂食器'];
const deviceStatuses = ['online', 'offline', 'maintenance'];
farms.forEach(farm => {
deviceTypes.forEach((type, index) => {
const count = Math.floor(Math.random() * 20) + 10; // 10-30个设备
for (let i = 0; i < count; i++) {
const status = deviceStatuses[Math.floor(Math.random() * deviceStatuses.length)];
deviceData.push({
name: `${type}_${farm.name}_${i + 1}`,
type: type,
status: status,
farmId: farm.id,
last_maintenance: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000), // 随机过去30天内
installation_date: new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000), // 随机过去一年内
metrics: JSON.stringify({
temperature: Math.round((Math.random() * 10 + 20) * 10) / 10,
humidity: Math.round((Math.random() * 30 + 50) * 10) / 10
}),
created_at: new Date(),
updated_at: new Date()
});
}
});
});
await queryInterface.bulkInsert('devices', deviceData);
// 获取设备ID
const devices = await queryInterface.sequelize.query(
'SELECT id, farmId FROM devices',
{ type: Sequelize.QueryTypes.SELECT }
);
// 插入预警数据
const alertData = [];
const alertTypes = ['温度异常', '湿度异常', '设备故障', '电源异常'];
const alertLevels = ['low', 'medium', 'high', 'critical'];
const alertStatuses = ['active', 'acknowledged', 'resolved'];
farms.forEach(farm => {
// 每个农场生成5-15个预警
const alertCount = Math.floor(Math.random() * 10) + 5;
for (let i = 0; i < alertCount; i++) {
const type = alertTypes[Math.floor(Math.random() * alertTypes.length)];
const level = alertLevels[Math.floor(Math.random() * alertLevels.length)];
const status = alertStatuses[Math.floor(Math.random() * alertStatuses.length)];
const farmDevices = devices.filter(device => device.farmId === farm.id);
const device = farmDevices[Math.floor(Math.random() * farmDevices.length)];
alertData.push({
type: type,
level: level,
message: `${type}${farm.name}发生${type}`,
status: status,
farmId: farm.id,
deviceId: device ? device.id : null,
resolved_at: status === 'resolved' ? new Date() : null,
resolved_by: status === 'resolved' ? 1 : null,
resolution_notes: status === 'resolved' ? '问题已解决' : null,
created_at: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000), // 随机过去7天内
updated_at: new Date()
});
}
});
await queryInterface.bulkInsert('alerts', alertData);
},
down: async (queryInterface, Sequelize) => {
// 按照依赖关系的相反顺序删除数据
await queryInterface.bulkDelete('alerts', null, {});
await queryInterface.bulkDelete('devices', null, {});
await queryInterface.bulkDelete('animals', null, {});
await queryInterface.bulkDelete('farms', null, {});
}
};

View File

@@ -0,0 +1,275 @@
/**
* 种子数据: extended_data
* 创建时间: 2023-01-03T00:00:00.000Z
* 描述: 扩展数据,增加更多养殖场、动物、设备和预警数据
*/
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
// 插入更多农场数据
await queryInterface.bulkInsert('farms', [
{
name: '蓝天养鸡场',
type: '养鸡场',
location: JSON.stringify({ lat: 30.2741, lng: 120.1551 }),
address: '杭州市西湖区蓝天路4号',
contact: '赵六',
phone: '13800138004',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '金山养鸭场',
type: '养鸭场',
location: JSON.stringify({ lat: 36.0611, lng: 103.8343 }),
address: '兰州市城关区金山路5号',
contact: '孙七',
phone: '13800138005',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '银河渔场',
type: '渔场',
location: JSON.stringify({ lat: 29.5647, lng: 106.5507 }),
address: '重庆市渝中区银河路6号',
contact: '周八',
phone: '13800138006',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '星空牧场',
type: '综合养殖场',
location: JSON.stringify({ lat: 34.3416, lng: 108.9398 }),
address: '西安市雁塔区星空路7号',
contact: '吴九',
phone: '13800138007',
status: 'active',
created_at: new Date(),
updated_at: new Date()
},
{
name: '彩虹农庄',
type: '生态农场',
location: JSON.stringify({ lat: 22.3193, lng: 114.1694 }),
address: '深圳市福田区彩虹路8号',
contact: '郑十',
phone: '13800138008',
status: 'active',
created_at: new Date(),
updated_at: new Date()
}
]);
// 获取所有农场ID
const farms = await queryInterface.sequelize.query(
'SELECT id, name, type FROM farms',
{ type: Sequelize.QueryTypes.SELECT }
);
// 为每个农场添加动物数据
const animalData = [];
farms.forEach(farm => {
const animalTypes = {
'养猪场': ['猪'],
'养牛场': ['牛'],
'养羊场': ['羊'],
'养鸡场': ['鸡'],
'养鸭场': ['鸭'],
'渔场': ['鱼'],
'综合养殖场': ['猪', '牛', '鸡'],
'生态农场': ['猪', '牛', '羊', '鸡']
};
const types = animalTypes[farm.type] || ['猪'];
const healthStatuses = ['healthy', 'sick', 'quarantine', 'recovering'];
types.forEach(type => {
// 为每种动物类型创建2-4个记录
const recordCount = Math.floor(Math.random() * 3) + 2;
for (let i = 0; i < recordCount; i++) {
const count = Math.floor(Math.random() * 1000) + 100; // 100-1100只
const healthStatus = healthStatuses[Math.floor(Math.random() * healthStatuses.length)];
animalData.push({
type: type,
count: count,
farm_id: farm.id,
health_status: healthStatus,
last_inspection: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000),
notes: `${type}群体${healthStatus === 'healthy' ? '健康' : '需要关注'}`,
created_at: new Date(),
updated_at: new Date()
});
}
});
});
await queryInterface.bulkInsert('animals', animalData);
// 为每个农场添加设备数据
const deviceData = [];
const deviceTypes = [
'温度传感器', '湿度传感器', '摄像头', '喂食器',
'水质监测器', '空气质量监测器', '自动门', '照明系统',
'通风系统', '报警器', 'GPS定位器', '体重秤'
];
const deviceStatuses = ['online', 'offline', 'maintenance', 'error'];
farms.forEach(farm => {
// 每个农场20-50个设备
const deviceCount = Math.floor(Math.random() * 30) + 20;
for (let i = 0; i < deviceCount; i++) {
const type = deviceTypes[Math.floor(Math.random() * deviceTypes.length)];
const status = deviceStatuses[Math.floor(Math.random() * deviceStatuses.length)];
deviceData.push({
name: `${type}_${farm.name}_${String(i + 1).padStart(3, '0')}`,
type: type,
status: status,
farm_id: farm.id,
last_maintenance: new Date(Date.now() - Math.random() * 90 * 24 * 60 * 60 * 1000),
installation_date: new Date(Date.now() - Math.random() * 730 * 24 * 60 * 60 * 1000),
metrics: JSON.stringify({
temperature: Math.round((Math.random() * 15 + 15) * 10) / 10, // 15-30度
humidity: Math.round((Math.random() * 40 + 40) * 10) / 10, // 40-80%
battery: Math.round(Math.random() * 100), // 0-100%
signal_strength: Math.round(Math.random() * 100) // 0-100%
}),
created_at: new Date(),
updated_at: new Date()
});
}
});
await queryInterface.bulkInsert('devices', deviceData);
// 获取所有设备ID
const devices = await queryInterface.sequelize.query(
'SELECT id, farm_id, type FROM devices',
{ type: Sequelize.QueryTypes.SELECT }
);
// 为每个农场添加预警数据
const alertData = [];
const alertTypes = [
'温度异常', '湿度异常', '设备故障', '电源异常',
'水质异常', '空气质量差', '饲料不足', '疾病预警',
'安全警报', '维护提醒', '环境污染', '异常行为'
];
const alertLevels = ['low', 'medium', 'high', 'critical'];
const alertStatuses = ['active', 'acknowledged', 'resolved', 'investigating'];
farms.forEach(farm => {
// 每个农场10-30个预警
const alertCount = Math.floor(Math.random() * 20) + 10;
for (let i = 0; i < alertCount; i++) {
const type = alertTypes[Math.floor(Math.random() * alertTypes.length)];
const level = alertLevels[Math.floor(Math.random() * alertLevels.length)];
const status = alertStatuses[Math.floor(Math.random() * alertStatuses.length)];
const farmDevices = devices.filter(device => device.farm_id === farm.id);
const device = farmDevices[Math.floor(Math.random() * farmDevices.length)];
const createdAt = new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000);
alertData.push({
type: type,
level: level,
message: `${farm.name}发生${type}${device ? `设备:${device.type}` : '位置未知'}`,
status: status,
farm_id: farm.id,
device_id: device ? device.id : null,
resolved_at: status === 'resolved' ? new Date(createdAt.getTime() + Math.random() * 7 * 24 * 60 * 60 * 1000) : null,
resolved_by: status === 'resolved' ? 1 : null,
resolution_notes: status === 'resolved' ? '问题已解决,系统恢复正常' : null,
created_at: createdAt,
updated_at: new Date()
});
}
});
await queryInterface.bulkInsert('alerts', alertData);
// 添加传感器数据
const sensorData = [];
const sensorDevices = devices.filter(device =>
device.type.includes('传感器') || device.type.includes('监测器')
);
// 为每个传感器设备生成过去30天的数据
sensorDevices.forEach(device => {
for (let day = 0; day < 30; day++) {
// 每天4-8个数据点
const pointsPerDay = Math.floor(Math.random() * 5) + 4;
for (let point = 0; point < pointsPerDay; point++) {
const timestamp = new Date(Date.now() - day * 24 * 60 * 60 * 1000 + point * (24 / pointsPerDay) * 60 * 60 * 1000);
sensorData.push({
device_id: device.id,
farm_id: device.farm_id,
temperature: Math.round((Math.random() * 20 + 10) * 10) / 10, // 10-30度
humidity: Math.round((Math.random() * 50 + 30) * 10) / 10, // 30-80%
air_quality: Math.round(Math.random() * 500), // 0-500 AQI
light_intensity: Math.round(Math.random() * 100000), // 0-100000 lux
noise_level: Math.round(Math.random() * 100), // 0-100 dB
timestamp: timestamp,
created_at: timestamp,
updated_at: timestamp
});
}
}
});
// 分批插入传感器数据,避免一次性插入过多数据
const batchSize = 1000;
for (let i = 0; i < sensorData.length; i += batchSize) {
const batch = sensorData.slice(i, i + batchSize);
await queryInterface.bulkInsert('sensor_data', batch);
}
console.log(`成功导入扩展数据:`);
console.log(`- 农场: ${farms.length}`);
console.log(`- 动物记录: ${animalData.length}`);
console.log(`- 设备: ${deviceData.length}`);
console.log(`- 预警: ${alertData.length}`);
console.log(`- 传感器数据: ${sensorData.length}`);
},
down: async (queryInterface, Sequelize) => {
// 获取要删除的农场ID除了前3个基础农场
const farmsToDelete = await queryInterface.sequelize.query(
"SELECT id FROM farms WHERE name IN ('蓝天养鸡场', '金山养鸭场', '银河渔场', '星空牧场', '彩虹农庄')",
{ type: Sequelize.QueryTypes.SELECT }
);
const farmIds = farmsToDelete.map(farm => farm.id);
if (farmIds.length > 0) {
// 按照依赖关系的相反顺序删除数据
await queryInterface.bulkDelete('sensor_data', {
farm_id: { [Sequelize.Op.in]: farmIds }
});
await queryInterface.bulkDelete('alerts', {
farm_id: { [Sequelize.Op.in]: farmIds }
});
await queryInterface.bulkDelete('devices', {
farm_id: { [Sequelize.Op.in]: farmIds }
});
await queryInterface.bulkDelete('animals', {
farm_id: { [Sequelize.Op.in]: farmIds }
});
await queryInterface.bulkDelete('farms', {
id: { [Sequelize.Op.in]: farmIds }
});
}
}
};