285 lines
7.8 KiB
Go
285 lines
7.8 KiB
Go
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
|
|
}
|