低空智控平台 后端go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

155 lines
3.5 KiB

package middleware
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"laic-backend/common"
"laic-backend/model"
"laic-backend/service"
)
// OperationLogMiddleware 记录设备控制写操作(POST/PUT/DELETE)到 operation_log
func OperationLogMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
if !isMutating(c.Request.Method) {
c.Next()
return
}
path := c.Request.URL.Path
if !isDeviceOperation(path) {
c.Next()
return
}
c.Next()
userID := c.GetInt64("user_id")
if userID == 0 {
return
}
result := "success"
if c.Writer.Status() >= http.StatusBadRequest {
result = "failed"
}
userName := c.GetString("username")
if name := resolveUserName(userID); name != "" {
userName = name
}
service.DefaultOperationLogService.Record(
userID, userName,
resolveModule(path), resolveAction(c.Request.Method, path),
path, result, c.ClientIP(),
)
}
}
func isMutating(method string) bool {
return method == http.MethodPost || method == http.MethodPut || method == http.MethodDelete
}
func isDeviceOperation(path string) bool {
parts := strings.Split(strings.Trim(path, "/"), "/")
if len(parts) < 3 || parts[0] != "v1" {
return false
}
switch parts[1] {
case "docks":
return len(parts) >= 4 && (parts[3] == "command" || parts[3] == "firmware")
case "tasks":
return len(parts) >= 4 && parts[3] == "execute"
case "alarms":
return len(parts) >= 4 && (parts[3] == "acknowledge" || parts[3] == "resolve")
case "live":
return len(parts) >= 4 && (parts[3] == "start" || parts[3] == "stop")
default:
return false
}
}
// resolveUserName 从 DB 读取用户显示名(快照),失败回退为空(由调用方回退 phone)
func resolveUserName(userID int64) string {
var u model.User
if err := common.DB.Select("name").First(&u, userID).Error; err == nil {
return u.Name
}
return ""
}
// resolveModule 将路径首个资源段映射为中文模块名
func resolveModule(path string) string {
parts := strings.Split(strings.Trim(path, "/"), "/")
if len(parts) < 2 {
return "系统"
}
switch parts[1] {
case "users":
return "用户管理"
case "roles":
return "角色管理"
case "docks":
return "机巢管理"
case "drones":
return "无人机管理"
case "alarms":
return "告警管理"
case "commands":
return "指令管理"
case "routes":
return "航线管理"
case "tasks":
return "任务管理"
case "executions":
return "执行记录"
case "firmwares":
return "固件管理"
case "live":
return "直播管理"
case "videos":
return "视频管理"
case "account":
return "账户中心"
case "logs":
return "系统管理"
case "auth":
return "认证"
default:
return "系统"
}
}
// resolveAction 将 HTTP 方法 + 路径末尾段映射为中文动作
func resolveAction(method, path string) string {
seg := path
if i := strings.LastIndex(seg, "/"); i >= 0 {
seg = seg[i+1:]
}
special := map[string]string{
"execute": "执行任务",
"command": "下发指令",
"upgrade": "下发升级",
"pay": "支付订单",
"download": "下载视频",
"start": "开始直播",
"stop": "停止直播",
"complete": "确认上传",
"recharge": "充值",
"resolve": "处理告警",
"acknowledge": "确认告警",
"logout": "退出登录",
}
if a, ok := special[seg]; ok {
return a
}
switch method {
case http.MethodPost:
return "新增"
case http.MethodPut:
return "修改"
case http.MethodDelete:
return "删除"
default:
return method
}
}