package api import ( "licserver/internal/service" "net/http" "strconv" "time" "github.com/gin-gonic/gin" ) type TokenHandler struct { tokenService *service.TokenService } func NewTokenHandler(tokenService *service.TokenService) *TokenHandler { return &TokenHandler{tokenService: tokenService} } func (h *TokenHandler) CreateToken(c *gin.Context) { var input struct { DeviceUID string `json:"device_uid" binding:"required"` TokenType string `json:"token_type" binding:"required,oneof=api device"` ExpireDays int `json:"expire_days" binding:"required,min=1"` IPList []string `json:"ip_list"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } expireTime := time.Now().AddDate(0, 0, input.ExpireDays) userID := c.GetUint("userID") token, err := h.tokenService.CreateToken( input.DeviceUID, input.TokenType, expireTime, input.IPList, userID, ) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, token) } func (h *TokenHandler) ValidateToken(c *gin.Context) { token := c.GetHeader("X-Access-Token") if token == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供访问令牌"}) return } clientIP := c.ClientIP() accessToken, err := h.tokenService.ValidateToken(token, clientIP) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, accessToken) } func (h *TokenHandler) RevokeToken(c *gin.Context) { token := c.Param("token") userID := c.GetUint("userID") if err := h.tokenService.RevokeToken(token, userID); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "令牌已撤销"}) } func (h *TokenHandler) GetTokens(c *gin.Context) { deviceUID := c.Query("device_uid") page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10")) tokens, total, err := h.tokenService.GetTokens(deviceUID, page, pageSize) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "code": 0, "message": "获取令牌列表成功", "count": total, "data": tokens, }) } func (h *TokenHandler) GetTokenLogs(c *gin.Context) { tokenID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "无效的令牌ID"}) return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10")) logs, total, err := h.tokenService.GetTokenLogs(uint(tokenID), page, pageSize) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "code": 0, "message": "获取令牌使用日志成功", "count": total, "data": logs, }) }