package controllers import ( "context" "encoding/json" "errors" "fwh-toolbox-server/database" "fwh-toolbox-server/ext/api/fwh_pro" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type StateConfig struct { Enable bool `bson:"enable" json:"enable"` } type SocConfig struct { Enable bool `bson:"enable" json:"enable"` } type APowerConfig struct { Enable bool `bson:"enable" json:"enable"` } type AlarmConfig struct { Enable bool `bson:"enable" json:"enable"` } type VersionConfig struct { Enable bool `bson:"enable" json:"enable"` } type TariffsConfig struct { Enable bool `bson:"enable" json:"enable"` } type OthersConfig struct { Enable bool `bson:"enable" json:"enable"` } type MonitorPageConfig struct { State StateConfig `bson:"state" json:"state"` Soc SocConfig `bson:"soc" json:"soc"` APower APowerConfig `bson:"aPower" json:"aPower"` Alarm AlarmConfig `bson:"alarm" json:"alarm"` Version VersionConfig `bson:"version" json:"version"` Tariffs TariffsConfig `bson:"tariffs" json:"tariffs"` Others OthersConfig `bson:"others" json:"others"` } type SitesMonitorConfig struct { Name string `bson:"name" json:"name"` Description string `bson:"description" json:"description"` SiteList []string `bson:"siteList" json:"siteList"` PageConfig *MonitorPageConfig `bson:"pageConfig,omitempty" json:"pageConfig,omitempty"` } type SiteInfoPara struct { SiteList []string `json:"siteList"` PageSize uint `json:"pageSize"` PageNum uint `json:"pageNum"` } type SiteInfo struct { Id string `json:"id"` Name *string `json:"name"` FhpSn string `json:"fhpSn"` ActiveStatus int `json:"activeStatus"` ActiveTime string `json:"activeTime"` Country string `json:"country"` Province string `json:"province"` City string `json:"city"` OnOffStatus int `json:"onOffStatus"` RealSysHdVersion string `json:"realSysHdVersion"` RunStatus int `json:"runStatus"` Version string `json:"version"` } type SiteInfoResponse struct { Code int `json:"code"` Msg string `json:"msg"` Result []SiteInfo `json:"result"` } type WorkModeInfo struct { Id uint `json:"id"` OldIndex uint `json:"oldIndex"` Name string `json:"name"` Soc float32 `json:"soc"` MaxSoc float32 `json:"maxSoc"` MinSoc float32 `json:"minSoc"` DischargeDepthSoc *float32 `json:"dischargeDepthSoc"` WorkMode uint `json:"workMode"` EnergyIncentivesType uint `json:"energyIncentivesType"` ElectricityType uint `json:"electricityType"` } type SiteModeInfo struct { CurrendId uint `json:"currendId"` List []WorkModeInfo `json:"list"` } type SiteModeInfoResponse struct { Code int `json:"code"` Msg string `json:"msg"` Result SiteModeInfo `json:"result"` Success bool `json:"success"` } type SitePowerFlow struct { Index uint `json:"index"` // 非当天为0,当天为实时数量 DeviceTimeArray []string `json:"deviceTimeArray"` // 设备本地时间,格式 “2025-08-18 00:00:00” PowerFhpArray []float32 `json:"powerFhpArray"` PowerGenArray []float32 `json:"powerGenArray"` PowerLoadArray []float32 `json:"powerLoadArray"` PowerSunArray []float32 `json:"powerSunArray"` PowerUtiArray []float32 `json:"powerUtiArray"` SocArray []float32 `json:"socArray"` RunStatusArray []uint `json:"runStatusArray"` // 运行状态,0:待机;1:充电;2:放电;3:故障 KwhTotalArray []float32 `json:"kwhTotalArray"` // 总可用电量,应该是根据SOC推算出来的。 } type SitePowerFlowResponse struct { Code int `json:"code"` Msg string `json:"msg"` Result SitePowerFlow `json:"result"` } type SiteAlarmList struct { Id uint `json:"id"` GatewayId string `json:"gatewayId"` AlarmEqSn string `json:"alarmEqSn"` AlarmCode string `json:"alarmCode"` CommonAlarmCode string `json:"commonAlarmCode"` Level int `json:"level"` Time string `json:"time"` LogName string `json:"logName"` CommonLogName string `json:"commonLogName"` LogNameEn string `json:"logNameEn"` CommonLogNameEn string `json:"commonLogNameEn"` } type SiteAlarmListResponse struct { Code int `json:"code"` Message string `json:"message"` Result []SiteAlarmList `json:"result"` Success bool `json:"success"` Total uint `json:"total"` } type Progress string // 'pending' | 'running' | 'error' | 'complete' type SiteAnalysisInfo struct { Id uint64 `bson:"id" json:"id"` Sn string `bson:"sn" json:"sn"` Description string `bson:"description" json:"description"` Item []string `bson:"item" json:"item"` Progress Progress `bson:"progress" json:"progress"` } // 从数据库获取站点分析列表 func GetSiteAnalysisList() ([]SiteAnalysisInfo, error) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") cursor, err := collection.Find(ctx, bson.M{}) // 空条件,查全部 if err != nil { return nil, err } defer cursor.Close(ctx) var configList []SitesMonitorConfig for cursor.Next(ctx) { var cfg SitesMonitorConfig if err := cursor.Decode(&cfg); err != nil { return nil, err } configList = append(configList, cfg) } return configList, nil } // 从数据库获取站点监控配置列表 func GetSiteMonitorConfig() ([]SitesMonitorConfig, error) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") cursor, err := collection.Find(ctx, bson.M{}) // 空条件,查全部 if err != nil { return nil, err } defer cursor.Close(ctx) var configList []SitesMonitorConfig for cursor.Next(ctx) { var cfg SitesMonitorConfig if err := cursor.Decode(&cfg); err != nil { return nil, err } configList = append(configList, cfg) } return configList, nil } // 从数据库获取监控名列表 func GetSiteMonitorNameList() ([]string, error) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") cursor, err := collection.Find( ctx, bson.M{}, // 空条件,查全部 options.Find().SetProjection(bson.M{ "name": 1, // 只要 name 字段 "_id": 0, // 不要 _id 字段(默认会返回) }), ) if err != nil { return nil, err } defer cursor.Close(ctx) var nameList []string for cursor.Next(ctx) { var result struct { Name string `bson:"name"` } if err := cursor.Decode(&result); err != nil { return nil, err } nameList = append(nameList, result.Name) } return nameList, nil } // 从数据库获取一条站点监控配置 func GetOneSiteMonitorConfig(name string) ([]SitesMonitorConfig, error) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") var cfg SitesMonitorConfig err := collection.FindOne(ctx, bson.M{"name": name}).Decode(&cfg) if err == mongo.ErrNoDocuments { return []SitesMonitorConfig{}, nil } else if err != nil { return nil, err } var configList []SitesMonitorConfig configList = append(configList, cfg) return configList, nil } // 插入一条站点监控配置到数据库 func InsertSiteMonitorConfig(config SitesMonitorConfig) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") // _, err := collection.InsertOne(ctx, config) filter := bson.M{"name": config.Name} // 按用户名匹配 update := bson.M{ "$set": config, // 如果存在就更新所有字段 } opts := options.Update().SetUpsert(true) _, err := collection.UpdateOne(ctx, filter, update, opts) if err != nil { return err } return nil } // 更新一条站点监控配置到数据库 func UpdateSiteMonitorConfig(name string, config SitesMonitorConfig) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") // _, err := collection.InsertOne(ctx, config) filter := bson.M{"name": name} // 按用户名匹配 update := bson.M{ "$set": config, // 如果存在就更新所有字段 } opts := options.Update().SetUpsert(true) _, err := collection.UpdateOne(ctx, filter, update, opts) if err != nil { return err } return nil } // 删除一条站点监控配置 func DeleteSiteMonitorConfig(name string) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() filter := bson.M{"name": name} // 删除条件 collection := database.GetCollection("SiteMonitorConfig") _, err := collection.DeleteOne(ctx, filter) if err != nil { return err } return nil } // 更新一条站点监控页面配置到数据库 func UpdateSiteMonitorPageConfig(name string, config MonitorPageConfig) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() collection := database.GetCollection("SiteMonitorConfig") // _, err := collection.InsertOne(ctx, config) filter := bson.M{"name": name} // 按用户名匹配 update := bson.M{ "$set": bson.M{ "pageConfig": config, // 更新页面配置字段 }, } opts := options.Update().SetUpsert(true) _, err := collection.UpdateOne(ctx, filter, update, opts) if err != nil { return err } return nil } // 从fwh_pro获取站点信息表 func QuerySiteInfoList(para SiteInfoPara) (SiteInfoResponse, error) { resByte, err := fwh_pro.QuerySiteInfoList(para.SiteList, para.PageSize, para.PageNum) if err != nil { return SiteInfoResponse{}, err } var siteInfoRes SiteInfoResponse // 反序列化(unmarshal) jsonErr := json.Unmarshal(resByte, &siteInfoRes) if jsonErr != nil { return SiteInfoResponse{}, jsonErr } if siteInfoRes.Code == 401 { // TODO 尝试重新登录 return SiteInfoResponse{}, errors.New("certification expired") } return siteInfoRes, nil } // 从fwh_pro获取站点工作模式信息 func QuerySiteModeInfo(site string) (SiteModeInfoResponse, error) { resByte, err := fwh_pro.QuerySiteModeInfo(site) if err != nil { return SiteModeInfoResponse{}, err } var siteModeInfoRes SiteModeInfoResponse // 反序列化(unmarshal) jsonErr := json.Unmarshal(resByte, &siteModeInfoRes) if jsonErr != nil { return SiteModeInfoResponse{}, jsonErr } if siteModeInfoRes.Code == 401 { // TODO 尝试重新登录 return SiteModeInfoResponse{}, errors.New("certification expired") } return siteModeInfoRes, nil } // 从fwh_pro获取站点功率流 func QuerySitePowerFlow(site string, day time.Time) (SitePowerFlowResponse, error) { resByte, err := fwh_pro.QuerySitePowerFlow(site, day) if err != nil { return SitePowerFlowResponse{}, err } var sitePowerFlowRes SitePowerFlowResponse // 反序列化(unmarshal) jsonErr := json.Unmarshal(resByte, &sitePowerFlowRes) if jsonErr != nil { return SitePowerFlowResponse{}, jsonErr } if sitePowerFlowRes.Code == 401 { // TODO 尝试重新登录 return SitePowerFlowResponse{}, errors.New("certification expired") } return sitePowerFlowRes, nil } // 从fwh_pro获取站点告警列表 func QuerySiteAlarmList(site string) (SiteAlarmListResponse, error) { resByte, err := fwh_pro.QuerySiteAlarmList(site) if err != nil { return SiteAlarmListResponse{}, err } var siteAlarmListRes SiteAlarmListResponse // 反序列化(unmarshal) jsonErr := json.Unmarshal(resByte, &siteAlarmListRes) if jsonErr != nil { return SiteAlarmListResponse{}, jsonErr } if siteAlarmListRes.Code == 401 { // TODO 尝试重新登录 return SiteAlarmListResponse{}, errors.New("certification expired") } return siteAlarmListRes, nil }