package dao import ( "database/sql" "time" "go_rain_dtu/internal/model" "go_rain_dtu/pkg/logger" ) type SensorDAO struct { db *sql.DB } func NewSensorDAO(db *sql.DB) *SensorDAO { return &SensorDAO{db: db} } // 插入传感器数据 func (dao *SensorDAO) Insert(data *model.SensorData) error { query := ` INSERT INTO sensor_data ( timestamp, wind_speed, wind_force, wind_direction_8, wind_direction_360, humidity, temperature, atm_pressure, solar_radiation, rainfall ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` _, err := dao.db.Exec(query, data.Timestamp, data.WindSpeed, data.WindForce, data.WindDirection8, data.WindDirection360, data.Humidity, data.Temperature, data.AtmPressure, data.SolarRadiation, data.Rainfall, ) if err != nil { logger.Logger.Printf("插入传感器数据失败: %v", err) return err } return nil } // 获取聚合数据 func (dao *SensorDAO) GetAggregatedData(start, end time.Time, interval string) ([]model.AggregatedData, error) { // 参数化时间间隔 var intervalMinutes int var timeFormat string switch interval { case "5min": intervalMinutes = 5 timeFormat = "%Y-%m-%dT%H:%i:00" case "30min": intervalMinutes = 30 timeFormat = "%Y-%m-%dT%H:%i:00" default: // 1hour intervalMinutes = 60 timeFormat = "%Y-%m-%dT%H:00:00" } // 计算秒数 intervalSeconds := intervalMinutes * 60 // 构建通用查询 query := ` SELECT DATE_FORMAT(MIN(timestamp), '%Y-%m-%dT%H:%i:%S') as ts, ROUND(AVG(temperature)/10, 1) as avg_temp, MAX(rainfall) - MIN(rainfall) as rainfall, ROUND(AVG(humidity)/10, 1) as avg_humidity, ROUND(AVG(wind_speed)/10, 1) as avg_wind_speed FROM sensor_data WHERE timestamp BETWEEN ? AND ? GROUP BY FLOOR(UNIX_TIMESTAMP(timestamp)/?) ORDER BY ts DESC ` // 执行查询 rows, err := dao.db.Query( query, start, end, // 时间范围 intervalSeconds, // GROUP BY参数 ) if err != nil { logger.Logger.Printf("查询聚合数据失败: %v (间隔=%s, 开始=%s, 结束=%s)", err, interval, start.Format(time.RFC3339), end.Format(time.RFC3339)) return nil, err } defer rows.Close() var result []model.AggregatedData for rows.Next() { var data model.AggregatedData var tsStr string err := rows.Scan(&tsStr, &data.AvgTemperature, &data.Rainfall, &data.AvgHumidity, &data.AvgWindSpeed) if err != nil { logger.Logger.Printf("扫描数据行失败: %v", err) continue } // 解析ISO格式的时间字符串 data.Timestamp, err = time.Parse("2006-01-02T15:04:05", tsStr) if err != nil { logger.Logger.Printf("解析时间失败: %v, 原始字符串: %s", err, tsStr) continue } result = append(result, data) } // 检查是否有游标错误 if err = rows.Err(); err != nil { logger.Logger.Printf("查询游标错误: %v", err) return nil, err } logger.Logger.Printf("聚合查询成功: 返回%d条记录 (间隔=%s)", len(result), interval) return result, nil }