feat: 交叉验证 AI vs LAMP(#15,一致确认/不一致升级会诊)
This commit is contained in:
@@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -26,6 +27,7 @@ func RegisterLampRoutes(rg *gin.RouterGroup, db *gorm.DB, s3 *service.S3Service,
|
||||
rg.GET("/lamp-tests/:id/steps", read, listLampTestSteps(db))
|
||||
rg.PATCH("/lamp-tests/:id/steps/:stepNo", write, updateLampTestStep(db))
|
||||
rg.POST("/lamp-tests/:id/result-image", write, uploadLampResultImage(db, s3, imageBucket))
|
||||
rg.GET("/lamp-tests/:id/cross-validation", read, getLampCrossValidation(db))
|
||||
}
|
||||
|
||||
// listLampTests 检测任务单列表(roomId/batchId/status 过滤)
|
||||
@@ -97,6 +99,8 @@ func updateLampTest(db *gorm.DB) gin.HandlerFunc {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
resultSet := false
|
||||
resultValue := ""
|
||||
if r, ok := updates["result"]; ok {
|
||||
result, _ := r.(string)
|
||||
if result != "" && !model.ValidLampResult(result) {
|
||||
@@ -109,15 +113,86 @@ func updateLampTest(db *gorm.DB) gin.HandlerFunc {
|
||||
} else {
|
||||
updates["status"] = "testing"
|
||||
}
|
||||
resultSet = true
|
||||
resultValue = result
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
db.Model(&model.LampTest{}).Where("id = ?", id).Updates(updates)
|
||||
}
|
||||
// 交叉验证:结果落库后与同房间最近巡检比对
|
||||
if resultSet && resultValue != "" {
|
||||
_ = runCrossValidation(db, id, resultValue)
|
||||
}
|
||||
db.Where("id = ?", id).First(&t)
|
||||
c.JSON(http.StatusOK, t)
|
||||
}
|
||||
}
|
||||
|
||||
// runCrossValidation 用同房间最近的巡检记录做交叉验证,并回写 cross_status/cross_reason
|
||||
func runCrossValidation(db *gorm.DB, lampTestID, lampResult string) error {
|
||||
var t model.LampTest
|
||||
if err := db.Where("id = ?", lampTestID).First(&t).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if t.RoomID == nil {
|
||||
return nil
|
||||
}
|
||||
var inspection model.InspectionRecord
|
||||
if err := db.Where("room_id = ?", *t.RoomID).Order("created_at DESC").First(&inspection).Error; err != nil {
|
||||
return nil // 无关联巡检,保持 pending
|
||||
}
|
||||
var detections []service.AIDetection
|
||||
if len(inspection.Detections) > 0 {
|
||||
_ = json.Unmarshal(inspection.Detections, &detections)
|
||||
}
|
||||
aiClass := service.AIClassFromDetections(detections)
|
||||
var diseases []string
|
||||
if len(t.Diseases) > 0 {
|
||||
_ = json.Unmarshal(t.Diseases, &diseases)
|
||||
}
|
||||
ok, reason := service.CrossValidate(aiClass, lampResult, diseases)
|
||||
status := "inconsistent"
|
||||
if ok {
|
||||
status = "consistent"
|
||||
}
|
||||
return db.Model(&model.LampTest{}).Where("id = ?", lampTestID).
|
||||
Updates(map[string]interface{}{"cross_status": status, "cross_reason": reason}).Error
|
||||
}
|
||||
|
||||
// getLampCrossValidation 交叉验证详情(含关联巡检摘要)
|
||||
func getLampCrossValidation(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var t model.LampTest
|
||||
if db.Where("id = ?", id).First(&t).Error != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "lamp test not found"})
|
||||
return
|
||||
}
|
||||
var related map[string]interface{}
|
||||
if t.RoomID != nil {
|
||||
var inspection model.InspectionRecord
|
||||
if db.Where("room_id = ?", *t.RoomID).Order("created_at DESC").First(&inspection).Error == nil {
|
||||
var detections []service.AIDetection
|
||||
if len(inspection.Detections) > 0 {
|
||||
_ = json.Unmarshal(inspection.Detections, &detections)
|
||||
}
|
||||
related = map[string]interface{}{
|
||||
"id": inspection.ID,
|
||||
"imageUrl": inspection.ImageURL,
|
||||
"aiClass": service.AIClassFromDetections(detections),
|
||||
"riskLevel": inspection.RiskLevel,
|
||||
"createdAt": inspection.CreatedAt,
|
||||
}
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"crossStatus": t.CrossStatus,
|
||||
"crossReason": t.CrossReason,
|
||||
"relatedInspection": related,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// deleteLampTest 删除任务单(级联删除步骤)
|
||||
func deleteLampTest(db *gorm.DB) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user