147 lines
4.0 KiB
Go
147 lines
4.0 KiB
Go
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
|
||
}
|
||
}
|
||
}
|