/** * 设备监控管理API - 后台管理 * 提供设备状态监控和管理功能 */ const Framework = require("../../framework/node-core-framework.js"); module.exports = { /** * @swagger * /admin_api/device/list: * post: * summary: 获取设备列表 * description: 分页获取所有设备列表(管理后台) * tags: [后台-设备管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * page: * type: integer * description: 页码 * pageSize: * type: integer * description: 每页数量 * isOnline: * type: boolean * description: 是否在线(可选) * healthStatus: * type: string * description: 健康状态(可选) * responses: * 200: * description: 获取成功 */ 'POST /device/list': async (ctx) => { const models = Framework.getModels(); const { device_status, op } = models; 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; // 支持搜索设备名称或SN码 if (searchText) { where[op.or] = [ { deviceName: { [op.like]: `%${searchText}%` } }, { sn_code: { [op.like]: `%${searchText}%` } } ]; } const result = await device_status.findAndCountAll({ where, limit, offset, order: [ ['isOnline', 'DESC'], ['last_modify_time', 'DESC'] ] }); return ctx.success({ total: result.count, list: result.rows }); }, /** * @swagger * /admin_api/device/overview: * get: * summary: 获取设备概览 * description: 获取所有设备的统计概览 * tags: [后台-设备管理] * responses: * 200: * description: 获取成功 */ 'GET /device/overview': async (ctx) => { const models = Framework.getModels(); const { device_status, op } = models; 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' } }) ]); // 计算平均健康分数 const avgHealthScore = await device_status.findAll({ attributes: [ [models.sequelize.fn('AVG', models.sequelize.col('healthScore')), 'avgScore'] ], raw: true }); // 获取最近离线的设备 const recentOffline = await device_status.findAll({ where: { isOnline: false }, limit: 5, order: [['lastOfflineTime', 'DESC']], attributes: ['sn_code', 'deviceName', 'lastOfflineTime', 'lastError'] }); 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 }); }, /** * @swagger * /admin_api/device/update-config: * post: * summary: 更新设备配置 * description: 更新指定设备的配置信息 * tags: [后台-设备管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - sn_code * - config * properties: * sn_code: * type: string * description: 设备SN码 * config: * type: object * description: 配置数据 * responses: * 200: * description: 更新成功 */ 'POST /device/update-config': async (ctx) => { const models = Framework.getModels(); const { device_status } = models; const body = ctx.getBody(); const { sn_code, config } = body; if (!sn_code || !config) { return ctx.fail('设备SN码和配置数据不能为空'); } await device_status.update({ config: JSON.stringify(config) }, { where: { sn_code } }); return ctx.success({ message: '设备配置更新成功' }); }, /** * @swagger * /admin_api/device/reset-error: * post: * summary: 重置设备错误 * description: 清除设备的错误信息和计数 * tags: [后台-设备管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - sn_code * properties: * sn_code: * type: string * description: 设备SN码 * responses: * 200: * 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: '设备错误已重置' }); }, /** * @swagger * /admin_api/device/delete: * post: * summary: 删除设备 * description: 删除指定的设备记录 * tags: [后台-设备管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - sn_code * properties: * sn_code: * type: string * description: 设备SN码 * responses: * 200: * description: 删除成功 */ 'POST /device/delete': 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码不能为空'); } const result = await device_status.destroy({ where: { sn_code } }); if (result === 0) { return ctx.fail('设备不存在'); } return ctx.success({ message: '设备删除成功' }); } };