feat: train record session.

This commit is contained in:
2026-05-02 12:52:49 +08:00
parent f81ee19bed
commit 44ad9ea7f6
4 changed files with 126 additions and 0 deletions
+121
View File
@@ -7,10 +7,15 @@ import (
)
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"hr_receiver/config"
"hr_receiver/models"
"math"
@@ -97,6 +102,122 @@ func (tc *TrainingController) CreateTrainingRecord(c *gin.Context) {
})
}
type trainingSessionRequest struct {
Tid int `json:"tid"`
Time int64 `json:"time"`
TestTime int64 `json:"testTime"`
EndTime int64 `json:"endTime"`
Name string `json:"name"`
RunType string `json:"runType"`
Gender string `json:"gender"`
Age int `json:"age"`
MaxHeartRate int `json:"maxHeartRate"`
Duration int `json:"duration"`
PeopleNum int `json:"peopleNum"`
Evaluation string `json:"evaluation"`
AiResult string `json:"aiResult"`
IsStart bool `json:"isStart"`
RegionID uint32 `json:"regionId"`
AppName string `json:"appName"`
}
func (tc *TrainingController) UploadTrainingSession(c *gin.Context) {
var req trainingSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
writeError(c, http.StatusBadRequest, err.Error())
return
}
trainID := fmt.Sprintf("%d", req.Time)
now := time.Now().UnixMilli()
flavorType := "heartrate"
identifier := schema.NamingStrategy{}.IndexName(
"mqtt_training_session",
fmt.Sprintf("%s_%d_%s", flavorType, req.RegionID, trainID),
)
rawPayload, _ := json.Marshal(req)
if req.IsStart {
record := &models.MqttTrainingSessionRecord{
Identifier: identifier,
TestID: trainID,
EventType: "start_test",
RegionID: req.RegionID,
FlavorType: flavorType,
RawFlavor: "hr",
AppName: req.AppName,
TrainId: trainID,
PeopleNum: req.PeopleNum,
StartedAt: &req.Time,
PublishedAt: now,
ReceivedAt: now,
RawPayload: string(rawPayload),
}
err := tc.DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "identifier"}},
DoUpdates: clause.Assignments(map[string]interface{}{"started_at": *record.StartedAt, "train_id": record.TrainId, "updated_at": time.Now()}),
}).Create(record).Error
if err != nil {
writeError(c, http.StatusInternalServerError, "failed to save session")
return
}
writeSuccess(c, http.StatusOK, "session start registered", nil)
return
}
var existing models.MqttTrainingSessionRecord
err := tc.DB.Where("train_id = ?", trainID).First(&existing).Error
if err != nil {
record := &models.MqttTrainingSessionRecord{
Identifier: identifier,
TestID: trainID,
EventType: "stop_test",
RegionID: req.RegionID,
FlavorType: flavorType,
RawFlavor: "hr",
AppName: req.AppName,
TrainId: trainID,
PeopleNum: req.PeopleNum,
StartedAt: &req.Time,
EndedAt: &req.EndTime,
PublishedAt: now,
ReceivedAt: now,
RawPayload: string(rawPayload),
}
err = tc.DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "identifier"}},
DoUpdates: clause.Assignments(map[string]interface{}{
"ended_at": *record.EndedAt,
"people_num": record.PeopleNum,
"event_type": record.EventType,
"updated_at": time.Now(),
}),
}).Create(record).Error
if err != nil {
writeError(c, http.StatusInternalServerError, "failed to create session")
return
}
writeSuccess(c, http.StatusOK, "session created", nil)
return
}
updates := map[string]interface{}{
"event_type": "stop_test",
"ended_at": req.EndTime,
"people_num": req.PeopleNum,
"received_at": now,
"raw_payload": string(rawPayload),
"updated_at": time.Now(),
}
if err := tc.DB.Model(&existing).Updates(updates).Error; err != nil {
writeError(c, http.StatusInternalServerError, "failed to update session")
return
}
writeSuccess(c, http.StatusOK, "session updated", nil)
}
// analysis_response.go
type AnalysisResponse struct {
Status string `json:"status"` // 状态码