package versionSer import ( "context" "fmt" "math/rand" "net/http" "stat/api/proto" "stat/common/enum/consts" "stat/common/genId" "stat/common/log" "stat/common/redis" "stat/common/tf" "stat/common/utils" "stat/models/appInfoMod" "stat/models/versionMod" "stat/statg" "strings" "time" "github.com/caixw/lib.go/encoding/version" "github.com/jinzhu/copier" ) // ListVersion 获取版本信息 func ListVersion(ctx context.Context, req *proto.VersionListReq) (resp *proto.VersionListResp, err error) { resp = &proto.VersionListResp{ Data: make([]*proto.VersionInfo, 0), } skip, limit := utils.ToDBPage(req.PageNum, req.PageSize) data, count, err := versionMod.GetVersionList(ctx, req.AppId, skip, limit) if err != nil { return nil, err } appInfoList, err := appInfoMod.GetAllAppInfo(ctx) if err != nil { return nil, err } for _, v := range data { versionInfo := proto.VersionInfo{ Id: v.Id, AppId: v.AppId, VersionNum: v.VersionNum, Terminal: v.Terminal, Link: v.Link, Info: v.Info, PackageType: v.PackageType, IsForceUpdate: v.IsForceUpdate, MinVersion: v.MinVersion, Status: v.Status, Size: v.Size, Md5: v.Md5, BackLink: v.BackLink, } for _, appinfo := range appInfoList { if appinfo.AppId == v.AppId { versionInfo.AppName = appinfo.Name } } resp.Data = append(resp.Data, &versionInfo) } resp.Count = count return } // DeleteVersion 删除版本 func DeleteVersion(ctx context.Context, id int64) (err error) { err = versionMod.DelVersion(ctx, id) return } // AddVersion 添加版本 func AddVersion(ctx context.Context, req *proto.VersionAddReq) (err error) { model := &versionMod.VersionModel{} // TODO:修改成指针 err = copier.Copy(model, req) if err != nil { return } model.TfInfo = make([]versionMod.TfInfo, 0) if req.PackageType == versionMod.Tf { for _, url := range req.Link { tmp := versionMod.TfInfo{ URL: strings.TrimSpace(url), } if req.PackageType == versionMod.Tf { result, err := tf.CheckTFValid(url) if err != nil { log.Error("runCheckUrl CheckTFValid", log.Any("url", url), log.E(err)) continue } tmp.AppIcon = result.AppIcon tmp.AppName = result.AppName } model.TfInfo = append(model.TfInfo, tmp) } } model.VersionNum = strings.TrimSpace(model.VersionNum) model.CreatedAt = time.Now() model.UpdatedAt = time.Now() model.Id = genId.GetNextVersionId() err = versionMod.AddVersion(ctx, model) return } // DeleteVersion 删除版本 func UpdateVersion(ctx context.Context, req *proto.VersionUpdateReq) (err error) { model := &versionMod.VersionModel{} err = copier.Copy(model, req) if err != nil { return } model.TfInfo = make([]versionMod.TfInfo, 0) if req.PackageType != nil && *req.PackageType == versionMod.Tf { for _, url := range *req.Link { tmp := versionMod.TfInfo{ URL: strings.TrimSpace(url), } if *req.PackageType == versionMod.Tf { result, err := tf.CheckTFValid(url) if err != nil { log.Error("runCheckUrl CheckTFValid", log.Any("url", url), log.E(err)) continue } tmp.AppIcon = result.AppIcon tmp.AppName = result.AppName } model.TfInfo = append(model.TfInfo, tmp) } } model.UpdatedAt = time.Now() err = versionMod.UpdateVersion(ctx, model) return } func AppVersion(ctx context.Context, req *proto.AppVersionReq) (resp *proto.AppVersionResp, err error) { var list1 []*versionMod.VersionModel var list []*versionMod.VersionModel resp = &proto.AppVersionResp{} if req.SysType == "android" { list1, err = versionMod.FindVersByPkgTyps(ctx, req.AppId, req.SysType, req.CurVersion, 0) if err != nil { return } } else { // ios 包 list1, err = versionMod.FindIosVersion(ctx, req.AppId, req.SysType, req.CurVersion, []versionMod.PkgType{versionMod.Shop}) if err != nil { return } } list = make([]*versionMod.VersionModel, 0) for _, v := range list1 { if version.Compare(v.VersionNum, req.CurVersion) > 0 { list = append(list, v) } else if req.CurVersion == "9.9.9" { list = append(list, v) } } if len(list) == 0 || len(req.CurVersion) == 0 || req.CurVersion == "null" { resp.HasNewVersion = false return } var minVersion string for _, value := range list { if len(value.MinVersion) > 0 && value.MinVersion > minVersion { minVersion = value.MinVersion break } else if value.IsForceUpdate { minVersion = value.VersionNum } } resp.HasNewVersion = true resp.ServerVersion = list[0].VersionNum resp.DownloadLink = list[0].Link resp.Description = list[0].Info resp.IsForceUpdate = list[0].IsForceUpdate if len(minVersion) > 0 { if minVersion > req.CurVersion { resp.IsForceUpdate = true } } if len(resp.DownloadLink) > 0 && len(resp.DownloadLink[0]) < 2 && list[0].Terminal == "ios" && len(list[0].BackLink) > 2 { resp.DownloadLink = []string{list[0].BackLink} return } // // 新增批量打包逻辑 if req.SysType == "android" && len(list[0].Md5) > 0 { // 包名称:com.pf.ys201114 randTime := int64(60*60) + int64(rand.Intn(60*60)) requestPackageTime := time.Now().Add(-time.Second * time.Duration(randTime)) // 报毒包随机 // 下载链接 projectString := "" beginPath := "" pathList := strings.Split(strings.Replace(list[0].Md5, ".apk", "", -1), "_") if len(pathList) > 0 { beginPath = strings.TrimSpace(pathList[len(pathList)-1]) } else { return } endpoint := statg.GlobalAppIdEndpoints[req.AppId] if endpoint != nil { projectString = fmt.Sprintf("%s/out/%s/%s%s_", endpoint.NameEn, beginPath, endpoint.NameEn, requestPackageTime.Format("20060102")[2:]) } if projectString != "" { packageUrlString := statg.Conf.URL.PackageUrl if req.AppId == 999 && len(statg.Conf.URL.BiliPackageUrl) > 0 { packageUrlString = statg.Conf.URL.BiliPackageUrl } else if req.AppId == 777 && len(statg.Conf.URL.HuanqiuPackageUrl) > 0 { packageUrlString = statg.Conf.URL.HuanqiuPackageUrl } else if req.AppId == 444 && len(statg.Conf.URL.ManhuaPackageUrl) > 0 { packageUrlString = statg.Conf.URL.ManhuaPackageUrl } packageUrlArray := strings.Split(packageUrlString, ";") packageUrl := packageUrlString if len(packageUrlArray) > 0 { // 默认使用第一个 packageUrl = packageUrlArray[0] } link := strings.TrimSpace(packageUrl + projectString + list[0].Md5) checklink := link cerr := CheckPackageLink(ctx, checklink) if cerr != nil { log.Error("AppVersion", log.Any("link", link), log.E(cerr)) if statg.Conf.RunMod == consts.RunModRelease { // 比特币和溅射淫行下载链接异常不需要报警 if req.AppId != 998 { //text := fmt.Sprintf("[警告]:应用名称:统计中心\nandroid下载链接异常: 版本:%s-->%s\n链接%s %s\n\n", req.CurVersion, list[0].VersionNum, link, cerr.Error()) appDict, _ := appInfoMod.GetAllAppIdNameMap(ctx) text := fmt.Sprintf("【%s】Android下载链接异常:\n链接:%s\n错误:%s\n", appDict[req.AppId], link, cerr.Error()) SendLinkErrorMessageToBot(text) } } } else { resp.DownloadLink = []string{link} } } } return } // CheckPackageLink 下载链接下载检测 func CheckPackageLink(ctx context.Context, url_https string) (err error) { url := strings.Replace(url_https, "https", "http", -1) redisKey := fmt.Sprintf("channelpackagecheck:%s", url) status, _ := redis.StatRds.Exists(redisKey) if status { // 存在 return nil } // 检测下载地址 resp, err := http.Head(url) if err != nil { return err } if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusGatewayTimeout { return fmt.Errorf("file is %d ", resp.StatusCode) } _ = redis.StatRds.Set(redisKey, "1", 24*time.Hour) return nil } func NewChannelDownLoadLink(ctx context.Context, req *proto.ChannelDownLoadLinkReq) (resp *proto.ChannelDownLoadLinkResp) { return nil }