Files
collector/internal/logic/collector.go
2026-04-17 14:50:34 +08:00

113 lines
2.3 KiB
Go

package logic
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"git.apinb.com/quant/collector/internal/types"
)
// Collector 数据采集器
type Collector struct {
url string
httpClient *http.Client
lastHash string
}
// NewCollector 创建新的采集器
func NewCollector(url string) *Collector {
return &Collector{
url: url,
httpClient: &http.Client{
Timeout: 10 * time.Second,
},
lastHash: "",
}
}
// FetchData 从HTTP接口获取数据
func (c *Collector) FetchData() (*types.StatusData, error) {
resp, err := c.httpClient.Get(c.url)
if err != nil {
return nil, fmt.Errorf("HTTP请求失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP状态码错误: %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取响应失败: %w", err)
}
var status types.StatusData
if err := json.Unmarshal(body, &status); err != nil {
return nil, fmt.Errorf("JSON解析失败: %w", err)
}
return &status, nil
}
// CalculateHash 计算数据的SHA256哈希值
func (c *Collector) CalculateHash(status *types.StatusData) (string, error) {
// 将数据序列化为JSON
data, err := json.Marshal(status)
if err != nil {
return "", fmt.Errorf("序列化数据失败: %w", err)
}
// 计算SHA256哈希
hash := sha256.Sum256(data)
return hex.EncodeToString(hash[:]), nil
}
// HasChanged 检查数据是否发生变化
func (c *Collector) HasChanged(currentHash string) bool {
if c.lastHash == "" {
return true // 第一次采集
}
return c.lastHash != currentHash
}
// UpdateHash 更新上次哈希值
func (c *Collector) UpdateHash(hash string) {
c.lastHash = hash
}
// GetLastHash 获取上次哈希值
func (c *Collector) GetLastHash() string {
return c.lastHash
}
// CollectAndCheck 采集数据并检查是否变化
func (c *Collector) CollectAndCheck() (*types.StatusData, string, bool, error) {
// 获取数据
status, err := c.FetchData()
if err != nil {
return nil, "", false, err
}
// 计算哈希
currentHash, err := c.CalculateHash(status)
if err != nil {
return nil, "", false, err
}
// 检查是否变化
changed := c.HasChanged(currentHash)
// 如果变化了,更新哈希
if changed {
c.UpdateHash(currentHash)
}
return status, currentHash, changed, nil
}