123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package service
- import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "github.com/PuerkitoBio/goquery"
- v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
- "strings"
- )
- type ParserService interface {
- GetMessage(ctx context.Context, req []byte) (string, error)
- ParseAlert(html string) (message string, err error)
- GetRuleId(ctx context.Context, htmlBytes []byte) (string, error)
- ParseSDKOnlineHTMLTable(htmlContent string) ([]v1.SDKInfo, error)
- }
- func NewParserService(
- service *Service,
- ) ParserService {
- return &parserService{
- Service: service,
- }
- }
- type parserService struct {
- *Service
- }
- // 解析 alert 消息
- func (s *parserService) ParseAlert(html string) (message string, err error) {
- doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
- if err != nil {
- return "", err
- }
- sel := doc.Find(".alert")
- if sel.Length() == 0 {
- // 没有 .alert 元素
- return "", nil
- }
- // 找到 .alert,继续提取
- t := strings.TrimSpace(sel.Find("h4").Text())
- full := strings.TrimSpace(sel.Text())
- full = strings.TrimPrefix(full, "×")
- full = strings.TrimSpace(full)
- m := strings.TrimSpace(strings.TrimPrefix(full, t))
- return m, nil
- }
- func (s *parserService) GetMessage(ctx context.Context, req []byte) (string, error) {
- type msg struct {
- Message string `json:"msg"` // 如果字段叫 msg,用 `json:"msg"`
- }
- var m msg
- if err := json.Unmarshal(req, &m); err != nil {
- return "", fmt.Errorf("解析 message 失败: %v", err)
- }
- if m.Message == "no affect row" {
- return "", fmt.Errorf("没有该条数据")
- }
- return m.Message, nil
- }
- func (s *parserService) GetRuleId(ctx context.Context, htmlBytes []byte) (string, error) {
- // 1. 把 []byte 包成 io.Reader
- reader := bytes.NewReader(htmlBytes)
- // 2. 用 goquery 解析
- doc, err := goquery.NewDocumentFromReader(reader)
- if err != nil {
- return "", err
- }
- // 方法一:按位置拿(第 2 个 tr、第 2 个 td)
- id := doc.
- Find("table.table tbody tr").Eq(1). // 跳过表头行,拿第一条数据
- Find("td").Eq(1).Text() // 第 2 个 td
- return strings.TrimSpace(id), nil
- }
- // 解析 Sdk在线情况 表格
- func (s *parserService) ParseSDKOnlineHTMLTable(htmlContent string) ([]v1.SDKInfo, error) {
- // 创建goquery文档
- doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
- if err != nil {
- return nil, fmt.Errorf("解析HTML失败: %v", err)
- }
- var sdkInfos []v1.SDKInfo
- // 查找表格并解析数据行
- doc.Find("table.table.table-hover tbody tr").Each(func(i int, s *goquery.Selection) {
- // 跳过表头行(如果有的话)
- if s.Find("th").Length() > 0 {
- return
- }
- var info v1.SDKInfo
- // 解析每一列的数据
- s.Find("td").Each(func(j int, td *goquery.Selection) {
- text := strings.TrimSpace(td.Text())
- // 根据列的位置分配到对应字段(跳过第一列的复选框)
- switch j {
- case 1: // 规则ID
- info.RuleID = text
- case 2: // 客户端IP
- info.ClientIP = text
- case 3: // 网关IP
- info.GatewayIP = text
- case 4: // SDK-UUID
- info.SDKUUID = text
- case 5: // 会话ID
- info.SessionID = text
- case 6: // SDK类型
- info.SDKType = text
- case 7: // SDK版本
- info.SDKVersion = text
- case 8: // 系统
- info.System = text
- case 9: // 附加信息
- info.ExtraInfo = text
- }
- })
- // 只有当规则ID不为空时才添加记录
- if info.RuleID != "" {
- sdkInfos = append(sdkInfos, info)
- }
- })
- return sdkInfos, nil
- }
|