1
This commit is contained in:
@@ -61,7 +61,8 @@ module.exports = {
|
||||
*/
|
||||
'POST /device/detail': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { device_status } = models;
|
||||
const { pla_account } = models;
|
||||
const deviceManager = require('../../middleware/schedule/deviceManager');
|
||||
const body = ctx.getBody();
|
||||
const { deviceSn } = body;
|
||||
|
||||
@@ -69,69 +70,97 @@ module.exports = {
|
||||
return ctx.fail('设备SN码不能为空');
|
||||
}
|
||||
|
||||
const device = await device_status.findOne({
|
||||
// 从 pla_account 获取账号信息
|
||||
const account = await pla_account.findOne({
|
||||
where: { sn_code: deviceSn }
|
||||
});
|
||||
|
||||
if (!device) {
|
||||
if (!account) {
|
||||
return ctx.fail('设备不存在');
|
||||
}
|
||||
|
||||
const deviceData = device.toJSON();
|
||||
const accountData = account.toJSON();
|
||||
|
||||
// 处理 JSON 字段
|
||||
if (deviceData.config) {
|
||||
try {
|
||||
deviceData.config = typeof deviceData.config === 'string'
|
||||
? JSON.parse(deviceData.config)
|
||||
: deviceData.config;
|
||||
} catch (e) {
|
||||
console.error('解析设备配置失败:', e);
|
||||
deviceData.config = {};
|
||||
}
|
||||
}
|
||||
// 从 deviceManager 获取在线状态
|
||||
const deviceStatus = deviceManager.getAllDevicesStatus();
|
||||
const onlineStatus = deviceStatus[deviceSn] || { isOnline: false };
|
||||
|
||||
// 组合返回数据
|
||||
const deviceData = {
|
||||
sn_code: accountData.sn_code,
|
||||
device_id: accountData.device_id,
|
||||
deviceName: accountData.name || accountData.sn_code,
|
||||
platform: accountData.platform_type,
|
||||
isOnline: onlineStatus.isOnline || false,
|
||||
isRunning: false, // 不再维护运行状态
|
||||
lastHeartbeatTime: onlineStatus.lastHeartbeat ? new Date(onlineStatus.lastHeartbeat) : null,
|
||||
accountName: accountData.name,
|
||||
platform_type: accountData.platform_type,
|
||||
is_enabled: accountData.is_enabled
|
||||
};
|
||||
|
||||
return ctx.success(deviceData);
|
||||
},
|
||||
|
||||
'POST /device/list': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { device_status, op } = models;
|
||||
const { pla_account, op } = models;
|
||||
const deviceManager = require('../../middleware/schedule/deviceManager');
|
||||
const body = ctx.getBody();
|
||||
const { isOnline, healthStatus, platform, searchText} = ctx.getBody();
|
||||
|
||||
// 获取分页参数
|
||||
const { limit, offset } = ctx.getPageSize();
|
||||
|
||||
|
||||
const where = {};
|
||||
if (isOnline !== undefined) where.isOnline = isOnline;
|
||||
if (healthStatus) where.healthStatus = healthStatus;
|
||||
if (platform) where.platform = platform;
|
||||
// 从 pla_account 查询账号
|
||||
const where = { is_delete: 0 };
|
||||
if (platform) where.platform_type = platform;
|
||||
|
||||
// 支持搜索设备名称或SN码
|
||||
if (searchText) {
|
||||
where[op.or] = [
|
||||
{ deviceName: { [op.like]: `%${searchText}%` } },
|
||||
{ sn_code: { [op.like]: `%${searchText}%` } }
|
||||
];
|
||||
}
|
||||
// 支持搜索设备名称或SN码
|
||||
if (searchText) {
|
||||
where[op.or] = [
|
||||
{ name: { [op.like]: `%${searchText}%` } },
|
||||
{ sn_code: { [op.like]: `%${searchText}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
const result = await device_status.findAndCountAll({
|
||||
where,
|
||||
limit,
|
||||
offset,
|
||||
order: [
|
||||
['isOnline', 'DESC'],
|
||||
['last_modify_time', 'DESC']
|
||||
]
|
||||
});
|
||||
const result = await pla_account.findAndCountAll({
|
||||
where,
|
||||
limit,
|
||||
offset,
|
||||
order: [['id', 'DESC']]
|
||||
});
|
||||
|
||||
return ctx.success({
|
||||
total: result.count,
|
||||
list: result.rows
|
||||
});
|
||||
|
||||
// 获取设备在线状态
|
||||
const deviceStatus = deviceManager.getAllDevicesStatus();
|
||||
|
||||
// 组合数据并过滤在线状态
|
||||
let list = result.rows.map(account => {
|
||||
const accountData = account.toJSON();
|
||||
const status = deviceStatus[accountData.sn_code] || { isOnline: false };
|
||||
return {
|
||||
sn_code: accountData.sn_code,
|
||||
device_id: accountData.device_id,
|
||||
deviceName: accountData.name || accountData.sn_code,
|
||||
platform: accountData.platform_type,
|
||||
isOnline: status.isOnline || false,
|
||||
isRunning: false,
|
||||
lastHeartbeatTime: status.lastHeartbeat ? new Date(status.lastHeartbeat) : null,
|
||||
accountName: accountData.name,
|
||||
platform_type: accountData.platform_type,
|
||||
is_enabled: accountData.is_enabled
|
||||
};
|
||||
});
|
||||
|
||||
// 如果指定了在线状态筛选
|
||||
if (isOnline !== undefined) {
|
||||
list = list.filter(item => item.isOnline === isOnline);
|
||||
}
|
||||
|
||||
return ctx.success({
|
||||
total: list.length,
|
||||
list: list.slice(0, limit)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -147,56 +176,46 @@ return ctx.success({
|
||||
*/
|
||||
'GET /device/overview': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { device_status, op } = models;
|
||||
const { pla_account } = models;
|
||||
const deviceManager = require('../../middleware/schedule/deviceManager');
|
||||
|
||||
|
||||
const [
|
||||
totalDevices,
|
||||
onlineDevices,
|
||||
runningDevices,
|
||||
healthyDevices,
|
||||
warningDevices,
|
||||
errorDevices
|
||||
] = await Promise.all([
|
||||
device_status.count(),
|
||||
device_status.count({ where: { isOnline: true } }),
|
||||
device_status.count({ where: { isRunning: true } }),
|
||||
device_status.count({ where: { healthStatus: 'healthy' } }),
|
||||
device_status.count({ where: { healthStatus: 'warning' } }),
|
||||
device_status.count({ where: { healthStatus: 'error' } })
|
||||
]);
|
||||
// 从 pla_account 获取账号总数
|
||||
const totalDevices = await pla_account.count({ where: { is_delete: 0 } });
|
||||
|
||||
// 计算平均健康分数
|
||||
const avgHealthScore = await device_status.findAll({
|
||||
attributes: [
|
||||
[models.sequelize.fn('AVG', models.sequelize.col('healthScore')), 'avgScore']
|
||||
],
|
||||
raw: true
|
||||
});
|
||||
// 从 deviceManager 获取在线设备统计
|
||||
const deviceStatus = deviceManager.getAllDevicesStatus();
|
||||
const onlineDevices = Object.values(deviceStatus).filter(d => d.isOnline).length;
|
||||
const runningDevices = 0; // 不再维护运行状态
|
||||
const healthyDevices = onlineDevices; // 简化处理,在线即健康
|
||||
const warningDevices = 0;
|
||||
const errorDevices = 0;
|
||||
|
||||
// 获取最近离线的设备
|
||||
const recentOffline = await device_status.findAll({
|
||||
where: { isOnline: false },
|
||||
limit: 5,
|
||||
order: [['lastOfflineTime', 'DESC']],
|
||||
attributes: ['sn_code', 'deviceName', 'lastOfflineTime', 'lastError']
|
||||
});
|
||||
// 获取最近离线的设备(从内存状态中获取)
|
||||
const offlineDevicesList = Object.entries(deviceStatus)
|
||||
.filter(([sn_code, status]) => !status.isOnline)
|
||||
.map(([sn_code, status]) => ({
|
||||
sn_code,
|
||||
deviceName: sn_code,
|
||||
lastOfflineTime: status.lastHeartbeat ? new Date(status.lastHeartbeat) : null,
|
||||
lastError: ''
|
||||
}))
|
||||
.sort((a, b) => (b.lastOfflineTime?.getTime() || 0) - (a.lastOfflineTime?.getTime() || 0))
|
||||
.slice(0, 5);
|
||||
|
||||
return ctx.success({
|
||||
totalDevices,
|
||||
onlineDevices,
|
||||
offlineDevices: totalDevices - onlineDevices,
|
||||
runningDevices,
|
||||
idleDevices: onlineDevices - runningDevices,
|
||||
healthyDevices,
|
||||
warningDevices,
|
||||
errorDevices,
|
||||
onlineRate: totalDevices > 0 ? ((onlineDevices / totalDevices) * 100).toFixed(2) : 0,
|
||||
healthyRate: totalDevices > 0 ? ((healthyDevices / totalDevices) * 100).toFixed(2) : 0,
|
||||
averageHealthScore: parseFloat(avgHealthScore[0]?.avgScore || 0).toFixed(2),
|
||||
recentOffline
|
||||
});
|
||||
|
||||
return ctx.success({
|
||||
totalDevices,
|
||||
onlineDevices,
|
||||
offlineDevices: totalDevices - onlineDevices,
|
||||
runningDevices,
|
||||
idleDevices: onlineDevices - runningDevices,
|
||||
healthyDevices,
|
||||
warningDevices,
|
||||
errorDevices,
|
||||
onlineRate: totalDevices > 0 ? ((onlineDevices / totalDevices) * 100).toFixed(2) : 0,
|
||||
healthyRate: totalDevices > 0 ? ((healthyDevices / totalDevices) * 100).toFixed(2) : 0,
|
||||
averageHealthScore: '100.00', // 简化处理
|
||||
recentOffline: offlineDevicesList
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -228,7 +247,7 @@ return ctx.success({
|
||||
*/
|
||||
'POST /device/update-config': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { device_status } = models;
|
||||
const { account_config } = models;
|
||||
const body = ctx.getBody();
|
||||
const { sn_code, config } = body;
|
||||
|
||||
@@ -236,9 +255,19 @@ return ctx.success({
|
||||
return ctx.fail('设备SN码和配置数据不能为空');
|
||||
}
|
||||
|
||||
await device_status.update({
|
||||
config: JSON.stringify(config)
|
||||
}, { where: { sn_code } });
|
||||
// 从 pla_account 获取账号ID
|
||||
const { pla_account } = models;
|
||||
const account = await pla_account.findOne({ where: { sn_code } });
|
||||
if (!account) {
|
||||
return ctx.fail('设备不存在');
|
||||
}
|
||||
|
||||
// 更新 account_config 表的配置
|
||||
await account_config.upsert({
|
||||
account_id: account.id,
|
||||
platform_type: account.platform_type,
|
||||
platform_config: config
|
||||
});
|
||||
|
||||
return ctx.success({ message: '设备配置更新成功' });
|
||||
},
|
||||
@@ -267,25 +296,9 @@ return ctx.success({
|
||||
* description: 重置成功
|
||||
*/
|
||||
'POST /device/reset-error': async (ctx) => {
|
||||
const models = Framework.getModels();
|
||||
const { device_status } = models;
|
||||
const body = ctx.getBody();
|
||||
const { sn_code } = body;
|
||||
|
||||
if (!sn_code) {
|
||||
return ctx.fail('设备SN码不能为空');
|
||||
}
|
||||
|
||||
|
||||
await device_status.update({
|
||||
lastError: '',
|
||||
errorCount: 0,
|
||||
healthStatus: 'healthy',
|
||||
healthScore: 100
|
||||
}, { where: { sn_code } });
|
||||
|
||||
return ctx.success({ message: '设备错误已重置' });
|
||||
|
||||
// device_status 表已移除,此功能暂时禁用
|
||||
// 如果需要重置错误,可以在 account_config 表中添加错误信息字段
|
||||
return ctx.success({ message: '设备错误重置功能已禁用(device_status 表已移除)' });
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -312,8 +325,10 @@ return ctx.success({ message: '设备错误已重置' });
|
||||
* description: 删除成功
|
||||
*/
|
||||
'POST /device/delete': async (ctx) => {
|
||||
// device_status 表已移除,删除设备功能改为删除账号
|
||||
// 如果需要删除设备,应该删除对应的 pla_account 记录
|
||||
const models = Framework.getModels();
|
||||
const { device_status } = models;
|
||||
const { pla_account } = models;
|
||||
const body = ctx.getBody();
|
||||
const { sn_code } = body;
|
||||
|
||||
@@ -321,15 +336,17 @@ return ctx.success({ message: '设备错误已重置' });
|
||||
return ctx.fail('设备SN码不能为空');
|
||||
}
|
||||
|
||||
|
||||
const result = await device_status.destroy({ where: { sn_code } });
|
||||
// 软删除账号(设置 is_delete = 1)
|
||||
const result = await pla_account.update(
|
||||
{ is_delete: 1 },
|
||||
{ where: { sn_code } }
|
||||
);
|
||||
|
||||
if (result === 0) {
|
||||
return ctx.fail('设备不存在');
|
||||
}
|
||||
if (result[0] === 0) {
|
||||
return ctx.fail('设备不存在');
|
||||
}
|
||||
|
||||
return ctx.success({ message: '设备删除成功' });
|
||||
|
||||
return ctx.success({ message: '设备删除成功' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user