const db = require('../config/db'); const logger = require('../logger'); // 移除这一行重复的引用声明 // -const HeaterUsageService = require('../services/HeaterUsageService'); // 保留正确的类定义 class HeaterUsageService { // 在handleHeaterUsage方法中添加数据验证 static async handleHeaterUsage(device_id, status, temperature, timestamp) { try { if (!device_id || !timestamp) { throw new Error('设备ID和时间戳不能为空'); } // TODO 0: 总体逻辑:1. 当当前设备状态为开并且温度大于12,开始插入数据库并记录开始时间 2. 当当前状态关闭时并且查询到有大于12的记录,插入结束时间并计算时长 // TODO 举例: // if (status === 'on' && temperature > 12) { // // 开始插入开始时间 // const sql = `INSERT INTO heater_usage (device_id, start_time, end_time, duration) VALUES (?, ?, NULL, 0)`; // db.query(sql, [device_id, startTime]); // }else{ // // 查询是否有当前设置大于12的数据:其实就是最近开始时间的一条 // const sql1 = `SELECT * FROM heater_usage WHERE device_id = ? ORDER BY start_time DESC LIMIT 1`; // const [results] =await db.query(sql1, [device_id]); // // 如果有就计算 // if(results.length){ // // 在当前结果中,插入结束时间并计算时长,结束时间就取当前结束的时间 // // TODO 5 这里应该是修改当前查询到的信息,奈何sql不精,哈哈哈,下面的仅做参考 // const end_time = Date.now(); // const sql = `UPDATE heater_usage // SET end_time = ?, // duration = TIMESTAMPDIFF(SECOND, start_time, ?) // WHERE device_id = ? AND end_time IS NULL`; // db.query(sql, [end_time, end_time, device_id]); // } // } // old logger.info(`处理电暖器使用事件: 设备ID=${device_id}, 状态=${status}, 温度=${temperature}`); //TODO 1: temperature 类型要确定是数字类型,这个判断 记录 和更新只需要执行一个?下面又对 if (status === 'on' && temperature > 12) { const startTime = new Date(timestamp); logger.debug(`开始记录使用时间: ${startTime}`); const lastRecord = await this.getLastHeaterUsage(device_id); // TODO 2: 在 3 会返回ture,你这个判断永远不会执行,只有表为空的时候才会插入一条 if (!lastRecord || lastRecord.end_time) { logger.info(`插入新的电暖器使用记录: 设备ID=${device_id}`); await this.insertHeaterUsage(device_id, startTime); } } else { logger.info(`更新电暖器使用结束时间: 设备ID=${device_id}`); await this.updateHeaterUsageEndTime(device_id, timestamp); } } catch (error) { logger.error(`处理电暖器使用事件失败: ${error.message}`); throw error; } } // 在getLastHeaterUsage方法中添加更多调试信息 // TODO 3:排序查询从大到小 取第一个?如果有记录会永远返回 static async getLastHeaterUsage(device_id) { logger.debug(`查询设备最后使用记录: 设备ID=${device_id}`); try { const sql = `SELECT * FROM heater_usage WHERE device_id = ? ORDER BY end_time DESC LIMIT 1`; const [results] = await db.query(sql, [device_id]); logger.debug(`查询结果: ${JSON.stringify(results)}`); return results[0] || null; } catch (error) { logger.error(`查询失败: ${error.message}`); throw error; } } // TODO 4:插入数据没更新end_time,,一直为null 上面 3 查询就会一直是第一条,没排序 static async insertHeaterUsage(device_id, startTime) { // 插入新记录 const sql = `INSERT INTO heater_usage (device_id, start_time, end_time, duration, date) VALUES (?, ?, NULL, 0, ?)`; const date = this.getUsageDate(startTime); try { const [results] = await db.query(sql, [device_id, startTime, date]); return results; } catch (error) { logger.error(`插入记录失败: ${error.message}`); throw error; } } static async updateHeaterUsageEndTime(device_id, endTime) { // 更新结束时间并计算时长 const sql = `UPDATE heater_usage SET end_time = ?, duration = TIMESTAMPDIFF(SECOND, start_time, ?) WHERE device_id = ? AND end_time IS NULL`; try { const [results] = await db.query(sql, [endTime, endTime, device_id]); return results; } catch (error) { logger.error(`更新结束时间失败: ${error.message}`); throw error; } } // 修复点2:移除类定义外的多余代码 static getUsageDate(timestamp) { // 获取统计日期(以中午12点为分界) const date = new Date(timestamp); if (date.getHours() < 12) { date.setDate(date.getDate() - 1); //TODO 啥意思?减1毫秒? } return date.toISOString().split('T')[0]; //TODO 只返回年月日 ?估计这一步是更新end_time?检查 4 sql参数 } } module.exports = HeaterUsageService;