Files
silk/server-go/internal/handler/health.go
T

95 lines
2.9 KiB
Go

package handler
import (
"net/http"
"time"
"silk-server-go/internal/middleware"
"silk-server-go/internal/model"
"silk-server-go/internal/service"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// RegisterHealthRoutes 注册蚕房健康画像路由
func RegisterHealthRoutes(rg *gin.RouterGroup, db *gorm.DB) {
rg.GET("/rooms/:id/health-profile",
middleware.RequirePermission(db, "room:read"),
roomHealthProfile(db))
}
// roomHealthProfile 单蚕房健康画像:巡检风险/检测结果/事件聚合 → 综合健康分
func roomHealthProfile(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("id")
var room model.Room
if db.Where("id = ?", id).First(&room).Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "room not found"})
return
}
since := time.Now().Add(-30 * 24 * time.Hour)
// 近 30 天巡检风险分布
var riskRows []struct {
RiskLevel string `gorm:"column:risk_level"`
Cnt int64 `gorm:"column:cnt"`
}
db.Table("inspection_records").
Select("risk_level, count(*) AS cnt").
Where("room_id = ? AND ai_status = 'done' AND risk_level IS NOT NULL AND created_at >= ?", id, since).
Group("risk_level").
Scan(&riskRows)
riskCounts := map[string]int64{}
var riskLevels []string
for _, r := range riskRows {
riskCounts[r.RiskLevel] = r.Cnt
for i := int64(0); i < r.Cnt; i++ {
riskLevels = append(riskLevels, r.RiskLevel)
}
}
// 近 30 天 LAMP/分子检测结果
lampTotal, lampPositive := int64(0), int64(0)
db.Model(&model.LampTest{}).
Where("room_id = ? AND status = 'resulted' AND created_at >= ?", id, since).
Count(&lampTotal)
db.Model(&model.LampTest{}).
Where("room_id = ? AND status = 'resulted' AND result = 'positive' AND created_at >= ?", id, since).
Count(&lampPositive)
// 事件数
var consultationCount, traceCount int64
db.Model(&model.Consultation{}).Where("room_id = ?", id).Count(&consultationCount)
db.Model(&model.TraceRecord{}).Where("room_id = ?", id).Count(&traceCount)
// 当前批次
var batch *model.Batch
var latest model.Batch
if db.Where("room_id = ?", id).Order("created_at DESC").First(&latest).Error == nil {
batch = &latest
}
score, grade := service.ComputeHealthScore(service.HealthInput{
RecentRiskLevels: riskLevels,
LampPositive: int(lampPositive),
LampTotal: int(lampTotal),
ConsultationCount: int(consultationCount),
TraceCount: int(traceCount),
})
c.JSON(http.StatusOK, gin.H{
"roomId": room.ID,
"roomName": room.Name,
"score": score,
"grade": grade,
"riskDistribution": gin.H{
"green": riskCounts["green"], "yellow": riskCounts["yellow"],
"orange": riskCounts["orange"], "red": riskCounts["red"],
},
"lampResults": gin.H{"total": lampTotal, "positive": lampPositive},
"events": gin.H{"consultations": consultationCount, "traces": traceCount},
"batch": batch,
})
}
}