package control_case import ( "encoding/csv" "fmt" "net/http" "os" "path/filepath" "strconv" "strings" "control/analize" "github.com/che4web/go4rest" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type ControlCaseController struct { *go4rest.ViewSet[ControlCase] db *gorm.DB } func NewControlCaseController(db *gorm.DB) *ControlCaseController { viewSet := go4rest.NewViewSet[ControlCase](db) viewSet.PreloadField = []string{"Params"} return &ControlCaseController{ ViewSet: viewSet, db: db, } } type ParamsController struct { *go4rest.ViewSet[Params] db *gorm.DB } func NewParamsController(db *gorm.DB) *ParamsController { return &ParamsController{ ViewSet: go4rest.NewViewSet[Params](db), db: db, } } type LaunchControlCaseRequest struct { ParamsID uint `json:"params_id" binding:"required"` Name string `json:"name"` } func (c *ControlCaseController) Launch(ctx *gin.Context) { var req LaunchControlCaseRequest if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var params Params if err := c.db.First(¶ms, req.ParamsID).Error; err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "params not found"}) return } name := req.Name if strings.TrimSpace(name) == "" { name = fmt.Sprintf("case-%d", params.ID) } controlCase := ControlCase{ Name: name, ParamsID: params.ID, Status: "N", } if err := c.db.Create(&controlCase).Error; err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if err := c.db.Preload("Params").First(&controlCase, controlCase.ID).Error; err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ctx.JSON(http.StatusCreated, controlCase) } type CSVSeriesResponse struct { Columns []string `json:"columns"` Rows [][]interface{} `json:"rows"` } func (c *ControlCaseController) ChartData(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) return } var controlCase ControlCase if err := c.db.Preload("Params").First(&controlCase, id).Error; err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) return } csvPath := filepath.Join(".", strconv.FormatUint(uint64(controlCase.ParamsID), 10), "foo.csv") file, err := os.Open(csvPath) if err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "csv file not found"}) return } defer file.Close() reader := csv.NewReader(file) records, err := reader.ReadAll() if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if len(records) == 0 { ctx.JSON(http.StatusOK, CSVSeriesResponse{Columns: []string{}, Rows: [][]interface{}{}}) return } columns := records[0] rows := make([][]interface{}, 0, len(records)-1) for _, record := range records[1:] { row := make([]interface{}, 0, len(record)) for _, value := range record { trimmed := strings.TrimSpace(value) if f, err := strconv.ParseFloat(trimmed, 64); err == nil { row = append(row, f) } else { row = append(row, trimmed) } } rows = append(rows, row) } ctx.JSON(http.StatusOK, CSVSeriesResponse{Columns: columns, Rows: rows}) } func (c *ControlCaseController) RecalculateAnalysis(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) return } var controlCase ControlCase if err := c.db.First(&controlCase, id).Error; err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) return } csvPath := filepath.Join(".", strconv.FormatUint(uint64(controlCase.ParamsID), 10), "foo.csv") result, err := analize.AnalyzeCSV(c.db, controlCase.ID, controlCase.Name, csvPath) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ctx.JSON(http.StatusOK, result) } func (c *ControlCaseController) FieldMap(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) return } timeValue, err := strconv.ParseFloat(ctx.Query("time"), 64) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid time"}) return } var controlCase ControlCase if err := c.db.First(&controlCase, id).Error; err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) return } h5Path := filepath.Join(".", strconv.FormatUint(uint64(controlCase.ParamsID), 10), "storage.h5") result, err := ReadNearestFieldMap(h5Path, timeValue) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ctx.JSON(http.StatusOK, result) }