Files
2026-05-04 16:20:46 +08:00

147 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}
}
}