HeaterUsageService.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. const db = require('../config/db');
  2. const logger = require('../logger');
  3. // 移除这一行重复的引用声明
  4. // -const HeaterUsageService = require('../services/HeaterUsageService');
  5. // 保留正确的类定义
  6. class HeaterUsageService {
  7. // 在handleHeaterUsage方法中添加数据验证
  8. static async handleHeaterUsage(device_id, status, temperature, timestamp) {
  9. try {
  10. if (!device_id || !timestamp) {
  11. throw new Error('设备ID和时间戳不能为空');
  12. }
  13. // TODO 0: 总体逻辑:1. 当当前设备状态为开并且温度大于12,开始插入数据库并记录开始时间 2. 当当前状态关闭时并且查询到有大于12的记录,插入结束时间并计算时长
  14. // TODO 举例:
  15. // if (status === 'on' && temperature > 12) {
  16. // // 开始插入开始时间
  17. // const sql = `INSERT INTO heater_usage (device_id, start_time, end_time, duration) VALUES (?, ?, NULL, 0)`;
  18. // db.query(sql, [device_id, startTime]);
  19. // }else{
  20. // // 查询是否有当前设置大于12的数据:其实就是最近开始时间的一条
  21. // const sql1 = `SELECT * FROM heater_usage WHERE device_id = ? ORDER BY start_time DESC LIMIT 1`;
  22. // const [results] =await db.query(sql1, [device_id]);
  23. // // 如果有就计算
  24. // if(results.length){
  25. // // 在当前结果中,插入结束时间并计算时长,结束时间就取当前结束的时间
  26. // // TODO 5 这里应该是修改当前查询到的信息,奈何sql不精,哈哈哈,下面的仅做参考
  27. // const end_time = Date.now();
  28. // const sql = `UPDATE heater_usage
  29. // SET end_time = ?,
  30. // duration = TIMESTAMPDIFF(SECOND, start_time, ?)
  31. // WHERE device_id = ? AND end_time IS NULL`;
  32. // db.query(sql, [end_time, end_time, device_id]);
  33. // }
  34. // }
  35. // old
  36. logger.info(`处理电暖器使用事件: 设备ID=${device_id}, 状态=${status}, 温度=${temperature}`);
  37. //TODO 1: temperature 类型要确定是数字类型,这个判断 记录 和更新只需要执行一个?下面又对
  38. if (status === 'on' && temperature > 12) {
  39. const startTime = new Date(timestamp);
  40. logger.debug(`开始记录使用时间: ${startTime}`);
  41. const lastRecord = await this.getLastHeaterUsage(device_id);
  42. // TODO 2: 在 3 会返回ture,你这个判断永远不会执行,只有表为空的时候才会插入一条
  43. if (!lastRecord || lastRecord.end_time) {
  44. logger.info(`插入新的电暖器使用记录: 设备ID=${device_id}`);
  45. await this.insertHeaterUsage(device_id, startTime);
  46. }
  47. } else {
  48. logger.info(`更新电暖器使用结束时间: 设备ID=${device_id}`);
  49. await this.updateHeaterUsageEndTime(device_id, timestamp);
  50. }
  51. } catch (error) {
  52. logger.error(`处理电暖器使用事件失败: ${error.message}`);
  53. throw error;
  54. }
  55. }
  56. // 在getLastHeaterUsage方法中添加更多调试信息
  57. // TODO 3:排序查询从大到小 取第一个?如果有记录会永远返回
  58. static async getLastHeaterUsage(device_id) {
  59. logger.debug(`查询设备最后使用记录: 设备ID=${device_id}`);
  60. try {
  61. const sql = `SELECT * FROM heater_usage WHERE device_id = ? ORDER BY end_time DESC LIMIT 1`;
  62. const [results] = await db.query(sql, [device_id]);
  63. logger.debug(`查询结果: ${JSON.stringify(results)}`);
  64. return results[0] || null;
  65. } catch (error) {
  66. logger.error(`查询失败: ${error.message}`);
  67. throw error;
  68. }
  69. }
  70. // TODO 4:插入数据没更新end_time,,一直为null 上面 3 查询就会一直是第一条,没排序
  71. static async insertHeaterUsage(device_id, startTime) {
  72. // 插入新记录
  73. const sql = `INSERT INTO heater_usage (device_id, start_time, end_time, duration, date) VALUES (?, ?, NULL, 0, ?)`;
  74. const date = this.getUsageDate(startTime);
  75. try {
  76. const [results] = await db.query(sql, [device_id, startTime, date]);
  77. return results;
  78. } catch (error) {
  79. logger.error(`插入记录失败: ${error.message}`);
  80. throw error;
  81. }
  82. }
  83. static async updateHeaterUsageEndTime(device_id, endTime) {
  84. // 更新结束时间并计算时长
  85. const sql = `UPDATE heater_usage
  86. SET end_time = ?,
  87. duration = TIMESTAMPDIFF(SECOND, start_time, ?)
  88. WHERE device_id = ? AND end_time IS NULL`;
  89. try {
  90. const [results] = await db.query(sql, [endTime, endTime, device_id]);
  91. return results;
  92. } catch (error) {
  93. logger.error(`更新结束时间失败: ${error.message}`);
  94. throw error;
  95. }
  96. }
  97. // 修复点2:移除类定义外的多余代码
  98. static getUsageDate(timestamp) {
  99. // 获取统计日期(以中午12点为分界)
  100. const date = new Date(timestamp);
  101. if (date.getHours() < 12) {
  102. date.setDate(date.getDate() - 1); //TODO 啥意思?减1毫秒?
  103. }
  104. return date.toISOString().split('T')[0]; //TODO 只返回年月日 ?估计这一步是更新end_time?检查 4 sql参数
  105. }
  106. }
  107. module.exports = HeaterUsageService;