package controllers import ( "errors" "hr_receiver/config" "hr_receiver/models" "hr_receiver/mqtt" "hr_receiver/util" "net/http" "strings" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) type SystemDebugController struct{} type mqttDebugStartRequest struct { PersistToDatabase bool `json:"persistToDatabase"` } var debugUpgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } func NewSystemDebugController() *SystemDebugController { return &SystemDebugController{} } // @Summary 获取MQTT调试状态 // @Description 获取MQTT调试服务的当前运行状态 // @Tags 系统调试 // @Produce json // @Security BearerAuth // @Success 200 {object} SwagAPIResponse "查询成功" // @Router /admin/system-debug/mqtt/status [get] func (sc *SystemDebugController) MqttStatus(c *gin.Context) { service := mqtt.GetDebugService() if service == nil { writeError(c, http.StatusServiceUnavailable, "mqtt debug service unavailable") return } writeSuccess(c, http.StatusOK, "query success", service.Status()) } // @Summary 启动MQTT调试 // @Description 启动MQTT调试服务 // @Tags 系统调试 // @Accept json // @Produce json // @Param persist body mqttDebugStartRequest false "是否持久化到数据库" // @Security BearerAuth // @Success 200 {object} SwagAPIResponse "启动成功" // @Router /admin/system-debug/mqtt/start [post] func (sc *SystemDebugController) StartMqtt(c *gin.Context) { service := mqtt.GetDebugService() if service == nil { writeError(c, http.StatusServiceUnavailable, "mqtt debug service unavailable") return } var payload mqttDebugStartRequest if err := c.ShouldBindJSON(&payload); err != nil && !errors.Is(err, http.ErrBodyNotAllowed) { writeError(c, http.StatusBadRequest, err.Error()) return } if err := service.Start(payload.PersistToDatabase); err != nil { writeError(c, http.StatusInternalServerError, err.Error()) return } writeSuccess(c, http.StatusOK, "start success", service.Status()) } // @Summary 停止MQTT调试 // @Description 停止MQTT调试服务 // @Tags 系统调试 // @Produce json // @Security BearerAuth // @Success 200 {object} SwagAPIResponse "停止成功" // @Router /admin/system-debug/mqtt/stop [post] func (sc *SystemDebugController) StopMqtt(c *gin.Context) { service := mqtt.GetDebugService() if service == nil { writeError(c, http.StatusServiceUnavailable, "mqtt debug service unavailable") return } service.Stop() writeSuccess(c, http.StatusOK, "stop success", service.Status()) } // @Summary MQTT WebSocket连接 // @Description 通过WebSocket实时监听MQTT消息(需要SuperAdmin权限) // @Tags 系统调试 // @Param token query string true "JWT Token" // @Success 101 "切换为WebSocket协议" // @Router /admin/system-debug/mqtt/ws [get] func (sc *SystemDebugController) MqttWebSocket(c *gin.Context) { service := mqtt.GetDebugService() if service == nil { c.JSON(http.StatusServiceUnavailable, gin.H{"error": "mqtt debug service unavailable"}) return } token := strings.TrimSpace(c.Query("token")) if token == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "missing token"}) return } claims, err := util.ParseToken(token) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"}) return } var user models.User if err := config.DB.First(&user, claims.UserID).Error; err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } if !user.IsActive { c.JSON(http.StatusForbidden, gin.H{"error": "user is disabled"}) return } if util.IsTokenRevoked(&user, claims) { c.JSON(http.StatusUnauthorized, gin.H{"error": "token has been revoked"}) return } if user.Role != models.UserRoleSuperAdmin { c.JSON(http.StatusForbidden, gin.H{"error": "super admin required"}) return } conn, err := debugUpgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { return } service.AddSubscriber(conn) defer service.RemoveSubscriber(conn) for { if _, _, err := conn.ReadMessage(); err != nil { break } } }