From 44f15e1ff163a5c6f827dafd113953e701d1e984 Mon Sep 17 00:00:00 2001 From: Snowykami Date: Sat, 13 Sep 2025 15:08:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20utils=20=E5=8C=85?= =?UTF-8?q?=E5=8F=8A=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8C=85?= =?UTF-8?q?=E6=8B=AC=20UA=20=E8=A7=A3=E6=9E=90=E5=92=8C=20IP=20=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/utils/client.go | 1 + pkg/utils/ip_info.go | 1 + pkg/utils/ip_info_test.go | 1 + pkg/utils/ua.go | 61 +++++++++++++++++++++++++++++++++++++++ pkg/utils/ua_test.go | 1 + 5 files changed, 65 insertions(+) create mode 100644 pkg/utils/client.go create mode 100644 pkg/utils/ip_info.go create mode 100644 pkg/utils/ip_info_test.go create mode 100644 pkg/utils/ua.go create mode 100644 pkg/utils/ua_test.go diff --git a/pkg/utils/client.go b/pkg/utils/client.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/client.go @@ -0,0 +1 @@ +package utils diff --git a/pkg/utils/ip_info.go b/pkg/utils/ip_info.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/ip_info.go @@ -0,0 +1 @@ +package utils diff --git a/pkg/utils/ip_info_test.go b/pkg/utils/ip_info_test.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/ip_info_test.go @@ -0,0 +1 @@ +package utils diff --git a/pkg/utils/ua.go b/pkg/utils/ua.go new file mode 100644 index 0000000..1d68e07 --- /dev/null +++ b/pkg/utils/ua.go @@ -0,0 +1,61 @@ +package utils + +import "regexp" + +type Result struct { + OS string + OSVersion string + Browser string + BrowserVer string +} + +// ParseUA 解析 UA,返回结构化信息 +func ParseUA(ua string) Result { + r := Result{} + + // 1. 操作系统 + 版本 + osRe := []*regexp.Regexp{ + regexp.MustCompile(`\(Macintosh;.*Mac OS X ([0-9_]+)\)`), + regexp.MustCompile(`\(Windows NT ([0-9.]+)\)`), + regexp.MustCompile(`\(iPhone;.*OS ([0-9_]+)`), + regexp.MustCompile(`\(Android ([0-9.]+)`), + regexp.MustCompile(`\(X11;.*Linux `), + } + for _, re := range osRe { + if m := re.FindStringSubmatch(ua); len(m) > 1 { + switch { + case strings.Contains(m[0], "Macintosh"): + r.OS, r.OSVersion = "macOS", strings.Replace(m[1], "_", ".", -1) + case strings.Contains(m[0], "Windows NT"): + r.OS, r.OSVersion = "Windows", m[1] + case strings.Contains(m[0], "iPhone"): + r.OS, r.OSVersion = "iOS", strings.Replace(m[1], "_", ".", -1) + case strings.Contains(m[0], "Android"): + r.OS, r.OSVersion = "Android", m[1] + case strings.Contains(m[0], "Linux"): + r.OS = "Linux" + } + break + } + } + + // 2. 浏览器 + 版本(按优先级匹配) + browserRe := []struct { + re *regexp.Regexp + name string + }{ + {regexp.MustCompile(`Edg/([\d.]+)`), "Edge"}, + {regexp.MustCompile(`Chrome/([\d.]+)`), "Chrome"}, + {regexp.MustCompile(`Firefox/([\d.]+)`), "Firefox"}, + {regexp.MustCompile(`Version/([\d.]+).*Safari`), "Safari"}, + {regexp.MustCompile(`OPR/([\d.]+)`), "Opera"}, + } + for _, b := range browserRe { + if m := b.re.FindStringSubmatch(ua); len(m) > 1 { + r.Browser, r.BrowserVer = b.name, m[1] + break + } + } + + return r +} diff --git a/pkg/utils/ua_test.go b/pkg/utils/ua_test.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/ua_test.go @@ -0,0 +1 @@ +package utils