feat(server-go): 区域发病统计(#22,rooms.region + region-stats)

This commit is contained in:
weijuesen
2026-08-13 08:53:00 +08:00
parent 15f09dcdee
commit 7949f90c0c
4 changed files with 106 additions and 0 deletions
+29
View File
@@ -3,6 +3,7 @@ package handler
import (
"encoding/json"
"net/http"
"strconv"
"time"
"silk-server-go/internal/middleware"
@@ -18,6 +19,7 @@ func RegisterTraceRoutes(rg *gin.RouterGroup, db *gorm.DB) {
read := middleware.RequirePermission(db, "trace:read")
write := middleware.RequirePermission(db, "trace:write")
rg.GET("/trace-records", read, listTraceRecords(db))
rg.GET("/trace-records/region-stats", read, traceRegionStats(db))
rg.GET("/trace-records/:id", read, getTraceRecord(db))
rg.POST("/trace-records", write, createTraceRecord(db))
rg.PATCH("/trace-records/:id", write, updateTraceRecord(db))
@@ -27,6 +29,33 @@ func RegisterTraceRoutes(rg *gin.RouterGroup, db *gorm.DB) {
rg.POST("/trace-records/:id/checklist", write, submitTraceChecklist(db))
}
// traceRegionStats 区域发病统计(近 N 天,按蚕房 region 聚合)
func traceRegionStats(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
days := 90
if d, err := strconv.Atoi(c.DefaultQuery("days", "90")); err == nil && d > 0 && d <= 365 {
days = d
}
q := db.Table("trace_records").
Select("rooms.region AS region, trace_records.disease AS disease").
Joins("LEFT JOIN rooms ON rooms.id = trace_records.room_id").
Where("trace_records.created_at >= ?", time.Now().Add(-time.Duration(days)*24*time.Hour))
if disease := c.Query("disease"); disease != "" {
q = q.Where("trace_records.disease = ?", disease)
}
var rows []struct {
Region string `gorm:"column:region"`
Disease string `gorm:"column:disease"`
}
q.Scan(&rows)
entries := make([]service.RegionDiseaseEntry, 0, len(rows))
for _, r := range rows {
entries = append(entries, service.RegionDiseaseEntry{Region: r.Region, Disease: r.Disease})
}
c.JSON(http.StatusOK, service.AggregateRegionStats(entries))
}
}
func listTraceRecords(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
q := db.Model(&model.TraceRecord{})