This commit is contained in:
2026-04-07 12:22:57 +08:00
parent bb8bd910e6
commit aaa8308a90
19 changed files with 1389 additions and 5 deletions

112
collector/collector.go Normal file
View File

@@ -0,0 +1,112 @@
package collector
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"git.apinb.com/quant/collector/models"
)
// 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() (*models.Status, 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 models.Status
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 *models.Status) (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() (*models.Status, 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
}

View File

@@ -0,0 +1,58 @@
package collector
import (
"encoding/json"
"os"
"testing"
"git.apinb.com/quant/collector/models"
)
// TestCalculateHash 测试Hash计算功能
func TestCalculateHash(t *testing.T) {
// 读取样本数据
data, err := os.ReadFile("../exmple/status.json")
if err != nil {
t.Fatalf("读取样本文件失败: %v", err)
}
var status models.Status
if err := json.Unmarshal(data, &status); err != nil {
t.Fatalf("JSON解析失败: %v", err)
}
collector := NewCollector("http://localhost:5000/status")
hash, err := collector.CalculateHash(&status)
if err != nil {
t.Fatalf("计算Hash失败: %v", err)
}
if hash == "" {
t.Error("Hash值不能为空")
}
t.Logf("计算的Hash: %s", hash)
}
// TestHasChanged 测试变化检测
func TestHasChanged(t *testing.T) {
collector := NewCollector("http://localhost:5000/status")
// 第一次应该返回true
if !collector.HasChanged("hash1") {
t.Error("第一次检测应该返回true")
}
// 更新hash
collector.UpdateHash("hash1")
// 相同的hash应该返回false
if collector.HasChanged("hash1") {
t.Error("相同的hash应该返回false")
}
// 不同的hash应该返回true
if !collector.HasChanged("hash2") {
t.Error("不同的hash应该返回true")
}
}