package versionSer import ( "context" "encoding/json" "stat/common/log" "stat/common/utils" "stat/models/downloadCpc" "stat/models/versionMod" "stat/service/cacheSer" "stat/statg" "strings" "time" ) // IosMobileconfigCfg iOS mobileconfig 生成所需的应用级配置 type IosMobileconfigCfg struct { AppId int32 IosDownSuff string // 下载文件名(如 madou.mobileconfig) H5Origin string H5Target string H5Config string } // ParseChannel 解析 channel(json 字符串)为 pc/dc/ch;非法 JSON 时返回空字符串,dc 走 RepairDC func ParseChannel(channel string) (pc, dc, ch string) { if channel == "" { return } var p ChannelParams _ = json.Unmarshal([]byte(channel), &p) dc = utils.RepairDC(p.DC) pc = p.PC ch = p.CH return } // RecordCpcDownload 记录 cpc 下载到 landingpage_cpc 表(走异步 writer);相同 IP 1 小时内只记一次 func RecordCpcDownload(ctx context.Context, isIos bool, appId int32, channel, ip, userAgent string) { if ip == "" { return } pc, dc, ch := ParseChannel(channel) sysType := "android" if isIos { sysType = "ios" } devType := "" if strings.Contains(userAgent, "iPhone") { devType = "iphone" } else if strings.Contains(userAgent, "iPad") { devType = "ipad" } else if strings.Contains(userAgent, "Android") { devType = "android" } info := &downloadCpc.DownloadCpc{ AppId: appId, PC: pc, DC: dc, CH: ch, IP: ip, DevType: devType, SysType: sysType, PeerIP: ip, CreatedAt: time.Now(), } if landPageVisit.TryLock(ip, time.Now().Add(landPageVisitIpTimeout)) { cacheSer.Writers.LandPageVisitWriter.Add(info) } } // LatestAndroidDownloadUrl 取应用最新 Android 版本的下载链接(第一个 Link),没有返回空字符串 func LatestAndroidDownloadUrl(appId int32) string { ctx := context.Background() data, err := versionMod.ButtonClick(ctx, appId, "android", 0) if err != nil || data == nil { log.Warn("LatestAndroidDownloadUrl ButtonClick failed", log.E(err), log.Any("appId", appId)) return "" } if len(data.Link) == 0 { return "" } return data.Link[0] } // IosMobileconfigByAppId 取应用的 iOS mobileconfig 配置;endpoint 未配置 H5 三件套则返回 nil func IosMobileconfigByAppId(appId int32) *IosMobileconfigCfg { endpoint := statg.GlobalAppIdEndpoints[appId] if endpoint == nil { return nil } if endpoint.H5Origin == "" || endpoint.H5Target == "" || endpoint.H5Config == "" { return nil } return &IosMobileconfigCfg{ AppId: appId, IosDownSuff: endpoint.H5Config, H5Origin: endpoint.H5Origin, H5Target: endpoint.H5Target, H5Config: endpoint.H5Config, } } // BuildMobileconfig 用 dc/pc 生成 mobileconfig 字节流和文件名 func BuildMobileconfig(cfg *IosMobileconfigCfg, dc, pc string) ([]byte, string) { if cfg == nil { return nil, "" } return GenerateConfigFile(cfg.H5Origin, cfg.H5Target, cfg.H5Config, dc, pc) }