c26b06f1cc
Go 控制面(SQLite + REST API)嵌入 Mihomo 数据面,Vue 3 多语言 Web 管理台。 含订阅/节点/规则/出站/监控/日志、OpenAPI、API Key、Gitea Actions CI 与开源文档; CI 使用 ubuntu-latest runner,Go/Docker 步骤走国内镜像与 shell,避免 GitHub 下载超时。 Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
1.8 KiB
Go
71 lines
1.8 KiB
Go
package api
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"github.com/prism/proxy/internal/rulematch"
|
||
)
|
||
|
||
type testRuleReq struct {
|
||
URL string `json:"url"`
|
||
}
|
||
|
||
func (s *Server) mergedRules(c *gin.Context) {
|
||
limit, offset := parseLimitOffset(c.DefaultQuery("limit", "50"), c.DefaultQuery("offset", "0"))
|
||
items, err := s.app.Store.ListMergedRulesPage(c.Request.Context(), limit, offset)
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
total, err := s.app.Store.CountMergedRules(c.Request.Context())
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
settings, _ := s.app.Store.GetSettings(c.Request.Context())
|
||
policy := settings["default_policy"]
|
||
if policy == "" {
|
||
policy = "DIRECT"
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"items": items,
|
||
"total": total,
|
||
"limit": limit,
|
||
"offset": offset,
|
||
"default_policy": policy,
|
||
})
|
||
}
|
||
|
||
func (s *Server) testRule(c *gin.Context) {
|
||
var req testRuleReq
|
||
if err := c.ShouldBindJSON(&req); err != nil || strings.TrimSpace(req.URL) == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "url required"})
|
||
return
|
||
}
|
||
ctx := c.Request.Context()
|
||
rules, err := s.app.Store.ListRules(ctx, "")
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
settings, _ := s.app.Store.GetSettings(ctx)
|
||
policy := settings["default_policy"]
|
||
geoReady := geoDataReady(s.app.DataDir)
|
||
result := rulematch.Match(rules, policy, req.URL, geoReady)
|
||
if result.SkippedGeo > 0 {
|
||
result.Note = appendNote(result.Note, "已跳过 "+strconv.Itoa(result.SkippedGeo)+" 条 Geo 规则(本地测试不支持 GEOIP/GEOSITE)")
|
||
}
|
||
c.JSON(http.StatusOK, result)
|
||
}
|
||
|
||
func appendNote(existing, extra string) string {
|
||
if existing == "" {
|
||
return extra
|
||
}
|
||
return existing + ";" + extra
|
||
}
|