package service import ( "crypto/rand" "encoding/hex" "errors" "strings" "time" "licserver/internal/model" "gorm.io/gorm" ) type TokenService struct { db *gorm.DB } func NewTokenService(db *gorm.DB) *TokenService { return &TokenService{db: db} } // 生成访问令牌 func generateToken() (string, error) { b := make([]byte, 32) if _, err := rand.Read(b); err != nil { return "", err } return hex.EncodeToString(b), nil } // 创建访问令牌 func (s *TokenService) CreateToken(deviceUID, tokenType string, expireTime time.Time, ipList []string, createdBy uint) (*model.AccessToken, error) { // 验证设备是否存在 var device model.Device if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil { return nil, errors.New("设备不存在") } // 生成令牌 token, err := generateToken() if err != nil { return nil, err } // 创建令牌记录 accessToken := &model.AccessToken{ Token: token, DeviceUID: deviceUID, Type: tokenType, Status: "active", ExpireTime: expireTime, IPList: strings.Join(ipList, ","), CreatedBy: createdBy, } if err := s.db.Create(accessToken).Error; err != nil { return nil, err } // 记录日志 tokenLog := &model.TokenLog{ TokenID: accessToken.ID, Action: "create", Status: "success", Message: "创建访问令牌", } s.db.Create(tokenLog) return accessToken, nil } // 验证令牌 func (s *TokenService) ValidateToken(token, ip string) (*model.AccessToken, error) { var accessToken model.AccessToken if err := s.db.Where("token = ?", token).First(&accessToken).Error; err != nil { return nil, errors.New("无效的令牌") } // 检查令牌状态 if accessToken.Status != "active" { return nil, errors.New("令牌已被撤销") } // 检查过期时间 if time.Now().After(accessToken.ExpireTime) { return nil, errors.New("令牌已过期") } // 检查IP限制 if accessToken.IPList != "" { allowedIPs := strings.Split(accessToken.IPList, ",") allowed := false for _, allowedIP := range allowedIPs { if allowedIP == ip { allowed = true break } } if !allowed { return nil, errors.New("IP地址不允许访问") } } // 更新使用记录 s.db.Model(&accessToken).Updates(map[string]interface{}{ "last_used": time.Now(), "usage_count": gorm.Expr("usage_count + 1"), }) // 记录日志 tokenLog := &model.TokenLog{ TokenID: accessToken.ID, Action: "use", IP: ip, Status: "success", } s.db.Create(tokenLog) return &accessToken, nil } // 撤销令牌 func (s *TokenService) RevokeToken(token string, userID uint) error { var accessToken model.AccessToken if err := s.db.Where("token = ?", token).First(&accessToken).Error; err != nil { return errors.New("令牌不存在") } // 检查权限 if accessToken.CreatedBy != userID { return errors.New("无权操作此令牌") } // 更新状态 if err := s.db.Model(&accessToken).Update("status", "revoked").Error; err != nil { return err } // 记录日志 tokenLog := &model.TokenLog{ TokenID: accessToken.ID, Action: "revoke", Status: "success", Message: "撤销访问令牌", } s.db.Create(tokenLog) return nil } // 获取令牌列表 func (s *TokenService) GetTokens(deviceUID string, page, pageSize int) ([]model.AccessToken, int64, error) { var tokens []model.AccessToken var total int64 query := s.db.Model(&model.AccessToken{}) if deviceUID != "" { query = query.Where("device_uid = ?", deviceUID) } query.Count(&total) if page > 0 && pageSize > 0 { offset := (page - 1) * pageSize query = query.Offset(offset).Limit(pageSize) } err := query.Order("created_at DESC").Find(&tokens).Error return tokens, total, err } // 获取令牌日志 func (s *TokenService) GetTokenLogs(tokenID uint, page, pageSize int) ([]model.TokenLog, int64, error) { var logs []model.TokenLog var total int64 query := s.db.Model(&model.TokenLog{}).Where("token_id = ?", tokenID) query.Count(&total) if page > 0 && pageSize > 0 { offset := (page - 1) * pageSize query = query.Offset(offset).Limit(pageSize) } err := query.Order("created_at DESC").Find(&logs).Error return logs, total, err }