package model import ( "database/sql" "fmt" "time" "weatherstation/config" _ "github.com/lib/pq" ) var db *sql.DB func InitDB() error { cfg := config.GetConfig() connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", cfg.Database.Host, cfg.Database.Port, cfg.Database.User, cfg.Database.Password, cfg.Database.DBName, cfg.Database.SSLMode) var err error db, err = sql.Open("postgres", connStr) if err != nil { return fmt.Errorf("无法连接到数据库: %v", err) } err = db.Ping() if err != nil { return fmt.Errorf("数据库连接测试失败: %v", err) } return nil } func CloseDB() { if db != nil { db.Close() } } func ensureStationExists(stationID, password string) error { if db == nil { return fmt.Errorf("数据库未初始化") } var count int err := db.QueryRow("SELECT COUNT(*) FROM stations WHERE station_id = $1", stationID).Scan(&count) if err != nil { return fmt.Errorf("查询站点失败: %v", err) } if count == 0 { _, err = db.Exec("INSERT INTO stations (station_id, password) VALUES ($1, $2)", stationID, password) if err != nil { return fmt.Errorf("添加站点失败: %v", err) } } else { _, err = db.Exec("UPDATE stations SET password = $1, last_update = $2 WHERE station_id = $3", password, time.Now(), stationID) if err != nil { return fmt.Errorf("更新站点失败: %v", err) } } return nil } func SaveWeatherData(data *WeatherData, rawData string) error { if db == nil { return fmt.Errorf("数据库未初始化") } err := ensureStationExists(data.StationID, data.Password) if err != nil { return err } cst := time.FixedZone("CST", 8*60*60) timestamp := time.Now().In(cst) _, err = db.Exec(` INSERT INTO weather_data ( station_id, timestamp, temp_f, humidity, dewpoint_f, windchill_f, wind_dir, wind_speed_mph, wind_gust_mph, rain_in, daily_rain_in, weekly_rain_in, monthly_rain_in, yearly_rain_in, total_rain_in, solar_radiation, uv, indoor_temp_f, indoor_humidity, abs_barometer_in, barometer_in, low_battery, raw_data ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23)`, data.StationID, timestamp, int(data.TempF*10), data.Humidity, int(data.DewpointF*10), int(data.WindchillF*10), data.WindDir, int(data.WindSpeedMph*100), int(data.WindGustMph*100), int(data.RainIn*1000), int(data.DailyRainIn*1000), int(data.WeeklyRainIn*1000), int(data.MonthlyRainIn*1000), int(data.YearlyRainIn*1000), int(data.TotalRainIn*1000), int(data.SolarRadiation*100), data.UV, int(data.IndoorTempF*10), data.IndoorHumidity, int(data.AbsBarometerIn*1000), int(data.BarometerIn*1000), data.LowBattery, rawData) if err != nil { return fmt.Errorf("保存气象数据失败: %v", err) } return nil }