From afbb9bef2896512246d0151983eac742c8385148 Mon Sep 17 00:00:00 2001 From: Eli Yip Date: Thu, 29 May 2025 18:41:06 +0800 Subject: [PATCH] refactor: remove old api dir, rename api2 to api --- {api2 => api}/animation_handlers.go | 2 +- {api2 => api}/device_handlers.go | 2 +- api/handler.go | 468 ---------------------------- api/models.go | 120 +++++-- {api2 => api}/pose_handlers.go | 2 +- api/router.go | 96 ++++-- {api2 => api}/sensor_handlers.go | 2 +- {api2 => api}/system_handlers.go | 2 +- api2/models.go | 111 ------- api2/router.go | 88 ------ main.go | 4 +- 11 files changed, 175 insertions(+), 722 deletions(-) rename {api2 => api}/animation_handlers.go (99%) rename {api2 => api}/device_handlers.go (99%) delete mode 100644 api/handler.go rename {api2 => api}/pose_handlers.go (99%) rename {api2 => api}/sensor_handlers.go (99%) rename {api2 => api}/system_handlers.go (99%) delete mode 100644 api2/models.go delete mode 100644 api2/router.go diff --git a/api2/animation_handlers.go b/api/animation_handlers.go similarity index 99% rename from api2/animation_handlers.go rename to api/animation_handlers.go index 558d872..c842c10 100644 --- a/api2/animation_handlers.go +++ b/api/animation_handlers.go @@ -1,4 +1,4 @@ -package api2 +package api import ( "fmt" diff --git a/api2/device_handlers.go b/api/device_handlers.go similarity index 99% rename from api2/device_handlers.go rename to api/device_handlers.go index dce693b..fedb2e1 100644 --- a/api2/device_handlers.go +++ b/api/device_handlers.go @@ -1,4 +1,4 @@ -package api2 +package api import ( "fmt" diff --git a/api/handler.go b/api/handler.go deleted file mode 100644 index b3a98d1..0000000 --- a/api/handler.go +++ /dev/null @@ -1,468 +0,0 @@ -package api - -import ( - "fmt" - "hands/config" - "hands/define" - "hands/hands" - "net/http" - "time" - - "github.com/gin-gonic/gin" -) - -// 手型设置处理函数 -func HandleHandType(c *gin.Context) { - var req HandTypeRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的手型设置请求:" + err.Error(), - }) - return - } - - // 验证接口 - if !config.IsValidInterface(req.Interface) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", req.Interface, config.Config.AvailableInterfaces), - }) - return - } - - // 验证手型 ID - if req.HandType == "left" && req.HandId != uint32(define.HAND_TYPE_LEFT) { - req.HandId = uint32(define.HAND_TYPE_LEFT) - } else if req.HandType == "right" && req.HandId != uint32(define.HAND_TYPE_RIGHT) { - req.HandId = uint32(define.HAND_TYPE_RIGHT) - } - - // 设置手型配置 - hands.SetHandConfig(req.Interface, req.HandType, req.HandId) - - handTypeName := "右手" - if req.HandType == "left" { - handTypeName = "左手" - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: fmt.Sprintf("接口 %s 手型已设置为%s (0x%X)", req.Interface, handTypeName, req.HandId), - Data: map[string]any{ - "interface": req.Interface, - "handType": req.HandType, - "handId": req.HandId, - }, - }) -} - -// 手指姿态处理函数 -func HandleFingers(c *gin.Context) { - var req FingerPoseRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的手指姿态数据:" + err.Error(), - }) - return - } - - // 验证每个值是否在范围内 - for _, v := range req.Pose { - if v < 0 || v > 255 { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "手指姿态值必须在 0-255 范围内", - }) - return - } - } - - // 如果未指定接口,使用默认接口 - if req.Interface == "" { - req.Interface = config.Config.DefaultInterface - } - - // 验证接口 - if !config.IsValidInterface(req.Interface) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", req.Interface, config.Config.AvailableInterfaces), - }) - return - } - - hands.StopAllAnimations(req.Interface) - - if err := hands.SendFingerPose(req.Interface, req.Pose, req.HandType, req.HandId); err != nil { - c.JSON(http.StatusInternalServerError, define.ApiResponse{ - Status: "error", - Error: "发送手指姿态失败:" + err.Error(), - }) - return - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: "手指姿态指令发送成功", - Data: map[string]any{"interface": req.Interface, "pose": req.Pose}, - }) -} - -// 掌部姿态处理函数 -func HandlePalm(c *gin.Context) { - var req PalmPoseRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的掌部姿态数据:" + err.Error(), - }) - return - } - - // 验证每个值是否在范围内 - for _, v := range req.Pose { - if v < 0 || v > 255 { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "掌部姿态值必须在 0-255 范围内", - }) - return - } - } - - // 如果未指定接口,使用默认接口 - if req.Interface == "" { - req.Interface = config.Config.DefaultInterface - } - - // 验证接口 - if !config.IsValidInterface(req.Interface) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", req.Interface, config.Config.AvailableInterfaces), - }) - return - } - - hands.StopAllAnimations(req.Interface) - - if err := hands.SendPalmPose(req.Interface, req.Pose, req.HandType, req.HandId); err != nil { - c.JSON(http.StatusInternalServerError, define.ApiResponse{ - Status: "error", - Error: "发送掌部姿态失败:" + err.Error(), - }) - return - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: "掌部姿态指令发送成功", - Data: map[string]any{"interface": req.Interface, "pose": req.Pose}, - }) -} - -// 预设姿势处理函数 -func HandlePreset(c *gin.Context) { - pose := c.Param("pose") - - // 从查询参数获取接口名称和手型 - ifName := c.Query("interface") - handType := c.Query("handType") - - if ifName == "" { - ifName = config.Config.DefaultInterface - } - - // 验证接口 - if !config.IsValidInterface(ifName) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", ifName, config.Config.AvailableInterfaces), - }) - return - } - - hands.StopAllAnimations(ifName) - - var fingerPose []byte - var message string - - switch pose { - case "fist": - fingerPose = []byte{64, 64, 64, 64, 64, 64} - message = "已设置握拳姿势" - case "open": - fingerPose = []byte{192, 192, 192, 192, 192, 192} - message = "已设置完全张开姿势" - case "pinch": - fingerPose = []byte{120, 120, 64, 64, 64, 64} - message = "已设置捏取姿势" - case "thumbsup": - fingerPose = []byte{64, 192, 192, 192, 192, 64} - message = "已设置竖起大拇指姿势" - case "point": - fingerPose = []byte{192, 64, 192, 192, 192, 64} - message = "已设置食指指点姿势" - // 数字手势 - case "1": - fingerPose = []byte{192, 64, 192, 192, 192, 64} - message = "已设置数字 1 手势" - case "2": - fingerPose = []byte{192, 64, 64, 192, 192, 64} - message = "已设置数字 2 手势" - case "3": - fingerPose = []byte{192, 64, 64, 64, 192, 64} - message = "已设置数字 3 手势" - case "4": - fingerPose = []byte{192, 64, 64, 64, 64, 64} - message = "已设置数字 4 手势" - case "5": - fingerPose = []byte{192, 192, 192, 192, 192, 192} - message = "已设置数字 5 手势" - case "6": - fingerPose = []byte{64, 192, 192, 192, 192, 64} - message = "已设置数字 6 手势" - case "7": - fingerPose = []byte{64, 64, 192, 192, 192, 64} - message = "已设置数字 7 手势" - case "8": - fingerPose = []byte{64, 64, 64, 192, 192, 64} - message = "已设置数字 8 手势" - case "9": - fingerPose = []byte{64, 64, 64, 64, 192, 64} - message = "已设置数字 9 手势" - default: - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的预设姿势", - }) - return - } - - // 解析手型 ID(从查询参数或使用接口配置) - handId := uint32(0) - if handType != "" { - handId = hands.ParseHandType(handType, 0, ifName) - } - - if err := hands.SendFingerPose(ifName, fingerPose, handType, handId); err != nil { - c.JSON(http.StatusInternalServerError, define.ApiResponse{ - Status: "error", - Error: "设置预设姿势失败:" + err.Error(), - }) - return - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: message, - Data: map[string]any{"interface": ifName, "pose": fingerPose}, - }) -} - -// 动画控制处理函数 -func HandleAnimation(c *gin.Context) { - var req AnimationRequest - if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的动画请求:" + err.Error(), - }) - return - } - - // 如果未指定接口,使用默认接口 - if req.Interface == "" { - req.Interface = config.Config.DefaultInterface - } - - // 验证接口 - if !config.IsValidInterface(req.Interface) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", req.Interface, config.Config.AvailableInterfaces), - }) - return - } - - // 停止当前动画 - hands.StopAllAnimations(req.Interface) - - // 如果是停止命令,直接返回 - if req.Type == "stop" { - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: fmt.Sprintf("%s 动画已停止", req.Interface), - }) - return - } - - // 处理速度参数 - if req.Speed <= 0 { - req.Speed = 500 // 默认速度 - } - - // 根据类型启动动画 - switch req.Type { - case "wave": - hands.StartWaveAnimation(req.Interface, req.Speed, req.HandType, req.HandId) - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: fmt.Sprintf("%s 波浪动画已启动", req.Interface), - Data: map[string]any{"interface": req.Interface, "speed": req.Speed}, - }) - case "sway": - hands.StartSwayAnimation(req.Interface, req.Speed, req.HandType, req.HandId) - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: fmt.Sprintf("%s 横向摆动动画已启动", req.Interface), - Data: map[string]any{"interface": req.Interface, "speed": req.Speed}, - }) - default: - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: "无效的动画类型", - }) - } -} - -// 获取传感器数据处理函数 -func HandleSensors(c *gin.Context) { - // 从查询参数获取接口名称 - ifName := c.Query("interface") - - hands.SensorMutex.RLock() - defer hands.SensorMutex.RUnlock() - - if ifName != "" { - // 验证接口 - if !config.IsValidInterface(ifName) { - c.JSON(http.StatusBadRequest, define.ApiResponse{ - Status: "error", - Error: fmt.Sprintf("无效的接口 %s,可用接口: %v", ifName, config.Config.AvailableInterfaces), - }) - return - } - - // 请求特定接口的数据 - if sensorData, ok := hands.SensorDataMap[ifName]; ok { - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Data: sensorData, - }) - } else { - c.JSON(http.StatusInternalServerError, define.ApiResponse{ - Status: "error", - Error: "传感器数据不存在", - }) - } - } else { - // 返回所有接口的数据 - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Data: hands.SensorDataMap, - }) - } -} - -// 系统状态处理函数 -func HandleStatus(c *gin.Context) { - hands.AnimationMutex.Lock() - animationStatus := make(map[string]bool) - for _, ifName := range config.Config.AvailableInterfaces { - animationStatus[ifName] = hands.AnimationActive[ifName] - } - hands.AnimationMutex.Unlock() - - // 检查 CAN 服务状态 - canStatus := hands.CheckCanServiceStatus() - - // 获取手型配置 - hands.HandConfigMutex.RLock() - handConfigsData := make(map[string]any) - for ifName, handConfig := range hands.HandConfigs { - handConfigsData[ifName] = map[string]any{ - "handType": handConfig.HandType, - "handId": handConfig.HandId, - } - } - hands.HandConfigMutex.RUnlock() - - interfaceStatuses := make(map[string]any) - for _, ifName := range config.Config.AvailableInterfaces { - interfaceStatuses[ifName] = map[string]any{ - "active": canStatus[ifName], - "animationActive": animationStatus[ifName], - "handConfig": handConfigsData[ifName], - } - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Data: map[string]any{ - "interfaces": interfaceStatuses, - "uptime": time.Since(ServerStartTime).String(), - "canServiceURL": config.Config.CanServiceURL, - "defaultInterface": config.Config.DefaultInterface, - "availableInterfaces": config.Config.AvailableInterfaces, - "activeInterfaces": len(canStatus), - "handConfigs": handConfigsData, - }, - }) -} - -// 获取可用接口列表处理函数 -func HandleInterfaces(c *gin.Context) { - responseData := map[string]any{ - "availableInterfaces": config.Config.AvailableInterfaces, - "defaultInterface": config.Config.DefaultInterface, - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Data: responseData, - }) -} - -// 获取手型配置处理函数 -func HandleHandConfigs(c *gin.Context) { - hands.HandConfigMutex.RLock() - defer hands.HandConfigMutex.RUnlock() - - result := make(map[string]any) - for _, ifName := range config.Config.AvailableInterfaces { - if handConfig, exists := hands.HandConfigs[ifName]; exists { - result[ifName] = map[string]any{ - "handType": handConfig.HandType, - "handId": handConfig.HandId, - } - } else { - // 返回默认配置 - result[ifName] = map[string]any{ - "handType": "right", - "handId": define.HAND_TYPE_RIGHT, - } - } - } - - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Data: result, - }) -} - -// 健康检查处理函数 -func HandleHealth(c *gin.Context) { - c.JSON(http.StatusOK, define.ApiResponse{ - Status: "success", - Message: "CAN Control Service is running", - Data: map[string]any{ - "timestamp": time.Now(), - "availableInterfaces": config.Config.AvailableInterfaces, - "defaultInterface": config.Config.DefaultInterface, - "serviceVersion": "1.0.0-hand-type-support", - }, - }) -} diff --git a/api/models.go b/api/models.go index 9f09550..d38193b 100644 --- a/api/models.go +++ b/api/models.go @@ -1,29 +1,111 @@ package api -type FingerPoseRequest struct { - Interface string `json:"interface,omitempty"` - Pose []byte `json:"pose" binding:"required,len=6"` - HandType string `json:"handType,omitempty"` // 新增:手型类型 - HandId uint32 `json:"handId,omitempty"` // 新增:CAN ID +import ( + "hands/device" + "time" +) + +// ===== 通用响应模型 ===== + +// ApiResponse 统一 API 响应格式(保持与原 API 兼容) +type ApiResponse struct { + Status string `json:"status"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` + Data any `json:"data,omitempty"` } -type PalmPoseRequest struct { - Interface string `json:"interface,omitempty"` - Pose []byte `json:"pose" binding:"required,len=4"` - HandType string `json:"handType,omitempty"` // 新增:手型类型 - HandId uint32 `json:"handId,omitempty"` // 新增:CAN ID +// ===== 设备管理相关模型 ===== + +// DeviceCreateRequest 创建设备请求 +type DeviceCreateRequest struct { + ID string `json:"id" binding:"required"` + Model string `json:"model" binding:"required"` + Config map[string]any `json:"config"` + HandType string `json:"handType,omitempty"` // "left" 或 "right" } -type AnimationRequest struct { - Interface string `json:"interface,omitempty"` - Type string `json:"type" binding:"required,oneof=wave sway stop"` - Speed int `json:"speed" binding:"min=0,max=2000"` - HandType string `json:"handType,omitempty"` // 新增:手型类型 - HandId uint32 `json:"handId,omitempty"` // 新增:CAN ID +// DeviceInfo 设备信息响应 +type DeviceInfo struct { + ID string `json:"id"` + Model string `json:"model"` + HandType string `json:"handType"` + Status device.DeviceStatus `json:"status"` } +// DeviceListResponse 设备列表响应 +type DeviceListResponse struct { + Devices []DeviceInfo `json:"devices"` + Total int `json:"total"` +} + +// HandTypeRequest 手型设置请求 type HandTypeRequest struct { - Interface string `json:"interface" binding:"required"` - HandType string `json:"handType" binding:"required,oneof=left right"` - HandId uint32 `json:"handId" binding:"required"` + HandType string `json:"handType" binding:"required,oneof=left right"` +} + +// ===== 姿态控制相关模型 ===== + +// FingerPoseRequest 手指姿态设置请求 +type FingerPoseRequest struct { + Pose []byte `json:"pose" binding:"required,len=6"` +} + +// PalmPoseRequest 手掌姿态设置请求 +type PalmPoseRequest struct { + Pose []byte `json:"pose" binding:"required,len=4"` +} + +// ===== 动画控制相关模型 ===== + +// AnimationStartRequest 动画启动请求 +type AnimationStartRequest struct { + Name string `json:"name" binding:"required"` + SpeedMs int `json:"speedMs,omitempty"` +} + +// AnimationStatusResponse 动画状态响应 +type AnimationStatusResponse struct { + IsRunning bool `json:"isRunning"` + CurrentName string `json:"currentName,omitempty"` + AvailableList []string `json:"availableList"` +} + +// ===== 传感器相关模型 ===== + +// SensorDataResponse 传感器数据响应 +type SensorDataResponse struct { + SensorID string `json:"sensorId"` + Timestamp time.Time `json:"timestamp"` + Values map[string]any `json:"values"` +} + +// SensorListResponse 传感器列表响应 +type SensorListResponse struct { + Sensors []SensorDataResponse `json:"sensors"` + Total int `json:"total"` +} + +// ===== 系统管理相关模型 ===== + +// SystemStatusResponse 系统状态响应 +type SystemStatusResponse struct { + TotalDevices int `json:"totalDevices"` + ActiveDevices int `json:"activeDevices"` + SupportedModels []string `json:"supportedModels"` + Devices map[string]DeviceInfo `json:"devices"` + Uptime time.Duration `json:"uptime"` +} + +// SupportedModelsResponse 支持的设备型号响应 +type SupportedModelsResponse struct { + Models []string `json:"models"` + Total int `json:"total"` +} + +// HealthResponse 健康检查响应 +type HealthResponse struct { + Status string `json:"status"` + Timestamp time.Time `json:"timestamp"` + Version string `json:"version,omitempty"` } diff --git a/api2/pose_handlers.go b/api/pose_handlers.go similarity index 99% rename from api2/pose_handlers.go rename to api/pose_handlers.go index 1df5232..25ca358 100644 --- a/api2/pose_handlers.go +++ b/api/pose_handlers.go @@ -1,4 +1,4 @@ -package api2 +package api import ( "fmt" diff --git a/api/router.go b/api/router.go index b7987c2..bf6036d 100644 --- a/api/router.go +++ b/api/router.go @@ -1,50 +1,88 @@ package api import ( + "hands/device" "time" "github.com/gin-gonic/gin" ) -// 全局变量 -var ( - ServerStartTime time.Time -) +// Server API v2 服务器结构体 +type Server struct { + deviceManager *device.DeviceManager + startTime time.Time + version string +} -func SetupRoutes(r *gin.Engine) { +// NewServer 创建新的 API v1 服务器实例 +func NewServer(deviceManager *device.DeviceManager) *Server { + return &Server{ + deviceManager: deviceManager, + startTime: time.Now(), + version: "1.0.0", + } +} + +// SetupRoutes 设置 API v1 路由 +func (s *Server) SetupRoutes(r *gin.Engine) { r.StaticFile("/", "./static/index.html") r.Static("/static", "./static") - api := r.Group("/api") + // API v1 路由组 + v2 := r.Group("/api/v1") { - // 手型设置 API - api.POST("/hand-type", HandleHandType) + // 设备管理路由 + devices := v2.Group("/devices") + { + devices.GET("", s.handleGetDevices) // 获取所有设备列表 + devices.POST("", s.handleCreateDevice) // 创建新设备 + devices.GET("/:deviceId", s.handleGetDevice) // 获取设备详情 + devices.DELETE("/:deviceId", s.handleDeleteDevice) // 删除设备 + devices.PUT("/:deviceId/hand-type", s.handleSetHandType) // 设置手型 - // 手指姿态 API - api.POST("/fingers", HandleFingers) + // 设备级别的功能路由 + deviceRoutes := devices.Group("/:deviceId") + { + // 姿态控制路由 + poses := deviceRoutes.Group("/poses") + { + poses.POST("/fingers", s.handleSetFingerPose) // 设置手指姿态 + poses.POST("/palm", s.handleSetPalmPose) // 设置手掌姿态 + poses.POST("/preset/:pose", s.handleSetPresetPose) // 设置预设姿势 + poses.POST("/reset", s.handleResetPose) // 重置姿态 - // 掌部姿态 API - api.POST("/palm", HandlePalm) + // 新的预设姿势 API + poses.GET("/presets", s.GetSupportedPresets) // 获取支持的预设姿势列表 + poses.POST("/presets/:presetName", s.ExecutePresetPose) // 执行预设姿势 + } - // 预设姿势 API - api.POST("/preset/:pose", HandlePreset) + // 动画控制路由 + animations := deviceRoutes.Group("/animations") + { + animations.GET("", s.handleGetAnimations) // 获取可用动画列表 + animations.POST("/start", s.handleStartAnimation) // 启动动画 + animations.POST("/stop", s.handleStopAnimation) // 停止动画 + animations.GET("/status", s.handleAnimationStatus) // 获取动画状态 + } - // 动画控制 API - api.POST("/animation", HandleAnimation) + // 传感器数据路由 + sensors := deviceRoutes.Group("/sensors") + { + sensors.GET("", s.handleGetSensors) // 获取所有传感器数据 + sensors.GET("/:sensorId", s.handleGetSensorData) // 获取特定传感器数据 + } - // 获取传感器数据 API - api.GET("/sensors", HandleSensors) + // 设备状态路由 + deviceRoutes.GET("/status", s.handleGetDeviceStatus) // 获取设备状态 + } + } - // 系统状态 API - api.GET("/status", HandleStatus) - - // 获取可用接口列表 API - api.GET("/interfaces", HandleInterfaces) - - // 获取手型配置 API - api.GET("/hand-configs", HandleHandConfigs) - - // 健康检查端点 - api.GET("/health", HandleHealth) + // 系统管理路由 + system := v2.Group("/system") + { + system.GET("/models", s.handleGetSupportedModels) // 获取支持的设备型号 + system.GET("/status", s.handleGetSystemStatus) // 获取系统状态 + system.GET("/health", s.handleHealthCheck) // 健康检查 + } } } diff --git a/api2/sensor_handlers.go b/api/sensor_handlers.go similarity index 99% rename from api2/sensor_handlers.go rename to api/sensor_handlers.go index 6cf1322..67a35f8 100644 --- a/api2/sensor_handlers.go +++ b/api/sensor_handlers.go @@ -1,4 +1,4 @@ -package api2 +package api import ( "fmt" diff --git a/api2/system_handlers.go b/api/system_handlers.go similarity index 99% rename from api2/system_handlers.go rename to api/system_handlers.go index db11d67..012ba21 100644 --- a/api2/system_handlers.go +++ b/api/system_handlers.go @@ -1,4 +1,4 @@ -package api2 +package api import ( "net/http" diff --git a/api2/models.go b/api2/models.go deleted file mode 100644 index c94dc41..0000000 --- a/api2/models.go +++ /dev/null @@ -1,111 +0,0 @@ -package api2 - -import ( - "hands/device" - "time" -) - -// ===== 通用响应模型 ===== - -// ApiResponse 统一 API 响应格式(保持与原 API 兼容) -type ApiResponse struct { - Status string `json:"status"` - Message string `json:"message,omitempty"` - Error string `json:"error,omitempty"` - Data any `json:"data,omitempty"` -} - -// ===== 设备管理相关模型 ===== - -// DeviceCreateRequest 创建设备请求 -type DeviceCreateRequest struct { - ID string `json:"id" binding:"required"` - Model string `json:"model" binding:"required"` - Config map[string]any `json:"config"` - HandType string `json:"handType,omitempty"` // "left" 或 "right" -} - -// DeviceInfo 设备信息响应 -type DeviceInfo struct { - ID string `json:"id"` - Model string `json:"model"` - HandType string `json:"handType"` - Status device.DeviceStatus `json:"status"` -} - -// DeviceListResponse 设备列表响应 -type DeviceListResponse struct { - Devices []DeviceInfo `json:"devices"` - Total int `json:"total"` -} - -// HandTypeRequest 手型设置请求 -type HandTypeRequest struct { - HandType string `json:"handType" binding:"required,oneof=left right"` -} - -// ===== 姿态控制相关模型 ===== - -// FingerPoseRequest 手指姿态设置请求 -type FingerPoseRequest struct { - Pose []byte `json:"pose" binding:"required,len=6"` -} - -// PalmPoseRequest 手掌姿态设置请求 -type PalmPoseRequest struct { - Pose []byte `json:"pose" binding:"required,len=4"` -} - -// ===== 动画控制相关模型 ===== - -// AnimationStartRequest 动画启动请求 -type AnimationStartRequest struct { - Name string `json:"name" binding:"required"` - SpeedMs int `json:"speedMs,omitempty"` -} - -// AnimationStatusResponse 动画状态响应 -type AnimationStatusResponse struct { - IsRunning bool `json:"isRunning"` - CurrentName string `json:"currentName,omitempty"` - AvailableList []string `json:"availableList"` -} - -// ===== 传感器相关模型 ===== - -// SensorDataResponse 传感器数据响应 -type SensorDataResponse struct { - SensorID string `json:"sensorId"` - Timestamp time.Time `json:"timestamp"` - Values map[string]any `json:"values"` -} - -// SensorListResponse 传感器列表响应 -type SensorListResponse struct { - Sensors []SensorDataResponse `json:"sensors"` - Total int `json:"total"` -} - -// ===== 系统管理相关模型 ===== - -// SystemStatusResponse 系统状态响应 -type SystemStatusResponse struct { - TotalDevices int `json:"totalDevices"` - ActiveDevices int `json:"activeDevices"` - SupportedModels []string `json:"supportedModels"` - Devices map[string]DeviceInfo `json:"devices"` - Uptime time.Duration `json:"uptime"` -} - -// SupportedModelsResponse 支持的设备型号响应 -type SupportedModelsResponse struct { - Models []string `json:"models"` - Total int `json:"total"` -} - -// HealthResponse 健康检查响应 -type HealthResponse struct { - Status string `json:"status"` - Timestamp time.Time `json:"timestamp"` - Version string `json:"version,omitempty"` -} diff --git a/api2/router.go b/api2/router.go deleted file mode 100644 index bf3d2cf..0000000 --- a/api2/router.go +++ /dev/null @@ -1,88 +0,0 @@ -package api2 - -import ( - "hands/device" - "time" - - "github.com/gin-gonic/gin" -) - -// Server API v2 服务器结构体 -type Server struct { - deviceManager *device.DeviceManager - startTime time.Time - version string -} - -// NewServer 创建新的 API v2 服务器实例 -func NewServer(deviceManager *device.DeviceManager) *Server { - return &Server{ - deviceManager: deviceManager, - startTime: time.Now(), - version: "2.0.0", - } -} - -// SetupRoutes 设置 API v2 路由 -func (s *Server) SetupRoutes(r *gin.Engine) { - r.StaticFile("/", "./static/index.html") - r.Static("/static", "./static") - - // API v2 路由组 - v2 := r.Group("/api/v2") - { - // 设备管理路由 - devices := v2.Group("/devices") - { - devices.GET("", s.handleGetDevices) // 获取所有设备列表 - devices.POST("", s.handleCreateDevice) // 创建新设备 - devices.GET("/:deviceId", s.handleGetDevice) // 获取设备详情 - devices.DELETE("/:deviceId", s.handleDeleteDevice) // 删除设备 - devices.PUT("/:deviceId/hand-type", s.handleSetHandType) // 设置手型 - - // 设备级别的功能路由 - deviceRoutes := devices.Group("/:deviceId") - { - // 姿态控制路由 - poses := deviceRoutes.Group("/poses") - { - poses.POST("/fingers", s.handleSetFingerPose) // 设置手指姿态 - poses.POST("/palm", s.handleSetPalmPose) // 设置手掌姿态 - poses.POST("/preset/:pose", s.handleSetPresetPose) // 设置预设姿势 - poses.POST("/reset", s.handleResetPose) // 重置姿态 - - // 新的预设姿势 API - poses.GET("/presets", s.GetSupportedPresets) // 获取支持的预设姿势列表 - poses.POST("/presets/:presetName", s.ExecutePresetPose) // 执行预设姿势 - } - - // 动画控制路由 - animations := deviceRoutes.Group("/animations") - { - animations.GET("", s.handleGetAnimations) // 获取可用动画列表 - animations.POST("/start", s.handleStartAnimation) // 启动动画 - animations.POST("/stop", s.handleStopAnimation) // 停止动画 - animations.GET("/status", s.handleAnimationStatus) // 获取动画状态 - } - - // 传感器数据路由 - sensors := deviceRoutes.Group("/sensors") - { - sensors.GET("", s.handleGetSensors) // 获取所有传感器数据 - sensors.GET("/:sensorId", s.handleGetSensorData) // 获取特定传感器数据 - } - - // 设备状态路由 - deviceRoutes.GET("/status", s.handleGetDeviceStatus) // 获取设备状态 - } - } - - // 系统管理路由 - system := v2.Group("/system") - { - system.GET("/models", s.handleGetSupportedModels) // 获取支持的设备型号 - system.GET("/status", s.handleGetSystemStatus) // 获取系统状态 - system.GET("/health", s.handleHealthCheck) // 健康检查 - } - } -} diff --git a/main.go b/main.go index 4bdaa74..9d5dcda 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "hands/api2" + "hands/api" "hands/cli" "hands/config" "hands/device" @@ -95,7 +95,7 @@ func main() { models.RegisterDeviceTypes() // 设置 API 路由 - api2.NewServer(device.NewDeviceManager()).SetupRoutes(r) + api.NewServer(device.NewDeviceManager()).SetupRoutes(r) // 启动服务器 log.Printf("🌐 CAN 控制服务运行在 http://localhost:%s", config.Config.WebPort)