feat(service): 优化地址解析逻辑以支持端口号直接解析

重构 parseTraditionalStyle 函数,简化 NetworkAddress 构造方式,
并引入 utils.IsNumber 判断纯端口号情况,提升地址解析的准确性与兼容性。
```
This commit is contained in:
yanweidong 2025-09-23 13:26:47 +08:00
parent 75aa6ae647
commit 139983134b
2 changed files with 140 additions and 13 deletions

View File

@ -5,6 +5,8 @@ import (
"net"
"net/url"
"strings"
"git.apinb.com/bsm-sdk/core/utils"
)
type NetworkAddress struct {
@ -126,28 +128,24 @@ func determineTCPProtocol(host string) string {
// 解析传统格式如 ":8080", "127.0.0.1:8080", "/tmp/socket"
func parseTraditionalStyle(addr string) (*NetworkAddress, error) {
result := &NetworkAddress{Raw: addr}
// 检查是否是 Unix socket包含路径分隔符
if strings.Contains(addr, "/") || strings.HasPrefix(addr, "@/") {
result.Protocol = "unix"
result.Path = addr
return result, nil
return &NetworkAddress{Protocol: "unix", Path: addr}, nil
}
// 否则按 TCP 地址解析
result.Protocol = "tcp"
host, port, err := net.SplitHostPort(addr)
if err != nil {
return nil, fmt.Errorf("解析地址失败: %w", err)
if err == nil {
return &NetworkAddress{Protocol: "tcp", Host: host, Port: port}, nil
}
result.Host = host
result.Port = port
result.Protocol = determineTCPProtocol(host)
// 检查是否是端口号
if ok := utils.IsNumber(addr); ok {
return &NetworkAddress{Protocol: "tcp", Host: "0.0.0.0", Port: addr}, nil
}
return nil, fmt.Errorf("解析地址失败: %w", err)
return result, nil
}
// 获取网络类型用于 net.Dial 或 net.Listen

129
utils/validator.go Normal file
View File

@ -0,0 +1,129 @@
package utils
import (
"regexp"
"strings"
"unicode"
)
// IsEmail 验证是否是邮箱格式
func IsEmail(email string) bool {
if strings.TrimSpace(email) == "" {
return false
}
// 邮箱正则表达式
pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
matched, err := regexp.MatchString(pattern, email)
if err != nil {
return false
}
return matched
}
// IsMobile 验证是否是手机号(中国手机号格式)
func IsMobile(mobile string) bool {
if strings.TrimSpace(mobile) == "" {
return false
}
// 中国手机号正则表达式1开头第二位3-9后面9位数字
pattern := `^1[3-9]\d{9}$`
matched, err := regexp.MatchString(pattern, mobile)
if err != nil {
return false
}
return matched
}
// IsNumber 验证是否是纯数字
func IsNumber(str string) bool {
if strings.TrimSpace(str) == "" {
return false
}
for _, char := range str {
if !unicode.IsDigit(char) {
return false
}
}
return true
}
// IsEnglish 验证是否是英文字符(不限大小写)
func IsEnglish(str string) bool {
if strings.TrimSpace(str) == "" {
return false
}
for _, char := range str {
if !unicode.IsLetter(char) {
return false
}
if !isEnglishLetter(char) {
return false
}
}
return true
}
// IsEnglishWithSpace 验证是否是英文字符(允许空格)
func IsEnglishWithSpace(str string) bool {
if strings.TrimSpace(str) == "" {
return false
}
for _, char := range str {
if unicode.IsSpace(char) {
continue
}
if !unicode.IsLetter(char) {
return false
}
if !isEnglishLetter(char) {
return false
}
}
return true
}
// IsAlphanumeric 验证是否是字母和数字组合
func IsAlphanumeric(str string) bool {
if strings.TrimSpace(str) == "" {
return false
}
for _, char := range str {
if !unicode.IsLetter(char) && !unicode.IsDigit(char) {
return false
}
}
return true
}
// IsStrongPassword 验证强密码至少8位包含大小写字母和数字
func IsStrongPassword(password string) bool {
if len(password) < 8 {
return false
}
var hasUpper, hasLower, hasDigit bool
for _, char := range password {
switch {
case unicode.IsUpper(char):
hasUpper = true
case unicode.IsLower(char):
hasLower = true
case unicode.IsDigit(char):
hasDigit = true
}
}
return hasUpper && hasLower && hasDigit
}
// 辅助函数:判断是否是英文字母
func isEnglishLetter(char rune) bool {
return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z')
}