package service import ( "sort" "strings" ) // HealthInput 健康画像输入 type HealthInput struct { RecentRiskLevels []string // 近 30 天巡检风险等级 LampPositive int LampTotal int ConsultationCount int TraceCount int } // ComputeHealthScore 综合健康分(0-100)与评级(优/良/中/差) func ComputeHealthScore(in HealthInput) (float64, string) { score := 100.0 for _, level := range in.RecentRiskLevels { switch level { case "red": score -= 25 case "orange": score -= 12 case "yellow": score -= 4 } } if in.LampTotal > 0 { score -= float64(in.LampPositive) / float64(in.LampTotal) * 30 } score -= float64(in.ConsultationCount) * 10 score -= float64(in.TraceCount) * 8 if score < 0 { score = 0 } if score > 100 { score = 100 } grade := "差" switch { case score >= 85: grade = "优" case score >= 70: grade = "良" case score >= 55: grade = "中" } return score, grade } // MonthDiseaseEntry 月度发病条目 type MonthDiseaseEntry struct { Month string Disease string } // MonthStat 月度发病统计 type MonthStat struct { Month string `json:"month"` Total int `json:"total"` Diseases map[string]int `json:"diseases"` } // AggregateMonthlyStats 按月份聚合发病数与病种分布(升序) func AggregateMonthlyStats(entries []MonthDiseaseEntry) []MonthStat { byMonth := make(map[string]*MonthStat) for _, e := range entries { if strings.TrimSpace(e.Month) == "" { continue } s, ok := byMonth[e.Month] if !ok { s = &MonthStat{Month: e.Month, Diseases: map[string]int{}} byMonth[e.Month] = s } s.Total++ s.Diseases[e.Disease]++ } result := make([]MonthStat, 0, len(byMonth)) for _, s := range byMonth { result = append(result, *s) } sort.Slice(result, func(i, j int) bool { return result[i].Month < result[j].Month }) return result }