更新Web文件

This commit is contained in:
Alex Yang
2025-11-23 18:37:24 +08:00
parent 0072e8a5c2
commit 15c87a9d94
6 changed files with 331 additions and 48 deletions

View File

@@ -8,6 +8,7 @@ import (
"net/http"
"os"
"regexp"
"sort"
"strings"
"sync"
"time"
@@ -30,6 +31,8 @@ type ShieldManager struct {
regexRules []regexRule
regexExceptions []regexRule
hostsMap map[string]string
blockedDomainsCount map[string]int
resolvedDomainsCount map[string]int
rulesMutex sync.RWMutex
updateCtx context.Context
updateCancel context.CancelFunc
@@ -46,6 +49,8 @@ func NewShieldManager(config *config.ShieldConfig) *ShieldManager {
regexRules: []regexRule{},
regexExceptions: []regexRule{},
hostsMap: make(map[string]string),
blockedDomainsCount: make(map[string]int),
resolvedDomainsCount: make(map[string]int),
updateCtx: ctx,
updateCancel: cancel,
}
@@ -62,6 +67,7 @@ func (m *ShieldManager) LoadRules() error {
m.regexRules = []regexRule{}
m.regexExceptions = []regexRule{}
m.hostsMap = make(map[string]string)
// 保留计数数据,不随规则重新加载而清空
// 加载本地规则文件
if err := m.loadLocalRules(); err != nil {
@@ -380,6 +386,106 @@ func (m *ShieldManager) IsBlocked(domain string) bool {
return false
}
// RecordBlockedDomain 记录被屏蔽的域名
func (m *ShieldManager) RecordBlockedDomain(domain string) {
m.rulesMutex.Lock()
defer m.rulesMutex.Unlock()
m.blockedDomainsCount[domain]++
}
// RecordResolvedDomain 记录被解析的域名
func (m *ShieldManager) RecordResolvedDomain(domain string) {
m.rulesMutex.Lock()
defer m.rulesMutex.Unlock()
m.resolvedDomainsCount[domain]++
}
// GetTopBlockedDomains 获取最常被屏蔽的域名
func (m *ShieldManager) GetTopBlockedDomains(limit int) []map[string]interface{} {
m.rulesMutex.RLock()
defer m.rulesMutex.RUnlock()
// 如果没有数据,返回空数组
if len(m.blockedDomainsCount) == 0 {
return []map[string]interface{}{}
}
// 转换为切片以便排序
type domainCount struct {
Domain string
Count int
}
var domains []domainCount
for domain, count := range m.blockedDomainsCount {
domains = append(domains, domainCount{Domain: domain, Count: count})
}
// 按计数降序排序
sort.Slice(domains, func(i, j int) bool {
return domains[i].Count > domains[j].Count
})
// 限制返回数量
if len(domains) > limit {
domains = domains[:limit]
}
// 转换为API响应格式
result := make([]map[string]interface{}, len(domains))
for i, item := range domains {
result[i] = map[string]interface{}{
"domain": item.Domain,
"count": item.Count,
}
}
return result
}
// GetTopResolvedDomains 获取最常被解析的域名
func (m *ShieldManager) GetTopResolvedDomains(limit int) []map[string]interface{} {
m.rulesMutex.RLock()
defer m.rulesMutex.RUnlock()
// 如果没有数据,返回空数组
if len(m.resolvedDomainsCount) == 0 {
return []map[string]interface{}{}
}
// 转换为切片以便排序
type domainCount struct {
Domain string
Count int
}
var domains []domainCount
for domain, count := range m.resolvedDomainsCount {
domains = append(domains, domainCount{Domain: domain, Count: count})
}
// 按计数降序排序
sort.Slice(domains, func(i, j int) bool {
return domains[i].Count > domains[j].Count
})
// 限制返回数量
if len(domains) > limit {
domains = domains[:limit]
}
// 转换为API响应格式
result := make([]map[string]interface{}, len(domains))
for i, item := range domains {
result[i] = map[string]interface{}{
"domain": item.Domain,
"count": item.Count,
}
}
return result
}
// GetHostsIP 获取hosts文件中的IP映射
func (m *ShieldManager) GetHostsIP(domain string) (string, bool) {
m.rulesMutex.RLock()