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 } }