package useragent import ( "hkdj-web-server/pub/common/enum/consts" "hkdj-web-server/pub/common/log" "net/url" "strings" "github.com/gin-gonic/gin" ) type UA struct { UserAgent string DevID string DevType string SysType string Ver string BuildID string SystemName string SystemVersion string DeviceBrand string DeviceModel string SessionID string SDKCommon *SDKCommonFields // SDK 公共参数独立保存,不能与原业务 UA 字段混用。 RequestPath string // 仅用于定位埋点参数缺失的业务接口。 } func IsH5(sysType string) bool { if sysType == consts.H5IOS || sysType == consts.H5Android || sysType == consts.H5PC || sysType == consts.H5 || sysType == consts.Light { return true } return false } func (s UA) IsH5() bool { return IsH5(s.SysType) } func UserAgent(c *gin.Context) { var uastr string ua := UA{RequestPath: c.FullPath()} var sdkErr error ua.SDKCommon, sdkErr = ParseSDKCommonHeader(c.GetHeader(SDKCommonHeader)) if sdkErr != nil { log.Error("【SDK公共参数解析失败】UserAgent", log.Any("接口", ua.RequestPath), log.E(sdkErr)) } ua.SessionID = c.GetHeader("sid") userAgent := c.GetHeader("X-User-Agent") // 兼容 H5 UserAgent if userAgent == "" { userAgent = c.Request.UserAgent() } c.Set(consts.CtxUAH5, c.Request.UserAgent()) if userAgent != "" { decodeUa, err := url.QueryUnescape(userAgent) if err != nil { log.Warn("URLDecode user-agent error", log.Any("ua", userAgent)) uastr = userAgent } else { uastr = decodeUa } uas := strings.Split(uastr, ";") for _, v := range uas { segment := strings.TrimSpace(v) if segment == "" { continue } vss := strings.SplitN(segment, "=", 2) if len(vss) < 2 { continue } key := strings.TrimSpace(vss[0]) value := strings.TrimSpace(vss[1]) lowerKey := strings.ToLower(key) switch lowerKey { case "devid": ua.DevID = value c.Set(consts.CtxDevId, ua.DevID) case "devtype": ua.DevType = value c.Set(consts.CtxDevType, ua.DevType) case "systype": inputSysType := strings.ToLower(strings.TrimSpace(value)) switch { case strings.Contains(inputSysType, "h5_android"): ua.SysType = consts.H5Android case strings.Contains(inputSysType, "h5_ios"): ua.SysType = consts.H5IOS case strings.Contains(inputSysType, "h5_pc"): ua.SysType = consts.H5PC case strings.Contains(inputSysType, "android"): ua.SysType = consts.Android case strings.Contains(inputSysType, "ios"): ua.SysType = consts.IOS case strings.Contains(inputSysType, "h5"): ua.SysType = consts.H5 case strings.Contains(inputSysType, "pc"): ua.SysType = consts.PC case strings.Contains(inputSysType, "light"): ua.SysType = consts.Light } c.Set(consts.CtxSysType, ua.SysType) case "ver": ua.Ver = value c.Set(consts.CtxVersion, ua.Ver) case "buildid": ua.BuildID = value c.Set(consts.CtxBuildId, ua.BuildID) case "system_name", "system-name", "systemname": if ua.SystemName == "" { ua.SystemName = value } case "system_version", "system-version", "systemversion": if ua.SystemVersion == "" { ua.SystemVersion = value } case "device_brand", "device-brand", "devicebrand": if ua.DeviceBrand == "" { ua.DeviceBrand = value } case "device_model", "device-model", "devicemodel": if ua.DeviceModel == "" { ua.DeviceModel = value } case "sid": if ua.SessionID == "" { ua.SessionID = value } default: log.Warn("user-agent unknown", log.Any("ua", userAgent), log.Any("segment", segment)) } } } else { log.Warn("user-agent empty") } ua.UserAgent = uastr if ua.DeviceBrand == "" { brand := strings.TrimSpace(c.GetHeader("device_brand")) if brand == "" { brand = strings.TrimSpace(c.GetHeader("device-brand")) } ua.DeviceBrand = brand } if ua.DeviceModel == "" { model := strings.TrimSpace(c.GetHeader("device_model")) if model == "" { model = strings.TrimSpace(c.GetHeader("device-model")) } ua.DeviceModel = model } if ua.SystemName == "" { name := strings.TrimSpace(c.GetHeader("system_name")) if name == "" { name = strings.TrimSpace(c.GetHeader("system-name")) } ua.SystemName = name } if ua.SystemVersion == "" { version := strings.TrimSpace(c.GetHeader("system_version")) if version == "" { version = strings.TrimSpace(c.GetHeader("system-version")) } ua.SystemVersion = version } if ua.SystemName == "" { ua.SystemName = ua.SysType } if ua.SystemVersion == "" { ua.SystemVersion = ua.Ver } c.Set(consts.CtxSystemName, ua.SystemName) c.Set(consts.CtxSystemVersion, ua.SystemVersion) c.Set(consts.CtxUA, ua) }