package service
import (
"archive/zip"
"context"
"encoding/json"
"errors"
"finclip-app-manager/domain/entity"
"finclip-app-manager/domain/entity/proto"
"finclip-app-manager/domain/entity/proto/apiproto"
"finclip-app-manager/domain/repository"
"finclip-app-manager/infrastructure/client/httpcall"
"finclip-app-manager/infrastructure/config"
impl "finclip-app-manager/infrastructure/db/repo"
"finclip-app-manager/infrastructure/kafka"
pb "finclip-app-manager/infrastructure/protobuf/golang"
"finclip-app-manager/infrastructure/utility"
"finclip-app-manager/infrastructure/utils"
"fmt"
"io"
"os"
"path"
"path/filepath"
"strings"
ezip "github.com/alexmullins/zip"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"net/http"
"time"
)
const (
/**
* 开发中: InDevelopment
* 审核中: Publishing
* 撤销审核: PublishWithdraw
* 审核通过:PublishApproved
* 审核被拒:PublishRejected
* 已上架:Published
* 高本版上架致下架:UnpublishedByNewSeq
* 开发者下架: UnpublishedByDev
* 运营端下架:UnpublishedByAdmin
**/
AppExternalStatusInDevelopment = "InDevelopment"
AppExternalStatusPublishing = "Publishing"
AppExternalStatusPublishWithdrawed = "PublishWithdrawed"
AppExternalStatusPublishApproved = "PublishApproved"
AppExternalStatusPublishRejected = "PublishRejected"
AppExternalStatusPublished = "Published"
AppExternalStatusUnpublishedByNewSeq = "UnpublishedByNewSeq"
AppExternalStatusUnpublishedByDev = "UnpublishedByDev"
AppExternalStatusUnpublishedByAdmin = "UnpublishedByAdmin"
)
type AppService struct {
appRepo repository.AppRepository
buildRepo repository.IAppBuildInfoRepo
bindingRepo repository.IBindingRepo
tempAppRepo repository.IAppTempInfoRepo
//qrcodeRepo repository.IQrCodeInfoRepo
prviacySettingRepo repository.IPrivacySettingRepo
tool *BoxTool
}
func NewAppService() *AppService {
return &AppService{
appRepo: impl.InitAppRepo(),
buildRepo: impl.InitBuildInfoRepo(),
bindingRepo: impl.InitBindingRepo(),
tempAppRepo: impl.InitAppTempInfoRepo(),
//qrcodeRepo: impl.InitQrCodeInfoRepo(),
prviacySettingRepo: impl.InitPrivacySettingRepo(),
tool: NewBoxTool(),
}
}
func (as *AppService) CreateApp(ctx context.Context, c *gin.Context, req proto.CreateAppReq, accountId string) (*entity.App, *utility.SvrRsp) {
log.Infof("createApp get req:%+v", req)
rsp := utility.DefaultSvrRsp()
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, accountId)
if err != nil {
log.Errorf("createApp GetGroupID err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
accountInfo, err := hCaller.GetAccountInfo(ctx, accountId)
if err != nil {
log.Errorf("createApp GetAccountInfo err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR)
}
if req.ProjectType < 0 || req.ProjectType > 2 {
log.Errorf("createApp param err")
return nil, rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR)
}
info := entity.App{}
info.AppClass = req.AppClass
info.AppTag = req.AppTag
info.AppType = req.AppType
info.CoreDescription = req.CoreDescription
info.Logo = req.Logo
info.Name = req.Name
info.GroupID = groupInfo.GroupID
info.CreatedBy = accountInfo.Account
info.DeveloperID = accountId
info.AppID = bson.NewObjectId().Hex()
info.ProjectType = req.ProjectType
timestamp := time.Now().UnixNano() / 1e6
info.Status = entity.Status{
Value: entity.StInDevelopment,
LastUpdated: timestamp,
ModifiedBy: info.DeveloperID,
}
info.Created = timestamp
info.IsForbidden = 0
licenseInfo, err := hCaller.GetLicense(ctx)
if err != nil {
log.Errorf("createApp get license info error:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
log.Infof("createApp get license info:%+v", licenseInfo)
appCount, err := as.appRepo.AppCount(ctx, "")
if err != nil {
log.Errorf("createApp get app count error:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if appCount >= licenseInfo.AppCount {
log.Errorf("createApp app count has over license limit app count:%d", appCount)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FC_PRI_LIMIT_APPID_OVER_ERROR)
}
//调用支付权限模块增加小程序数量
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
applyReq := httpcall.PayAddLimitReq{}
applyReq.Type = httpcall.PAY_ADD_TYPE_APP
applyReq.AccountId = accountId
applyReq.BusinessId = info.AppID
applyReq.BusinessName = info.Name
payAddRsp, httpCode, err := hCaller.PayAddLimit(ctx, &applyReq)
if err != nil {
log.Errorf("PayAddLimit err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if httpCode != http.StatusOK {
return nil, rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR)
}
if payAddRsp.Data.EndTime == 0 {
payAddRsp.Data.EndTime = MAX_EXPIRE_DATA
}
info.Expire = payAddRsp.Data.EndTime
} else { //调用运营端增加企业appid数量,会做校验
n := httpcall.AddLimitInfoReq{
Type: "appId",
OrganId: info.GroupID,
AddNum: 1,
}
httpCode, _, err := hCaller.AddLimitInfo(ctx, &n)
if err != nil {
log.Errorf("createApp AddLimitInfo err:%s", err.Error())
return nil, rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR)
}
}
if err = as.appRepo.InsertApp(ctx, info); err != nil {
log.Errorf("createApp insert appVer info err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_DB_ERR)
}
//生成操作日志
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, groupInfo.GroupID, kafka.GenContent(kafka.APP_ADD_LOG, info.Name, info.AppID), logExp, accountInfo.Account)
info.Expire = getExpire(info.Expire, licenseInfo.ExpireTime)
return &info, rsp.SetLoc(http.StatusCreated, utility.OK)
}
func (as *AppService) WithdrawPublishRequest(ctx context.Context, c *gin.Context, appId string, seq int, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, seq)
if err != nil {
log.Errorf("withdrawPublishRequest get app ver err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("withdrawPublishRequest GetGroupID err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
err = as.appRepo.WithdrawPubApp(ctx, appId, seq, accountInfo.Account)
if err != nil {
log.Errorf("withdrawPublishRequest db err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, accountInfo.OrganId, kafka.GenContent(kafka.APP_CANCEL_REVIEW_LOG, appVer.Name, appVer.AppID), logExp, accountInfo.Account)
//model.NewAsyncMessageRepo().GenAppStatusChangeInfo(traceCtx, model.AppStatusChangeInfo{Event: model.AppWithdrawPubReq, Info: map[string]interface{}{"appId": appVer.AppID}})
return rsp
}
func (as *AppService) UpdateApp(ctx context.Context, c *gin.Context, req proto.AppUpdateReq, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId)
if err != nil {
log.Errorf("UpdateApp app info not found,req:%+v", req)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
oldName := appInfo.Name
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId)
if err != nil {
log.Errorf("updateApp GetGroupID err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
if groupInfo.GroupID != appInfo.GroupID {
log.Errorf("updateApp group id not equal,req groupId:%+v,get groupId:%s", groupInfo, appInfo.GroupID)
return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN)
}
//err = as.appRepo.UpdateApp(ctx, appInfo)
//if err != nil {
// log.Errorf("updateApp app err:%s", err.Error())
// return rsp.SetLoc(http.StatusForbidden, utility.FS_DB_ERR)
//}
appInfo.Name = req.Name
appInfo.Logo = req.Logo
appInfo.AppClass = req.AppClass
appInfo.AppTag = req.AppTag
appInfo.CoreDescription = req.CoreDescription
appInfo.CustomData.DetailDescription = req.CustomData.DetailDescription
err = as.appRepo.UpdateApp(ctx, appInfo)
if err != nil {
log.Errorf("UpdateApp repo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if oldName != req.Name {
if err = as.appRepo.UpdateAppVerAppName(ctx, req.AppId, req.Name); err != nil {
log.Errorf("UpdateAppVerAppName repo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
//操作日志
logExp := make(map[string]interface{})
logReq := httpcall.GenOperateDataV2Req{
OrganId: appInfo.GroupID,
Content: kafka.GenContent(kafka.APP_EDIT_INFO_LOG, appInfo.Name, appInfo.AppID),
Extra: logExp,
Oper: "",
AccountId: userId,
IsDev: true,
}
hCaller.AddOperateLogV2(c, logReq)
return rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) UpdateAppIsForbidden(ctx context.Context, req proto.AppIsForbiddenUpdateReq, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId)
if err != nil {
log.Errorf("UpdateAppIsForbidden app info not found,req:%+v", req)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId)
if err != nil {
log.Errorf("updateAppIsForbidden GetGroupID err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
if groupInfo.GroupID != appInfo.GroupID {
log.Errorf("updateAppIsForbidden group id not equal,req groupId:%+v,get groupId:%s", groupInfo, appInfo.GroupID)
return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN)
}
if req.IsForbidden == 0 {
licenseInfo, err := hCaller.GetLicense(ctx)
if err != nil {
log.Errorf("createApp get license info error:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
log.Infof("createApp get license info:%+v", licenseInfo)
appCount, err := as.appRepo.AppCount(ctx, "")
if err != nil {
log.Errorf("createApp get app count error:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if appCount >= licenseInfo.AppCount {
log.Errorf("createApp app count has over license limit app count:%d", appCount)
return rsp.SetLoc(http.StatusOK, utility.FC_PRI_LIMIT_APPID_OVER_ERROR)
}
}
appInfo.IsForbidden = req.IsForbidden
//调用支付权限模块增加小程序数量
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
applyReq := httpcall.PayAddLimitReq{}
applyReq.Type = httpcall.PAY_ADD_TYPE_APP
applyReq.AccountId = userId
applyReq.BusinessId = req.AppId
applyReq.BusinessName = appInfo.Name
if req.IsForbidden == 0 {
payAddRsp, httpCode, err := hCaller.PayAddLimit(ctx, &applyReq)
if err != nil {
log.Errorf("PayAddLimit err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if httpCode != http.StatusOK {
return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR)
}
if payAddRsp.Data.EndTime == 0 {
payAddRsp.Data.EndTime = MAX_EXPIRE_DATA
}
appInfo.Expire = payAddRsp.Data.EndTime
} else {
_, httpCode, err := hCaller.PayUpdateLimit(ctx, &applyReq)
if err != nil {
log.Errorf("PayAddLimit err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if httpCode != http.StatusOK {
return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR)
}
}
} else { //调用运营端增加企业appid数量,会做校验
addNum := 1
if req.IsForbidden == 1 {
addNum = -1
}
n := httpcall.AddLimitInfoReq{
Type: "appId",
OrganId: appInfo.GroupID,
AddNum: addNum,
}
httpCode, _, err := hCaller.AddLimitInfo(ctx, &n)
if err != nil {
log.Errorf("createApp AddLimitInfo err:%s", err.Error())
return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR)
}
}
err = as.appRepo.UpdateApp(ctx, appInfo)
if err != nil {
log.Errorf("UpdateAppIsForbidden repo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
/*//操作日志
logExp := make(map[string]interface{})
logReq := kafka.GenOperateDataV2Req{
OrganId: appInfo.GroupID,
Content: kafka.GenContent(kafka.APP_EDIT_INFO_LOG, appInfo.Name, appInfo.AppID),
Extra: logExp,
Oper: "",
AccountId: userId,
IsDev: true,
}
kafka.GenOperateDataV2(ctx, c, logReq)*/
return rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) PubApp(ctx context.Context, appId string, seq int, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq)
if err != nil {
log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error())
if repository.NotFound(err) {
log.Errorf("DevPublishApp get appVer not found!")
return rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND)
}
}
log.Debugf("as.appRepo.GetAppVerInfo err:%s", utility.InterfaceToJsonString(appVerInfo))
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId)
if err != nil {
log.Errorf("DevPublishApp GetGroupID err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
if groupInfo.GroupID != appVerInfo.GroupID {
log.Errorf("DevPublishApp group id no equal,app ver group Id:%s,get group info:%+v", appVerInfo.GroupID, groupInfo)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_APP_SEQUENCE_NOT_FOUND)
}
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("DevPublishApp GetAccountInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR)
}
_, onlineAppErr := as.appRepo.GetOnlineAppVer(ctx, appId)
if onlineAppErr != nil {
if !repository.NotFound(onlineAppErr) {
log.Errorf("GetOnlineAppVer err:%s", onlineAppErr.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
lastPubVerInfo, err := as.appRepo.GetLatestPubAppVer(ctx, appId)
if err != nil && !repository.NotFound(err) {
log.Errorf("DevPublishApp GetLatestPubAppVer err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
var isRollback = false
if !repository.NotFound(err) && lastPubVerInfo.Sequence > seq { //代表回退版本
if repository.NotFound(onlineAppErr) { //如果当前小程序未上架,不允许回退
log.Errorf("no pub app,appId:[%s]", appId)
return rsp.SetLoc(http.StatusBadRequest, utility.FS_ROLLBACK_FORBID)
}
isRollback = true
//如果当前上架的小程序版本已经是回退版本,那不可再次回退
if lastPubVerInfo.Status.Value == entity.StPublished && lastPubVerInfo.IsRollback {
log.Errorf("roll back app ver has rollback,info:%+v", lastPubVerInfo)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_MULTI_ROLLBACK_FORBID)
}
//校验是否可以回退----不是最近下架的5个版本
rollbackList, err := as.appRepo.GetRollbackAbleList(ctx, groupInfo.GroupID, appId, lastPubVerInfo.Sequence)
if err != nil {
log.Errorf("GetRollbackAbleList err:%s,info:%+v", err.Error(), lastPubVerInfo)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
isValidRollbackSeq := false
for _, v := range rollbackList {
if v.Sequence == seq {
isValidRollbackSeq = true
}
}
if !isValidRollbackSeq {
log.Errorf("roll back app not valid,req appId:%s,seq:%d", appId, seq)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_ROLLBACK_FORBID)
}
log.Infof("PubApp appId:[%s],seq:[%d] is rollback!", appId, seq)
} else {
if appVerInfo.Status.Value != entity.StPublishApproved {
log.Errorf("PubApp status not valid,appId:[%s],seq:[%d]", appId, seq)
return rsp.SetLoc(http.StatusBadRequest, utility.FS_INVALID_STATE)
}
}
err = as.pubAppHelp(ctx, appId, seq, accountInfo.Account, true, isRollback, userId, appVerInfo.ActionStatus.ModifiedBy)
if err != nil {
log.Errorf("pubAppHelp err:%s", err.Error())
return rsp.SetLoc(http.StatusBadRequest, utility.FS_SYSTEM_CALL)
}
//service.NewWechatInfoService().TouchWechatInfo(traceCtx, appVer.AppID)
//if isDev {
// logExp := make(map[string]interface{})
// go model.GenOperateData(traceCtx, c, groupID, GenContent(APP_PUB_LOG, appVer.Name, appVer.AppID, appVer.Sequence), logExp, accountInfo.Account)
//}
//notifySpiderPushApp(traceCtx, req.AppID, client.UP_STATE)
//sendSwanReport(ctx, "userId", userId)
//c.JSON(http.StatusOK, gin.H{})
sendDelaySms(ctx, appVerInfo.DeveloperID, true, true, true, appId, appVerInfo.Name, seq)
//上架通过后,更新小程序隐私中的updateTime与effectiveTime
total, err := as.prviacySettingRepo.Count(ctx, appId)
if total > 0 {
item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId)
if err != nil {
log.Errorf("PrviacySettingRepo insert err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
/*if item.EffectiveTime == 0 {
item.EffectiveTime = time.Now().UnixNano() / 1e6
}*/
item.UpdateTime = time.Now().UnixNano() / 1e6
err = as.prviacySettingRepo.UpdateInfo(ctx, *item)
if err != nil {
log.Errorf("PrviacySettingRepo UpdateInfo time err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
return rsp.SetLoc(http.StatusOK, utility.OK)
}
//下架小程序
func (as *AppService) UnpubApp(ctx context.Context, c *gin.Context, appId string, seq int, userId string, isDev bool, reason string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq)
if err != nil {
log.Errorf("UnpubApp GetAppVerInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
log.Debugf("UnpubApp appVerInfo:%+v", appVerInfo)
if appVerInfo.Status.Value != entity.StPublished {
log.Errorf("UnpubApp status err,need approved,appId:%s,seq:%d", appId, seq)
return rsp.SetLoc(http.StatusBadRequest, utility.FS_INVALID_STATE)
}
var account string
if isDev {
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId)
if err != nil {
log.Errorf("UnpubApp get group info err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if groupInfo.GroupID != appVerInfo.GroupID {
log.Errorf("unpublishAppHelp group id not equal appVer group id:%s,get group id:%+v", appVerInfo.GroupID, groupInfo)
return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN)
}
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("UnpubApp GetAccountInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
account = accountInfo.Account
} else {
adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId)
if err != nil {
log.Errorf("UnpubApp GetAdminAccountInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
account = adminInfo.Account
}
err = as.appRepo.UnpubApp(ctx, appId, seq, account, reason, isDev)
if err != nil {
log.Errorf("UnpubApp db err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if isDev {
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, appVerInfo.GroupID, kafka.GenContent(kafka.APP_DOWN_LOG, appVerInfo.Name, appVerInfo.AppID, appVerInfo.Sequence), logExp, account)
} else {
notifyContent := kafka.NotifyContent{}
notifyContent.Title = fmt.Sprintf("小程序“%s”被下架", appVerInfo.Name)
notifyContent.Result = "fail"
notifyContent.Msg = fmt.Sprintf("小程序 %s(App ID:%s)被进行下架操作。用户暂无法使用小程序的所有服务(关联应用也无法使用)。下架理由为:%s", appVerInfo.Name, appVerInfo.AppID, reason)
notifyContent.Reason = reason
go kafka.GenNotifyData(ctx, appVerInfo.GroupID, 1000, notifyContent)
}
notifySpiderPushApp(ctx, appId, httpcall.DOWN_STATE)
return rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) RollbackAppList(ctx context.Context, appId, userId string) ([]entity.AppVersion, error) {
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("RollbackAppList GetAccountInfo err:%s", err.Error())
return nil, err
}
latestPubAppVer, err := as.appRepo.GetLatestPubAppVer(ctx, appId)
if err != nil {
if repository.NotFound(err) {
log.Errorf("RollbackAppList not found,appId:%s", appId)
return make([]entity.AppVersion, 0), nil
}
return nil, err
}
if latestPubAppVer.Status.Value != entity.StPublished {
log.Errorf("RollbackAppList latestPubAppVer no pub,appId:[%s]", appId)
return make([]entity.AppVersion, 0), nil
}
if latestPubAppVer.IsRollback {
log.Errorf("RollbackAppList latestPubAppVer has rollback,appId:[%s]", appId)
return make([]entity.AppVersion, 0), nil
}
rollbackList, err := as.appRepo.GetRollbackAbleList(ctx, accountInfo.OrganId, appId, latestPubAppVer.Sequence)
if err != nil {
log.Errorf("GetRollbackAbleList db err:%s", err.Error())
return nil, err
}
return rollbackList, nil
}
func (as *AppService) SubmitApp(ctx context.Context, c *gin.Context, req apiproto.SubmitPublishReqest, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
buildInfo, err := as.buildRepo.GetInfoById(ctx, req.Id)
if as.buildRepo.NotFound(err) || buildInfo == nil {
buildInfo, err = as.buildRepo.GetInfoByBuildId(ctx, req.Id)
if err != nil || buildInfo == nil {
if err != nil {
log.Errorf("SubmitApp get build info err:%s", err.Error())
} else {
log.Errorf("SubmitApp get build info nil")
}
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
if buildInfo.AppID != req.AppID {
log.Errorf("buildID err")
return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR)
}
if config.GetConfig().IsOpenAuditSecurity {
auditInfo, err := hCaller.GetAuditDataInfoByBuildInfoId(ctx, buildInfo.BuildInfoId)
log.Debugln("GetAuditDataInfoByBuildInfoId:%v", utility.InterfaceToJsonString(auditInfo))
if err != nil {
log.Errorf("GetAuditDataInfoByBuildInfoId err:%s", err.Error())
return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR)
}
//0无,1审核中,2通过,3不通过
if auditInfo.Data.Status != 2 && auditInfo.Data.OperOpinion != 1 {
log.Errorf("auditInfo.Data.Status not pass:%v", auditInfo.Data.Status)
return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR)
}
}
appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppID)
if err != nil {
log.Errorf("SubmitApp GetAppInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("SubmitApp GetAccountInfo err:%s,user id:%s", err.Error(), userId)
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if appInfo.GroupID != accountInfo.OrganId {
log.Errorf("SubmitApp group id not match!")
return rsp.SetLoc(http.StatusBadRequest, utility.FS_BAD_JSON)
}
maxSeqAppVerInfo, err := as.appRepo.GetMaxSeqAppVer(ctx, req.AppID)
if err != nil {
if !repository.NotFound(err) {
log.Errorf("SubmitApp GetMaxSeqAppVer err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
} else {
if maxSeqAppVerInfo.Status.Value == entity.StPublishing {
log.Errorf("submitPublishRequest max version Publishing!!!")
return rsp.SetLoc(http.StatusBadRequest, utility.FS_PUBLISHING_OR_UNPUBLISHING)
}
}
oper := c.GetHeader("C-Open-Api")
if oper == "" {
oper = accountInfo.Account
}
SubmitAppReq := entity.SubmitAppReq{
AppId: req.AppID,
BuildId: req.Id,
Account: oper,
NeedAutoPub: req.NeedAutoPub,
TestInfo: req.TestInfo,
UserId: userId,
}
err = as.appRepo.SubmitApp(ctx, SubmitAppReq, 0, userId)
if err != nil {
log.Errorf("SubmitApp app err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, appInfo.GroupID, kafka.GenContent(kafka.APP_SUB_REVIEW_LOG, appInfo.Name, appInfo.AppID), logExp, oper)
if config.Cfg.PublishEnv == config.ENV_UAT {
// 通知中心发送消息
notifyContent := kafka.NotifyContent{}
notifyContent.Title = fmt.Sprintf("%s提交了”%s”小程序审核", accountInfo.Account, appInfo.Name)
notifyContent.Result = "success"
notifyContent.Msg = fmt.Sprintf("%s提交了小程序“%s”(APPID: %s)的上架审核申请", oper, appInfo.Name, appInfo.AppID)
go kafka.GenNotifyData(ctx, accountInfo.OrganId, 1000, notifyContent)
}
return rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) ApproveApp(ctx context.Context, req apiproto.ApproveAppReq, isAdmin bool, userId string) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, req.AppID, req.Sequence)
if err != nil {
log.Errorf("ApproveApp get app version info err:%s", err.Error())
return rsp.SetLoc(http.StatusBadRequest, utility.FS_APP_SEQUENCE_NOT_FOUND)
}
var account string
if isAdmin {
adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId)
if err != nil {
log.Errorf("approveApp GetAdminAccountInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusBadRequest, utility.FS_GET_ACCOUNTINFO_ERROR)
}
account = adminInfo.Account
} else {
devAccountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("approveApp GetAdminAccountInfo err:%s", err.Error())
return rsp.SetLoc(http.StatusBadRequest, utility.FS_GET_ACCOUNTINFO_ERROR)
}
if devAccountInfo.OrganId != appVerInfo.GroupID {
log.Errorf("ApproveApp organ id not match,req organ id:%s,app ver:%+v", devAccountInfo.OrganId, appVerInfo)
return rsp.SetLoc(http.StatusNotFound, utility.FS_FORBIDDEN)
}
account = devAccountInfo.Account
}
if req.RequestFrom != "" {
account = req.RequestFrom
}
var isPass = false
if req.Status == entity.StPublishApproved {
isPass = true
}
var isPubImmediately = false
if appVerInfo.NeedAutoPub && isPass {
isPubImmediately = true
}
log.Infof("isPass:%t isPubImmediately:%t", isPass, isPubImmediately)
err = as.appRepo.ApproveApp(ctx, req.AppID, req.Sequence, account, req.Reason, isPass)
if err != nil {
log.Errorf("ApproveApp db err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
{
//给通知中心发消息
st := time.Unix(appVerInfo.PublishingStatus.LastUpdated/1000, 0).Format("2006-01-02 15:04")
at := time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04")
notifyContent := kafka.NotifyContent{}
if isPass {
notifyContent.Title = fmt.Sprintf("小程序“%s”上架审核成功", appVerInfo.Name)
notifyContent.Result = "success"
//notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)已经通过审核,可进行后续操作。
申请时间:%s,审核时间:%s",
// appVerInfo.Name, appVerInfo.AppID, st, at)
notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)您提交的小程序已经通过审核,请在小程序详情中进行版本上架操作。
申请时间:%s,审核时间:%s",
appVerInfo.Name, appVerInfo.AppID, st, at)
notifyContent.Reason = req.Reason
} else {
notifyContent.Title = fmt.Sprintf("小程序“%s”上架审核失败", appVerInfo.Name)
notifyContent.Result = "fail"
notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)未通过审核,可进行后续操作。
申请时间:%s,审核时间:%s", appVerInfo.Name, appVerInfo.AppID, st, at)
notifyContent.Reason = req.Reason
}
go kafka.GenNotifyData(ctx, appVerInfo.GroupID, 1000, notifyContent)
sendDelaySms(ctx, appVerInfo.DeveloperID, isPass, isPubImmediately, false, req.AppID, appVerInfo.Name, req.Sequence)
}
if isPubImmediately {
err = as.pubAppHelp(ctx, req.AppID, req.Sequence, "自动上架", false, false, "[auto]", appVerInfo.ActionStatus.ModifiedBy)
//err = as.appRepo.PubApp(ctx, req.AppID, req.Sequence, "自动上架", true, false)
if err != nil {
log.Errorf("ApproveApp auto pub app err:%s", err.Error())
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
} else {
appTagStr := ""
if len(appVerInfo.AppTag) > 0 {
for _, v := range appVerInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagStr += tag.Name + ","
log.Debugln("appTagStr", appTagStr)
}
}
}
if len(appTagStr) > 0 {
appTagStr = appTagStr[0 : len(appTagStr)-1]
}
}
}
//sendSwanReport(ctx, "account", appVerInfo.RequestStatus.ModifiedBy)
}
return rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) pubAppHelp(ctx context.Context, appId string, seq int, account string, isDev, isRollback bool, userId, requestAccount string) error {
//通知灰度发布并更新状态
var err error
if isDev { //运营端审核通过自动上架,做一个特殊处理
err = hCaller.PubNotifyRuleEngine(ctx, appId, seq, userId, isDev)
} else {
err = hCaller.PubNotifyRuleEngine(ctx, appId, seq, "", isDev)
}
if err != nil {
log.Errorf("pubAppHelp PubNotifyRuleEngine err:%s", err.Error())
return err
}
err = as.appRepo.PubApp(ctx, appId, seq, account, isDev, isRollback)
if err != nil {
log.Errorf("PubAppVer err:%s,appId:%s,seq:%d", err.Error(), appId, seq)
return err
}
appVersion, err := as.appRepo.GetAppVerInfo(ctx, appId, seq)
if err != nil {
log.Errorf("pubAppHelp GetAppVerInfo err:%s", err.Error())
return nil
}
//service.NewWechatInfoService().TouchWechatInfo(traceCtx, appVer.AppID)
//if isDev {
// logExp := make(map[string]interface{})
// go model.GenOperateData(traceCtx, c, groupID, GenContent(APP_PUB_LOG, appVer.Name, appVer.AppID, appVer.Sequence), logExp, accountInfo.Account)
//}
//notifySpiderPushApp(traceCtx, req.AppID, client.UP_STATE)
err = hCaller.TouchWechatInfo(ctx, appId)
if err != nil {
log.Errorf("TouchWechatInfo err:%s", err.Error())
return nil
}
/*appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return err
}
log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
if len(appVersion.AppTag) > 0 {
log.Debugln("AppTag:", appVersion.AppTag)
for _, v := range appVersion.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagStr += tag.Name + ","
log.Debugln("appTagStr", appTagStr)
}
}
}
if len(appTagStr) > 0 {
appTagStr = appTagStr[0 : len(appTagStr)-1]
}
}*/
/*
if len(appVersion.AppTag) > 0 {
for _, v := range appTagInfo.Data.AppClass {
if v.Key == appVersion.AppClass {
appClassStr = v.Name
}
}
}*/
/*if len(appVersion.CustomData.SourceFile) > 0 {
notifySpiderPubApp(ctx, appVersion.AppID, appVersion.Name, appVersion.CoreDescription, "", appVersion.CustomData.SourceFile[0].SourceFileUrl, appTagStr, appClassStr)
}*/
go hCaller.PubAppNotifyToMiniprogram(ctx, &appVersion)
sendSwanReport(ctx, "account", requestAccount)
return nil
}
type GetStatisticsResponse struct {
Created int `json:"created"`
Submited int `json:"submited"`
Approved int `json:"approved"`
Published int `json:"published"`
}
func (as *AppService) AppStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool, isForbidden int) (GetStatisticsResponse, error) {
var (
result = GetStatisticsResponse{}
err error
)
result.Created, err = as.appRepo.GetCreatedStatistics(ctx, startTime, endTime, groupId, isForbidden)
if err != nil {
return GetStatisticsResponse{}, err
}
result.Submited, err = as.appRepo.GetSubmittedStatistics(ctx, startTime, endTime, groupId, distinct)
if err != nil {
return GetStatisticsResponse{}, err
}
result.Approved, err = as.appRepo.GetApprovedStatistics(ctx, startTime, endTime, groupId, distinct)
if err != nil {
return GetStatisticsResponse{}, err
}
result.Published, err = as.appRepo.GetPublishedStatistics(ctx, startTime, endTime, groupId)
if err != nil {
return GetStatisticsResponse{}, err
}
return result, nil
}
func (as *AppService) GetAppInfoByAppId(ctx context.Context, appId string) (entity.App, error) {
return as.appRepo.GetAppInfo(ctx, appId)
}
func (as *AppService) GetAppVerInfo(ctx context.Context, appId string, seq int) (entity.AppVersion, error) {
return as.appRepo.GetAppVerInfo(ctx, appId, seq)
}
func (as *AppService) GetLatestPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) {
return as.appRepo.GetLatestPubAppVer(ctx, appId)
}
func (as *AppService) GetOnlineAppVer(ctx context.Context, appId string) (entity.AppVersion, error) {
return as.appRepo.GetOnlineAppVer(ctx, appId)
}
func (as *AppService) GetLatestReviewAppVer(ctx context.Context, appId string) (entity.AppVersion, error) {
return as.appRepo.GetLatestReviewAppVer(ctx, appId)
}
func (as *AppService) GetMaxSeqAppVer(ctx context.Context, appId string) (entity.AppVersion, error) {
return as.appRepo.GetMaxSeqAppVer(ctx, appId)
}
func (as *AppService) GetPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) {
return as.appRepo.GetLatestPubAppVer(ctx, appId)
}
func (as *AppService) GetAllPublishedVerList(ctx context.Context, appId string) ([]entity.AppVersion, int, error) {
return as.appRepo.GetAllPublishedVerList(ctx, appId)
}
func (as *AppService) GetBuildInfo(ctx context.Context, req apiproto.GetBuildAppInfoReq, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) {
switch req.Type {
case entity.BuildInfoTypeTrial: //获取体验版小程序详情
return as.GetTrialInfo(ctx, req.CodeId, sdkKey)
case entity.BuildInfoTypeTemporary, entity.BuildInfoTypeRomoteDebug: //获取ide临时小程序详情
return as.getTempAppBuildInfo(ctx, req.CodeId)
case entity.BuildInfoTypeDevelopment:
return as.GetDevInfo(ctx, req.CodeId, sdkKey)
default:
return nil, utility.DefaultSvrRsp().SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR)
}
}
func (as *AppService) GetTrialInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
buildInfo := new(pb.BuildAppInfo)
info, err := as.buildRepo.GetInfoById(ctx, codeId)
if err != nil {
log.Errorf("GetTrialInfo get info err:%s", err.Error())
if repository.NotFound(err) {
return nil, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND)
}
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if info.Source != entity.APP_BUILD_SOURCE_TRIAL {
log.Errorf("GetTrialInfo id is not a trial info:[%s]", codeId)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_NOT_TRIAL_INFO)
}
appInfo, err := as.appRepo.GetAppInfo(ctx, info.AppID)
if err != nil {
log.Errorf("GetTrialInfo GetAppVerInfo err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if appInfo.IsForbidden == 1 {
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN)
}
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID)
if err != nil {
log.Errorf("GetTrialInfo GetGroupInfoByUserId err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
// 获取开发者信息
//developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID)
//if err != nil {
// log.Errorf("GetDeveloperInfo err:%s", err.Error())
// return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR)
//}
//status := avs.account.getAccountStatus(groupInfo, developerInfo)
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
}
domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, groupInfo.GroupID)
if err != nil {
log.Errorf("GetTrialInfo ger domain info err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//支付信息过期校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
appStatus, err := as.CheckIdStatus(ctx, appInfo.AppID)
if err != nil {
log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appInfo.AppID)
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if appStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("check appid purch status no ok ")
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE)
}
}
log.Debugf("get group id:%s,sdkKey:%s", appInfo.GroupID, sdkKey)
inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry)
if !inWhiteList {
bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey)
if err != nil {
log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error())
if repository.NotFound(err) {
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND)
}
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if bindingInfo.CooperateStatus.Value != entity.StBindValid {
log.Errorf("GetTrialInfo binding bind invalid,binding info:%+v", bindingInfo)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED)
}
//支付信息校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID)
if err != nil {
log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID)
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("binding id pay check no ok ")
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE)
}
}
appAssBind := false
for _, v := range bindingInfo.AppInfos {
if v.AppID == appInfo.AppID {
appAssBind = true
}
}
if !appAssBind {
log.Errorf("GetTrialInfo sdk key not ass binding,appId:[%s]", appInfo.AppID)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appInfo.AppTag) > 0 {
for _, v := range appInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
buildInfo.CodeId = info.Id
buildInfo.CoreDescription = appInfo.CoreDescription
buildInfo.Created = info.Created
buildInfo.CreatedBy = info.CreatedBy
err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, info.CustomData, domainInfo, "cache")
if err != nil {
log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, errCode)
}
buildInfo.CustomData = customData
buildInfo.CustomData.DetailDescription = appInfo.CustomData.DetailDescription
buildInfo.GroupId = info.GroupID
buildInfo.GroupName = groupInfo.GroupName
buildInfo.Logo = appInfo.Logo
buildInfo.Name = appInfo.Name
buildInfo.Version = info.Version
buildInfo.IsTemp = false
buildInfo.NeedCrt = domainInfo.NeedCrt
buildInfo.AppId = info.AppID
buildInfo.AppTag = appTagArr
buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType)
buildInfo.ProjectType = int32(appInfo.ProjectType)
buildInfo.DeveloperStatus = int32(getAccountStatus(groupInfo))
//buildInfoCacheByte, _ = json.Marshal(buildInfo)
//avs.rc.Set(ctx, avs.getTrialInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime)
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, info.AppID)
if err == nil {
buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo)
//return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
return buildInfo, rsp
}
func (as *AppService) GetDevInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
buildInfo := new(pb.BuildAppInfo)
//buildInfoCacheByte, err := avs.rc.GetBytes(ctx, avs.getDevInfoCacheKey(codeId))
//if err == nil {
// if err = json.Unmarshal(buildInfoCacheByte, buildInfo); err == nil {
// log.Infof("GetDevInfo from cache ...")
// return buildInfo, rsp.SetLoc(gin.H{}, http.StatusOK, common.OK)
// }
//}
info, err := as.buildRepo.GetInfoById(ctx, codeId)
if err != nil {
log.Errorf("GetDevInfo get info err:%s", err.Error())
if repository.NotFound(err) {
return nil, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND)
}
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
appInfo, err := as.appRepo.GetAppInfo(ctx, info.AppID)
if err != nil {
log.Errorf("GetDevInfo GetAppVerInfo err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if appInfo.IsForbidden == 1 {
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN)
}
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID)
if err != nil {
log.Errorf("GetDevInfo GetGroupInfoByUserId err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//// 获取开发者信息
//developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID)
//if err != nil {
// log.Errorf("GetDeveloperInfo err:%s", err.Error())
// return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR)
//}
//status := avs.account.getAccountStatus(groupInfo, developerInfo)
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
}
//if !client.OrganStatusIsValid(groupInfo.ReviewStatus) {
// log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId)
// return nil, rsp.SetLoc(gin.H{}, http.StatusForbidden, common.FS_ORGAN_STATUS_INVALID)
//}
//支付信息过期校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
appStatus, err := as.CheckIdStatus(ctx, appInfo.AppID)
if err != nil {
log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appInfo.AppID)
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if appStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("check appid purch status no ok ")
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE)
}
}
domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, appInfo.GroupID)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
log.Debugf("get group id:%s,sdkKey:%s", appInfo.GroupID, sdkKey)
inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry)
if !inWhiteList {
bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey)
if err != nil {
log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error())
if repository.NotFound(err) {
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND)
}
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if bindingInfo.CooperateStatus.Value != entity.StBindValid {
log.Errorf("GetDevInfo binding bind invalid,binding info:%+v", bindingInfo)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED)
}
//支付信息校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID)
if err != nil {
log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID)
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("binding id pay check no ok ")
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE)
}
}
appAssBind := false
for _, v := range bindingInfo.AppInfos {
if v.AppID == appInfo.AppID {
appAssBind = true
}
}
if !appAssBind {
log.Errorf("GetDevInfo sdk key not ass binding,appId:[%s]", appInfo.AppID)
return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appInfo.AppTag) > 0 {
for _, v := range appInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
buildInfo.CodeId = info.Id
buildInfo.CoreDescription = appInfo.CoreDescription
buildInfo.Created = info.Created
buildInfo.CreatedBy = info.CreatedBy
err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, info.CustomData, domainInfo, "cache")
if err != nil {
log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, errCode)
}
buildInfo.CustomData = customData
buildInfo.CustomData.DetailDescription = appInfo.CustomData.DetailDescription
buildInfo.GroupId = info.GroupID
buildInfo.GroupName = groupInfo.GroupName
buildInfo.Logo = appInfo.Logo
buildInfo.Name = appInfo.Name
buildInfo.Version = info.Version
buildInfo.AppId = info.AppID
buildInfo.IsTemp = false
buildInfo.NeedCrt = domainInfo.NeedCrt
buildInfo.DeveloperStatus = int32(getAccountStatus(groupInfo))
buildInfo.AppTag = appTagArr
buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType)
buildInfo.ProjectType = int32(appInfo.ProjectType)
//buildInfoCacheByte, _ = json.Marshal(buildInfo)
//avs.rc.Set(ctx, avs.getDevInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime)
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, info.AppID)
if err == nil {
buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo)
//return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
return buildInfo, rsp
}
type GetRuleEngineVerPubListRspItem struct {
Version int `json:"version"`
VersionStr string `json:"versionStr"`
}
type VerToDescItem struct {
Version int `json:"version"`
Desc string `json:"desc"`
}
type GetRuleEngineVerPubListRsp struct {
VerList []GetRuleEngineVerPubListRspItem `json:"verList"` //大于等于MaxPubVer的序列号列表
NowPubVer GetRuleEngineVerPubListRspItem `json:"nowPubVer"` //当前上架版本
MaxPubVer GetRuleEngineVerPubListRspItem `json:"maxPubVer"` //已发布、已下架、审核通过三种状态里面的最大版本号
VerToDesc []VerToDescItem `json:"verToDesc"` //序列号到版本描述的映射
}
func (as *AppService) GetRuleEngineVerPubList(ctx context.Context, appId string) (interface{}, *utility.SvrRsp) {
rspData := GetRuleEngineVerPubListRsp{}
rsp := utility.DefaultSvrRsp()
pubVer, err := as.appRepo.GetOnlineAppVer(ctx, appId)
if err != nil {
if repository.NotFound(err) {
rspData.NowPubVer = GetRuleEngineVerPubListRspItem{Version: -1, VersionStr: ""}
} else {
log.Errorf("GetOnlineAppVer err:%s", err.Error())
return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
rspData.NowPubVer.Version = pubVer.Sequence
rspData.NowPubVer.VersionStr = pubVer.Version
maxVerSeq := 0
latestPubVer, err := as.appRepo.GetLatestPubAppVer(ctx, appId)
if err != nil {
if repository.NotFound(err) {
rspData.MaxPubVer.Version = 0
rspData.VerList = make([]GetRuleEngineVerPubListRspItem, 0)
} else {
log.Errorf("GetLatestPubAppVer err:%s", err.Error())
return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
maxVerSeq = latestPubVer.Sequence
rspData.MaxPubVer.Version = latestPubVer.Sequence
rspData.MaxPubVer.VersionStr = latestPubVer.Version
permitPubList, err := as.appRepo.GetAllPermitGrayPubVers(ctx, appId, maxVerSeq)
if err != nil {
log.Errorf("GetAllPermitGrayPubVers err:%s", err.Error())
return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
for _, v := range permitPubList {
item := GetRuleEngineVerPubListRspItem{
Version: v.Sequence,
VersionStr: v.Version,
}
rspData.VerList = append(rspData.VerList, item)
}
//获取版本号对应的版本说明
type VerToDescTemp struct {
Sequence int `bson:"sequence"`
CustomData map[string]interface{} `bson:"customData"`
}
verList, _, err := as.appRepo.GetAllVers(ctx, appId)
if err != nil {
log.Errorf("GetAllVers err:%s", err.Error())
return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
for _, v := range verList {
item := VerToDescItem{}
item.Version = v.Sequence
item.Desc = v.CustomData.VersionDescription
rspData.VerToDesc = append(rspData.VerToDesc, item)
}
log.Infof("GetRuleEngineVerPubList rsp:%+v", rspData)
return rspData, rsp
}
type ListAppsReq struct {
PullType string
PageNo int
PageSize int
SearchText string
SortType string
UserId string
GroupId string
IsDev bool
}
func (as *AppService) DevListApps(ctx context.Context, req *ListAppsReq) (int, []entity.App, error) {
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, req.UserId)
if err != nil {
log.Errorf("DevListApps GetGroupInfoByUserId err:%s", err.Error())
return 0, nil, err
}
total, list, err := as.appRepo.ListApps(ctx, groupInfo.GroupID, req.PageNo, req.PageSize, req.SearchText, req.SortType, req.PullType)
if err != nil {
if repository.NotFound(err) {
log.Infof("DevListApps empty!")
return 0, []entity.App{}, nil
}
return 0, nil, err
}
return total, list, err
}
func (as *AppService) AdminListApps(ctx context.Context, req *ListAppsReq) (int, []entity.App, error) {
total, list, err := as.appRepo.ListApps(ctx, req.GroupId, req.PageNo, req.PageSize, req.SearchText, req.SortType, req.PullType)
if err != nil {
if repository.NotFound(err) {
log.Infof("DevListApps empty!")
return 0, []entity.App{}, nil
}
return 0, nil, err
}
return total, list, err
}
func (as *AppService) AdminListPubApps(ctx context.Context, req *ListAppsReq) (int, []entity.AppVersion, error) {
list, total, err := as.appRepo.GetPublishedAppList(ctx, req.PageNo, req.PageSize, req.SearchText)
if err != nil {
if repository.NotFound(err) {
log.Infof("DevListApps empty!")
return 0, []entity.AppVersion{}, nil
}
return 0, nil, err
}
return total, list, err
}
type DevListAppsAndReviewsReq struct {
ListType string `form:"listType"`
GroupId string `form:"groupId"`
AppId string `form:"appId"`
Query string `form:"query"`
Sort string `form:"sort"`
SearchFields string `form:"searchFields"`
SearchText string `form:"searchText"`
PageSize int `form:"pageSize"`
PageNo int `form:"pageNo"`
ReviewsPageSize int `form:"reviewsPageSize"`
ReviewsPageNo int `form:"reviewsPageNo"`
}
type DevListAppsAndReviewsRsp struct {
Total int `json:"total"`
List []AppsAndReviewRspItem `json:"list"`
}
type ReviewsRsp struct {
Total int `json:"total"`
List []ReviewsRspItem `json:"list"`
}
type AppsAndReviewRspItem struct {
AppId string `json:"appId"`
Name string `json:"name"`
Logo string `json:"logo"`
Version string `json:"version"`
Status string `json:"status"`
ReviewTotal int `json:"reviewTotal"`
ReviewList []ReviewsRspItem `json:"reviewList"`
}
type ReviewsRspItem struct {
Sequence int `json:"sequence"`
Status string `json:"status"`
Version string `json:"version"`
}
func (as *AppService) ListAppAndReviews(ctx context.Context, appId string, pageNo, pageSize int) (interface{}, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
total, appVers, err := as.appRepo.ListAppVersByAppId(ctx, appId, pageNo, pageSize)
if err != nil {
log.Errorf("ListAppVers err:%s", err.Error())
return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
rspData := ReviewsRsp{}
rspData.List = make([]ReviewsRspItem, 0)
for _, v := range appVers {
reviewInfo := ReviewsRspItem{}
reviewInfo.Status = v.Status.Value
reviewInfo.Sequence = v.Sequence
reviewInfo.Version = v.Version
rspData.List = append(rspData.List, reviewInfo)
}
rspData.Total = total
return rspData, rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) GetAppsByAppIds(ctx context.Context, appIds []string) ([]entity.App, error) {
return as.appRepo.GetAppsByAppIds(ctx, appIds)
}
func (as *AppService) GetAppsToBinding(ctx context.Context, req apiproto.ListAppsToBindReq) (int, []entity.App, error) {
return as.appRepo.GetAppsToBinding(ctx, req.BindingId, req.PageNo, req.PageSize, req.SearchText)
}
func (as *AppService) GetLinkAppsByBindingID(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) {
return as.appRepo.GetLinkAppsByBindingId(ctx, bindingId, pageNo, pageSize, searchText)
}
func (as *AppService) GetLinkAppsBySDKKey(ctx context.Context, sdkKey string, pageNo, pageSize int) (int, []entity.App, error) {
return as.appRepo.GetLinkAppsBySDKKey(ctx, sdkKey, pageNo, pageSize)
}
func (as *AppService) AdminGetLinkApps(ctx context.Context, searchText string, pageNo, pageSize int) (int, interface{}, error) {
return as.appRepo.AdminGetLinkApps(ctx, pageNo, pageSize, searchText)
}
func (as *AppService) AdminGetAppReviews(ctx context.Context, req apiproto.AdminGetAppReviewsReq) (int, []entity.AppVersion, error) {
return as.appRepo.GetAppReviews(ctx, req)
}
func (as *AppService) UpdateGrayPubStatus(ctx context.Context, appId string, seq int, status bool) error {
return as.appRepo.UpdateGrayStatus(ctx, appId, seq, status)
}
func (as *AppService) GetAppInfo(ctx context.Context, appId string) (entity.App, error) {
return as.appRepo.GetAppInfo(ctx, appId)
}
func (as *AppService) ListAppVer(ctx context.Context, appId string, pageNo, pageSize int) (int, []entity.AppVersion, error) {
return as.appRepo.ListAppVersByAppId(ctx, appId, pageNo, pageSize)
}
func (as *AppService) AdminListAppVer(ctx context.Context, pageNo, pageSize int, searchText, t string, groupId string) (int, []entity.AppVersion, error) {
return as.appRepo.ListAppVers(ctx, pageNo, pageSize, searchText, t, groupId)
}
func (as *AppService) UpdateBuildInfo(ctx context.Context, c *gin.Context, userId string, req apiproto.UpdateAppInfoReq) error {
accountInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("UpdateBuildInfo err:%s", err.Error())
return err
}
oper := accountInfo.Account
reqFrom := c.GetHeader("C-Open-Api")
if reqFrom != "" {
req.Username = reqFrom
oper = reqFrom
}
info := entity.AppBuildInfo{
Id: bson.NewObjectId().Hex(),
BuildInfoId: req.BuildInfoId,
AppID: req.AppId,
Source: entity.APP_BUILD_SOURCE_BUILD,
Version: req.UpInfo.Version,
//VersionDescription: req.UpInfo.CustomData.VersionDescription,
GroupID: accountInfo.OrganId,
UserId: req.UserId,
Created: utils.GetNowMs(),
CreatedBy: req.Username,
CustomData: req.UpInfo.CustomData,
Status: true,
StartParams: entity.AppStartParams{},
}
info.CustomData.Developer = oper
err = as.buildRepo.Insert(ctx, info)
if err != nil {
log.Errorf("insert build info err:%s", err.Error())
return err
}
//操作日志
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, info.GroupID, kafka.GenContent(kafka.APP_EDIT_INFO_LOG, req.UpInfo.Version, info.AppID), logExp, oper)
return nil
}
type GetAppClassPerRspItem struct {
AppClass string `json:"appClass"`
AppClassName string `json:"appClassName"`
Count int `json:"count"`
}
type GetAppClassPerRsp struct {
List []GetAppClassPerRspItem `json:"list"`
}
func (as *AppService) GetAppClassPer(ctx context.Context, status string) (*GetAppClassPerRsp, error) {
rspList, err := as.appRepo.GetAppClassPer(ctx, status)
if err != nil {
return nil, err
}
rspData := GetAppClassPerRsp{}
rspData.List = make([]GetAppClassPerRspItem, 0)
for _, v := range rspList {
item := GetAppClassPerRspItem{
AppClass: v.Class,
Count: v.Count,
}
if len(v.Name) > 0 {
item.AppClassName = v.Name[0]
}
rspData.List = append(rspData.List, item)
}
return &rspData, nil
}
type GetGrayStatisticsVerListRspListItem struct {
PubTime int64 `json:"pub_time"`
UnPubTime int64 `json:"un_pub_time"`
Version int `json:"version"`
VersionStr string `json:"version_str"`
}
type GetGrayStatisticsVerListRsp struct {
Total int `json:"total"`
List []GetGrayStatisticsVerListRspListItem `json:"list"`
}
func (as *AppService) GetGrayStatisticsVerList(ctx context.Context, appId string, ver int, beginTime, endTime int64) (GetGrayStatisticsVerListRsp, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
num, verInfoList, err := as.appRepo.GetGrayStatisticsVerList(ctx, appId, ver, beginTime, endTime)
if err != nil {
log.Errorf("GetGrayStatisticsVerList err:%s", err.Error())
if repository.NotFound(err) {
return GetGrayStatisticsVerListRsp{Total: 0, List: make([]GetGrayStatisticsVerListRspListItem, 0)}, rsp
}
return GetGrayStatisticsVerListRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
log.Debugf("GetGrayStatisticsVerList num:%d,err:%+v,ver list:%+v", num, err, verInfoList)
rspData := GetGrayStatisticsVerListRsp{
List: make([]GetGrayStatisticsVerListRspListItem, 0),
}
for _, v := range verInfoList {
item := GetGrayStatisticsVerListRspListItem{}
item.PubTime = v.PublishedStatus.LastUpdated
item.UnPubTime = v.UnpublishedStatus.LastUpdated
item.Version = v.Sequence
item.VersionStr = v.Version
rspData.List = append(rspData.List, item)
}
rspData.Total = num
return rspData, rsp
}
type InternalGetAppVerInfoRsp struct {
AppID string `json:"appId"`
Name string `json:"name"`
Sequence int `json:"sequence"`
AppClass string `json:"appClass"`
AppTag []string `json:"appTag"`
AppType string `json:"appType"`
Status proto.AppRspStatus `json:"status"`
DeveloperID string `json:"developerId"`
DeveloperStatus int `json:"developerStatus"`
GroupID string `json:"groupId"`
GroupName string `json:"groupName"`
Created int64 `json:"created"`
CreatedBy string `json:"createdBy"`
CustomData proto.AppRspCustomData `json:"customData"`
Version string `json:"version"`
CorporationID string `json:"corporationId"`
CoreDescription string `json:"coreDescription"`
Logo string `json:"logo"`
GroupStatus int `json:"groupStatus,omitempty"` //todo:目前在缓存中,会返回给客户
InGrayRelease bool `json:"inGrayRelease"` //是否在灰度发布中
IsTemp bool `json:"isTemp"`
NeedCrt bool `json:"needCrt"`
WechatLoginInfo proto.WechatLoginInfo `json:"wechatLoginInfo"`
PrivacySettingType int `json:"privacySettingType"`
ProjectType int `json:"projectType"`
}
func (as *AppService) OpenApiGetAppVerInfo(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) {
log.Infof("OpenApiGetAppVerInfo appId:%s,sequence:%d,sdkver:%s", appId, sequence, sdkVer)
rsp := utility.DefaultSvrRsp()
tempRspInfo, err := as.getTempAppInfo(ctx, appId, sequence)
log.Debugf("getTempAppInfo rsp:%+v,err:%+v", tempRspInfo, err)
if err == nil {
return tempRspInfo, rsp
}
//if sequence != 0 {
// appVerCacheRspInfo, err := as.openApiGetAppVerInfoFromCache(ctx, appId, sequence, sdkVer)
// if err == nil {
// return appVerCacheRspInfo, http.StatusOK, common.OK
// }
//}
return as.openApiGetAppVerInfoNoCache(ctx, appId, sequence, sdkVer)
}
func (as *AppService) getTempAppBuildInfo(ctx context.Context, codeId string) (*pb.BuildAppInfo, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
tempRspInfo, err := as.getTempAppInfo(ctx, codeId, 1)
log.Infof("getTempAppInfo rsp:%+v,err:%+v", tempRspInfo, err)
if err != nil {
log.Errorf("getTempAppInfo err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
appInfo, err := as.appRepo.GetAppInfo(ctx, tempRspInfo.AppID)
if err != nil && !NotFound(err) {
log.Errorf("GetTrialInfo GetAppInfo err:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appInfo.AppTag) > 0 {
for _, v := range appInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
buildInfo := new(pb.BuildAppInfo)
buildInfo.CodeId = codeId
buildInfo.CoreDescription = tempRspInfo.CoreDescription
buildInfo.Created = tempRspInfo.Created
buildInfo.CreatedBy = tempRspInfo.CreatedBy
buildInfo.CustomData = ConvertRpcCustomDataToPb(tempRspInfo.CustomData)
buildInfo.CustomData.AppRuntimeDomain = new(pb.AppRuntimeDomain)
buildInfo.GroupId = tempRspInfo.GroupID
buildInfo.GroupName = tempRspInfo.GroupName
buildInfo.Logo = tempRspInfo.Logo
buildInfo.Name = tempRspInfo.Name
buildInfo.Version = tempRspInfo.Version
buildInfo.IsTemp = true
buildInfo.NeedCrt = tempRspInfo.NeedCrt
buildInfo.AppId = tempRspInfo.AppID
buildInfo.AppTag = appTagArr
buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType)
buildInfo.ProjectType = int32(tempRspInfo.ProjectType)
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, tempRspInfo.AppID)
if err == nil {
buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo)
//return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
return buildInfo, rsp.SetLoc(http.StatusOK, utility.OK)
}
func (as *AppService) getTempAppInfo(ctx context.Context, appId string, seq int) (InternalGetAppVerInfoRsp, error) {
rspInfo := InternalGetAppVerInfoRsp{}
//首先判断是否在临时表中
appTempInfo, err := as.tempAppRepo.GetInfoByAppIdAndSeq(ctx, appId, seq)
if err != nil {
return rspInfo, err
}
rspInfo = InternalGetAppVerInfoRsp{
AppID: appTempInfo.AppID,
Name: appTempInfo.Name,
Sequence: appTempInfo.Sequence,
AppClass: appTempInfo.AppClass,
AppType: appTempInfo.AppType,
Status: proto.AppRspStatus{
Value: appTempInfo.Status.Value,
Reason: appTempInfo.Status.Reason,
LastUpdated: appTempInfo.Status.LastUpdated,
ModifiedBy: appTempInfo.Status.ModifiedBy,
},
DeveloperID: appTempInfo.DeveloperID,
GroupID: appTempInfo.GroupID,
GroupName: "",
Created: appTempInfo.Created,
CreatedBy: appTempInfo.CreatedBy,
Version: appTempInfo.Version,
CoreDescription: appTempInfo.CoreDescription,
Logo: appTempInfo.Logo,
ProjectType: appTempInfo.ProjectType,
}
rspInfo.CustomData.DetailDescription = appTempInfo.CustomData.DetailDescription
rspInfo.CustomData.VersionDescription = appTempInfo.CustomData.VersionDescription
rspInfo.CustomData.AppRuntimeDomain.Business.Domains = []string{} // = domainData.Business
rspInfo.CustomData.AppRuntimeDomain.Service.Request = []string{} // = domainData.Service
rspInfo.CustomData.AppRuntimeDomain.Service.Socket = []string{}
rspInfo.CustomData.AppRuntimeDomain.Service.Download = []string{}
rspInfo.CustomData.AppRuntimeDomain.Service.Upload = []string{}
rspInfo.CustomData.AppRuntimeDomain.Whitelist.Domains = []string{} // = domainData.Whitelist
rspInfo.CustomData.AppRuntimeDomain.Blacklist.Domains = []string{}
rspInfo.CustomData.SourceFile = make([]proto.RspCustomDataSourceFile, 0)
if len(appTempInfo.CustomData.SourceFile) > 0 {
temp := appTempInfo.CustomData.SourceFile[0]
item := proto.RspCustomDataSourceFile{}
item.SourceFileUrl = ""
item.FileMd5 = temp.FileMd5
item.Url = temp.Url
item.UploadDate = temp.UploadDate
item.Name = temp.Name
item.BasicPackVer = temp.BasicPackVer
item.Packages = convertPackages2(temp.EncryptPackages)
rspInfo.CustomData.SourceFile = append(rspInfo.CustomData.SourceFile, item)
}
rspInfo.IsTemp = true
rspInfo.NeedCrt = false
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId)
if err == nil {
rspInfo.WechatLoginInfo = *wechatLoginInfo
//return rspInfo, errors.New("get wechatLoginInfo err")
}
return rspInfo, nil
}
func (as *AppService) openApiGetAppVerInfoFromCache(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, error) {
return InternalGetAppVerInfoRsp{}, nil
//verCache := cache.NewAppVerCache()
//cacheInfoByte, err := verCache.Get(ctx, avs.genOpenApiCacheKey(appId, sequence))
//if err != nil {
// log.Warnf("cache get app ver info err:[%s],app id:[%s],seq:[%d]", err.Error(), appId, sequence)
// return nil, err
//}
////走缓存
//log.Debugf("AppVerService OpenApiGetAppVerInfo in cache ...")
//cacheRspInfo := OpenApiAppVerCacheInfo{}
//err = json.Unmarshal(cacheInfoByte, &cacheRspInfo)
//if err != nil {
// return nil, err
//}
//
//rspInfo := InternalGetAppVerInfoRsp{
// AppID: cacheRspInfo.AppID,
// Name: cacheRspInfo.Name,
// Sequence: cacheRspInfo.Sequence,
// AppClass: cacheRspInfo.AppClass,
// AppType: cacheRspInfo.AppType,
// Status: cacheRspInfo.Status,
// DeveloperID: cacheRspInfo.DeveloperID,
// DeveloperStatus: cacheRspInfo.DeveloperStatus,
// GroupID: cacheRspInfo.GroupID,
// GroupName: cacheRspInfo.GroupName,
// Created: cacheRspInfo.Created,
// CreatedBy: cacheRspInfo.CreatedBy,
// Version: cacheRspInfo.Version,
// CorporationID: cacheRspInfo.CorporationID,
// CoreDescription: cacheRspInfo.CoreDescription,
// Logo: cacheRspInfo.Logo,
// InGrayRelease: cacheRspInfo.InGrayRelease,
//}
//
//err, _, customData := ConvertModelCustomDataToRpc(ctx, avs, cacheRspInfo.GroupID, cacheRspInfo.CustomData, &cacheRspInfo.DomainData, sdkVer)
//if err != nil {
// log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error())
// return nil, err
//}
//rspInfo.CustomData = *customData
//rspInfo.IsTemp = false
//rspInfo.NeedCrt = cacheRspInfo.DomainData.NeedCrt
//return &rspInfo, nil
}
func (as *AppService) openApiGetAppVerInfoNoCache(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
if sequence == 0 {
return as.GetInDevApp(ctx, appId, sdkVer)
}
appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, sequence)
if err != nil {
log.Errorf("InternalGetAppVerInfo get appVer info err:%s", err.Error())
if repository.NotFound(err) {
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND)
}
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
//校验企业的状态
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID)
log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED)
}
}
//获取域名
domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVer.GroupID)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR)
}
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("as.appRepo.GetAppInfo err:%s", err.Error())
if repository.NotFound(err) {
log.Errorf("get appVer not found!")
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appVer.AppTag) > 0 {
for _, v := range appVer.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
log.Debugln("AppTag:", appTagArr)
rspInfo := InternalGetAppVerInfoRsp{
AppID: appVer.AppID,
Name: appVer.Name,
Sequence: appVer.Sequence,
AppClass: appVer.AppClass,
AppTag: appTagArr,
AppType: appVer.AppType,
Status: proto.AppRspStatus{
Value: appVer.Status.Value,
Reason: appVer.Status.Reason,
LastUpdated: appVer.Status.LastUpdated,
ModifiedBy: appVer.Status.ModifiedBy,
},
DeveloperID: appVer.DeveloperID,
GroupID: appVer.GroupID,
GroupName: groupInfo.GroupName,
Created: appVer.Created,
CreatedBy: appVer.CreatedBy,
Version: appVer.Version,
CorporationID: appVer.CorporationID,
CoreDescription: appVer.CoreDescription,
Logo: appVer.Logo,
InGrayRelease: appVer.InGrayRelease,
PrivacySettingType: appInfo.PrivacySettingType,
ProjectType: appInfo.ProjectType,
}
err, errCode, customData := ConvertModelCustomDataToRpc(ctx, appVer.GroupID, appVer.CustomData, domainData, sdkVer)
if err != nil {
log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, errCode)
}
status := getAccountStatus(groupInfo)
rspInfo.CustomData = *customData
rspInfo.GroupStatus = groupInfo.ReviewStatus
rspInfo.IsTemp = false
rspInfo.NeedCrt = domainData.NeedCrt
rspInfo.DeveloperStatus = status
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId)
if err == nil {
rspInfo.WechatLoginInfo = *wechatLoginInfo
//return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
log.Debugf("rsp info:%+v", rspInfo)
return rspInfo, rsp
}
//兼容之前sequence为0的情况
func (as *AppService) GetInDevApp(ctx context.Context, appId, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) {
rsp := utility.DefaultSvrRsp()
app, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("openApiGetAppVerInfoNoCache GetAppInfo err:%,appId:[%]", err.Error(), appId)
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
buildInfo, err := as.buildRepo.GetLatestInfoByAppId(ctx, appId)
if err != nil {
log.Errorf("openApiGetAppVerInfoNoCache GetLatestInfoByAppId err:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
log.Debugf("GetInDevApp buildInfo:%+v", buildInfo)
//校验企业的状态
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, app.GroupID)
log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED)
}
}
//获取域名
domainData, err := hCaller.GetDomainInfoByOrganId(ctx, app.GroupID)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR)
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(app.AppTag) > 0 {
for _, v := range app.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
rspInfo := InternalGetAppVerInfoRsp{
AppID: app.AppID,
Name: app.Name,
Sequence: app.Sequence,
AppClass: app.AppClass,
AppType: app.AppType,
Status: proto.AppRspStatus{
Value: app.Status.Value,
Reason: app.Status.Reason,
LastUpdated: app.Status.LastUpdated,
ModifiedBy: app.Status.ModifiedBy,
},
DeveloperID: app.DeveloperID,
GroupID: app.GroupID,
GroupName: groupInfo.GroupName,
Created: app.Created,
CreatedBy: app.CreatedBy,
Version: buildInfo.Version,
CorporationID: app.GroupID,
CoreDescription: app.CoreDescription,
Logo: app.Logo,
InGrayRelease: false,
AppTag: appTagArr,
PrivacySettingType: app.PrivacySettingType,
ProjectType: app.ProjectType,
}
err, errCode, customData := ConvertModelCustomDataToRpc(ctx, app.GroupID, buildInfo.CustomData, domainData, sdkVer)
if err != nil {
log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error())
return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, errCode)
}
status := getAccountStatus(groupInfo)
rspInfo.CustomData = *customData
rspInfo.GroupStatus = groupInfo.ReviewStatus
rspInfo.IsTemp = false
rspInfo.NeedCrt = domainData.NeedCrt
rspInfo.DeveloperStatus = status
log.Debugf("rsp info:%+v", rspInfo)
return rspInfo, rsp
}
func (as *AppService) UpExpire(ctx context.Context, appId string, expire int64) *utility.SvrRsp {
rsp := utility.DefaultSvrRsp()
err := as.appRepo.UpdateExpire(ctx, appId, expire)
if err != nil {
log.Errorf("AppService UpExpire err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
/*err = as.appRepo.UpdateExpireAppVersion(ctx, appId, 0, expire)
if err != nil {
log.Errorf("AppService UpExpire err:%s", err.Error())
return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}*/
return rsp.SetLoc(http.StatusOK, utility.OK)
}
type RuntimeGetAppResponse struct {
AppID string `json:"appId" bson:"appId"`
Name string `json:"name" bson:"name"`
Sequence int `json:"sequence" bson:"sequence"`
AppClass string `json:"appClass" bson:"appClass"`
AppTag []string `json:"appTag" bson:"appTag"`
AppType string `json:"appType" bson:"appType"`
DeveloperID string `json:"developerId" bson:"developerId"`
DeveloperStatus int `json:"developerStatus" bson:"developerStatus"`
GroupID string `json:"groupId" bson:"groupId"`
GroupName string `json:"groupName" bson:"groupName"`
Created int64 `json:"created" bson:"created"`
CreatedBy string `json:"createdBy" bson:"createdBy"`
CustomData proto.AppRspCustomData `json:"customData" bson:"customData"`
Version string `json:"version" bson:"version"`
CorporationID string `json:"corporationId" bson:"corporationId"`
CoreDescription string `json:"coreDescription" bson:"coreDescription"`
Logo string `json:"logo" bson:"logo"`
Status proto.AppRspStatus `json:"status" bson:"status"`
InGrayRelease bool `json:"inGrayRelease" bson:"inGrayRelease"` //是否在灰度发布中
IsTemp bool `json:"isTemp"`
NeedCrt bool `json:"needCrt"` //是否需要校验域名证书
WechatLoginInfo proto.WechatLoginInfo `json:"wechatLoginInfo"`
PrivacySettingType int `json:"privacySettingType"`
ProjectType int `json:"projectType"`
}
func (as *AppService) RuntimeGetPubAppInfo(ctx context.Context, sdkKey, appId, sdkVer string) (RuntimeGetAppResponse, *utility.SvrRsp) {
resp := &RuntimeGetAppResponse{}
rsp := utility.DefaultSvrRsp()
inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry)
//未命中缓存
start := time.Now()
log.Infof("RuntimeGetPubAppInfo from cache no match ... ")
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("RuntimeGetPubAppInfo GetAppInfo err:%s", err.Error())
if repository.NotFound(err) {
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND)
}
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if appInfo.IsForbidden == 1 {
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN)
}
app, err := as.appRepo.GetOnlineAppVer(ctx, appId)
if err != nil {
if repository.NotFound(err) {
log.Errorf("RuntimeGetPubAppInfo get info app status invalid,appId:%s", appId)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_SERVICE_UNAVAILABLE)
}
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
log.Debugf("RuntimeGetPubAppInfo online app:%+v", app)
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appInfo.AppTag) > 0 {
for _, v := range appInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
//支付信息过期校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
appStatus, err := as.CheckIdStatus(ctx, appId)
if err != nil {
log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appId)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if appStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("check purch status no ok ")
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE)
}
}
//获取机构信息
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, app.GroupID)
if err != nil {
log.Errorf("Failed to call GetGroupInfoByUserId: %v", err)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
status := getAccountStatus(groupInfo)
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("group review status no ok ")
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("group review status no ok ")
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
}
//获取域名信息
domainData, err := hCaller.GetAppDomainByOrganId(ctx, app.GroupID)
if err != nil {
log.Errorf("Failed to call GetDomainInfo: %v", err)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
//应用状态信息校验
if !inWhiteList {
//首先判断sdkKey是否存在
var bindingInfo *entity.Binding
bindingInfo, err = as.bindingRepo.GetBindingByGroupIdAndSdkKey(ctx, app.GroupID, sdkKey)
if err != nil {
log.Errorf("GetBindingByGroupIdAndSdkKey err:%s", err.Error())
if repository.NotFound(err) {
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_SIGNATURE_SDKKEY_INVAILD)
}
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if bindingInfo.CooperateStatus.Value != entity.StBindValid {
log.Errorf("binding coop stats valid,appId:%s,sdkKey:%s", appId, sdkKey)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED)
}
for _, v := range bindingInfo.BundleInfos {
if v.SDKKey == sdkKey && v.IsForbidden == 1 {
log.Errorf("bundleInfo is forbidden", bindingInfo)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
}
isAppAssBind := false
for _, v := range bindingInfo.AppInfos {
if v.AppID == appId {
isAppAssBind = true
}
}
if !isAppAssBind {
log.Errorf("app id not ass binding,appId:%s,sdkKey:%s", appId, sdkKey)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
//支付信息校验
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID)
if err != nil {
log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("binding pay check no ok,bingdingId:%s", bindingInfo.BindingID)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE)
}
}
}
if GetLicenseValid() != LICENSE_IS_VALID {
log.Errorf("license valid no ok ... ")
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_LICENSE_INVALID_ERR)
}
//返回数据
err = covertAppToRsp(ctx, &app, resp, sdkVer, domainData)
if err != nil {
log.Errorf("covertAppToRsp err:%s", err.Error())
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
resp.GroupName = groupInfo.GroupName
resp.DeveloperStatus = status
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId)
if err == nil {
resp.WechatLoginInfo = *wechatLoginInfo
//return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
resp.AppTag = appTagArr
resp.PrivacySettingType = appInfo.PrivacySettingType
resp.ProjectType = appInfo.ProjectType
log.Infof("resp:%v", resp)
fmt.Println("RuntimeGetPubAppInfo get app no cache time consum:", time.Since(start))
return *resp, rsp.SetLoc(http.StatusOK, utility.OK)
}
//type RuleEngineGetAppVerInfoRsp struct {
// AppID string `json:"appId"`
// Name string `json:"name"`
// Sequence int `json:"sequence"`
// AppClass string `json:"appClass"`
// AppType string `json:"appType"`
// DeveloperID string `json:"developerId"`
// DeveloperStatus int `json:"developerStatus"`
// GroupID string `json:"groupId"`
// GroupName string `json:"groupName"`
// Created int64 `json:"created"`
// CreatedBy string `json:"createdBy"`
// CustomData proto.AppRspCustomData `json:"customData"`
// Version string `json:"version"`
// CorporationID string `json:"corporationId"`
// CoreDescription string `json:"coreDescription"`
// Logo string `json:"logo"`
// Status proto.AppRspStatus `json:"status"`
// InGrayRelease bool `json:"inGrayRelease"` //是否在灰度发布中
// IsTemp bool `json:"isTemp"`
// NeedCrt bool `json:"needCrt"`
//}
func (as *AppService) RuleEngineGetAppVerInfo(ctx context.Context, appId string, sequence int, sdkKey, sdkVer string) (RuntimeGetAppResponse, *utility.SvrRsp) {
//appVerCache := cache.NewAppVerCache()
//appVerCacheInfoByte, err := appVerCache.Get(ctx, avs.genRuleEngineCacheKey(appId, sequence))
//if err == nil {
// log.Infof("RuleEngineGetAppVerInfo in cache ...")
// appVerInfo := RuleEngineAppVerCacheInfo{}
// err = json.Unmarshal(appVerCacheInfoByte, &appVerInfo)
// if err == nil {
// //判断是否关联
// if _, ok := appVerInfo.BindStatus[sdkKey]; ok {
// rsp, err := avs.covertCacheToRuleEngineRsp(ctx, &appVerInfo, sdkVer)
// if err != nil {
// log.Errorf("covertCacheToRuleEngineRsp err:%s", err.Error())
// return nil, http.StatusInternalServerError, common.FS_SYSTEM_CALL
// }
// return rsp, http.StatusOK, common.OK
// }
// }
//}
//未命中缓存
resp := RuntimeGetAppResponse{}
rsp := utility.DefaultSvrRsp()
//首先校验licesne
if GetLicenseValid() != LICENSE_IS_VALID {
log.Errorf("RuleEngineGetAppVerInfo get info license invalid,sdkKey:%s,appId:%s,sequence:%d", sdkKey, appId, sequence)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_LICENSE_INVALID_ERR)
}
appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, sequence)
if err != nil {
log.Errorf("GetAppVerInfo err:%s", err.Error())
if repository.NotFound(err) {
return resp, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND)
}
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
//校验企业的状态,非法状态不放入缓存
log.Infof("get group info id:%s", appVer.GroupID)
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID)
log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo)
if err != nil {
log.Errorf("RuleEngineGetAppVerInfo ger group info err:%s", err.Error())
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED)
}
status := getAccountStatus(groupInfo)
if config.Cfg.IsUatEnv() {
if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
} else {
if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) {
log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID)
}
}
//if !avs.isOrganValid(groupInfo.ReviewStatus) {
// log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus)
// return nil, http.StatusForbidden, common.FS_ORGAN_STATUS_INVALID
//}
inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry)
if !inWhiteList {
//校验应用关联状态,非法状态不放入缓存
binds, err := as.bindingRepo.GetBindingByGroupIdAndSdkKey(ctx, appVer.GroupID, sdkKey)
if err != nil {
log.Errorf("GetBindingByGroupIdAndSdkKey err:%s,GroupID:%s,sdkKey:%s", err.Error(), appVer.GroupID, sdkKey)
if repository.NotFound(err) {
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_SIGNATURE_SDKKEY_INVAILD)
}
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR)
}
if binds.CooperateStatus.Value != entity.StBindValid {
log.Errorf("RuleEngineGetAppVerInfo CooperateStatus invalid:%s", binds.CooperateStatus.Value)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED)
}
for _, v := range binds.BundleInfos {
if v.SDKKey == sdkKey && v.IsForbidden == 1 {
log.Errorf("bundleInfo is forbidden", binds)
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
}
isAppAssBinding := false
for _, v := range binds.AppInfos {
if v.AppID == appId {
isAppAssBinding = true
}
}
if !isAppAssBinding {
log.Errorf("RuleEngineGetAppVerInfo get binding info no ass app,appId:%s,sdkKey:%s", appId, sdkKey)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND)
}
//校验应用支付状态
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
bindStatus, err := as.CheckIdStatus(ctx, binds.BindingID)
if err != nil {
log.Errorf("RuleEngineGetAppVerInfo get bind id pay status err:%s", err.Error())
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("GetGrayAppInfo get info bind pay status invaild,bind id:%s", binds.BindingID)
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_PAY_EXPIRE)
}
}
}
//校验小程序的上架状态
if appVer.Status.Value != entity.StPublished && !appVer.InGrayRelease {
log.Errorf("RuleEngineGetAppVerInfo appVer status invalid:%s", appVer.Status.Value)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_SERVICE_UNAVAILABLE)
}
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("RuleEngineGetAppVerInfo GetAppInfo err:%s", err.Error())
if repository.NotFound(err) {
return resp, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND)
}
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if appInfo.IsForbidden == 1 {
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN)
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR)
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagArr := make([]string, 0)
if len(appInfo.AppTag) > 0 {
for _, v := range appInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagArr = append(appTagArr, tag.Name)
}
}
}
}
//校验支付状态
if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() {
//先校验小程序
appStatus, err := as.CheckIdStatus(ctx, appId)
if err != nil {
log.Errorf("RuleEngineGetAppVerInfo get app id pay status err:%s", err.Error())
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
if appStatus == httpcall.PAY_ID_STATUS_EXPIRE {
log.Errorf("RuleEngineGetAppVerInfo get info app pay status invaild,appId:%s", appId)
return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE)
}
}
//获取域名
domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVer.GroupID)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error())
return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR)
}
err = covertAppToRsp(ctx, &appVer, &resp, sdkVer, domainData)
if err != nil {
log.Errorf("covertAppToRsp err:%s", err.Error())
return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
resp.DeveloperStatus = status
resp.GroupName = groupInfo.GroupName
resp.PrivacySettingType = appInfo.PrivacySettingType
resp.ProjectType = appInfo.ProjectType
resp.AppTag = appTagArr
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId)
if err == nil {
resp.WechatLoginInfo = *wechatLoginInfo
//return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL)
}
return resp, rsp
}
func (as *AppService) CheckIdStatus(ctx context.Context, id string) (int, error) {
return httpcall.PAY_ID_STATUS_USING, nil
/*switch config.Cfg.ReqType {
//case "grpc":
// return grpcClient.PurchasingGetIdStatus(ctx, id)
default:
status, _, err := hCaller.PayCheckIdStatus(ctx, id)
return status, err
}*/
}
func (as *AppService) BatchAppsByIdentity(ctx context.Context, sdkKey string, req *apiproto.BatchAppsByIdentityReq) *pb.BatchAppsByIdentityRsp {
var (
rsp = new(pb.BatchAppsByIdentityRsp)
)
rsp.Data = new(pb.BatchAppsByIdentityRsp_DATA)
rsp.Data.AppList = make([]*pb.BatchAppsByIdentityRsp_AppListItem, 0)
rsp.Result = new(pb.CommonResult)
//判断sdkKey是否存在
sdkExi, err := as.bindingRepo.SdkKeyExi(ctx, sdkKey)
if err != nil {
utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_SYSTEM_CALL, &rsp.Result)
return rsp
}
if !sdkExi {
utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND, &rsp.Result)
return rsp
}
for _, item := range req.Apps {
rspAppListItem := as.getOneAppByIdentity(ctx, req.IdentityType, item.AppId, item.Identity, sdkKey)
rsp.Data.AppList = append(rsp.Data.AppList, rspAppListItem)
}
utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result)
return rsp
}
func (as *AppService) IdentityAppsCheck(ctx context.Context, sdkKey string, req *apiproto.IdentityAppsCheckReq) *pb.IdentityAppsCheckRsp {
var (
rsp = new(pb.IdentityAppsCheckRsp)
)
rsp.Data = new(pb.IdentityAppsCheckRsp_DATA)
rsp.Data.AppList = make([]*pb.IdentityAppsCheckRsp_AppListItem, 0)
rsp.Result = new(pb.CommonResult)
//判断sdkKey是否存在
sdkExi, err := as.bindingRepo.SdkKeyExi(ctx, sdkKey)
if err != nil {
utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_SYSTEM_CALL, &rsp.Result)
return rsp
}
if !sdkExi {
utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND, &rsp.Result)
return rsp
}
//判断一个小程序identity是否存在
//todo 加个缓存处理
for _, a := range req.Apps {
rspAppListItem := as.getOneAppCheckResult(ctx, a.AppId, a.Identity, req.IdentityType, sdkKey)
rsp.Data.AppList = append(rsp.Data.AppList, rspAppListItem)
}
utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result)
return rsp
}
func (as *AppService) getOneAppCheckResult(ctx context.Context, appId, identity, identityType, sdkKey string) (rspAppListItem *pb.IdentityAppsCheckRsp_AppListItem) {
rspAppListItem = &pb.IdentityAppsCheckRsp_AppListItem{
Errcode: utility.OK,
Error: utility.GetErrMsg(utility.OK),
Data: &pb.IdentityAppsCheckRsp_AppListItem_AppListItemData{AppId: appId, Identity: identity, IdentityValid: false},
}
defer func() {
rspAppListItem.Error = utility.GetErrMsg(rspAppListItem.Errcode)
}()
//cacheInfo, err := e.erc.GetAppCheckValid(ctx, appId, identity, sdkKey)
//if err == nil {
// log.Debugf("getOneAppCheckResult from cache,info:%+v", cacheInfo)
// rspAppListItem.Data.IdentityValid = cacheInfo.IdentityValid
// rspAppListItem.Errcode = cacheInfo.Errcode
// return rspAppListItem
//}
//defer func() {
//if rspAppListItem.Errcode != utility.FS_SYSTEM_CALL {
//setCacheInfo := &AppCheckCacheInfo{IdentityValid: rspAppListItem.Data.IdentityValid, Errcode: rspAppListItem.Errcode}
//log.Debugf("set app check cache info:%+v", cacheInfo)
//if err = e.erc.SetAppCheckValid(ctx, appId, identity, sdkKey, setCacheInfo); err != nil {
// log.Errorf("SetAppCheckValid err:%s", err.Error())
//}
//}
//}()
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("get app info err:%s", err.Error())
rspAppListItem.Errcode = utility.FS_SYSTEM_CALL
if repository.NotFound(err) {
rspAppListItem.Errcode = utility.FS_APP_ID_NOT_FOUND
}
return rspAppListItem
}
log.Debugf("get app info:%+v", appInfo)
//判断该小程序是否可用
if appInfo.Status.Value != entity.StPublished {
log.Errorf("app info status invalid,sdkKey:[%s],appInfo:%+v", sdkKey, appInfo)
return rspAppListItem
}
//判断企业状态
organInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID)
if err != nil {
log.Errorf("get group info err:%s", err.Error())
rspAppListItem.Errcode = utility.FS_SYSTEM_CALL
return rspAppListItem
} else {
if !hCaller.JudgeGroupStatusValid(organInfo.ReviewStatus) {
log.Errorf("gropu status invalid,sdkKey:[%s],appId:[%s]", sdkKey, appId)
rspAppListItem.Errcode = utility.FS_ORGAN_STATUS_INVALID
return rspAppListItem
}
}
//判断是否关联
bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey)
if err != nil {
log.Errorf("get binging info err:%s", err.Error())
rspAppListItem.Errcode = utility.FS_SYSTEM_CALL
if repository.NotFound(err) {
rspAppListItem.Errcode = utility.FS_BIND_NOT_FOUND
}
return rspAppListItem
} else {
if bindingInfo.CooperateStatus.Value == entity.StBindInvalid {
log.Errorf("binding info coop value invalid:%+v,sdkKey:[%s]", bindingInfo, sdkKey)
rspAppListItem.Errcode = utility.FS_COOPERATION_TERMINATED
return rspAppListItem
}
if !repository.IsAssAppId(bindingInfo, appId) {
log.Errorf("binding not ass the appid,sdkKey:[%s],appId:[%s]", sdkKey, appId)
rspAppListItem.Errcode = utility.FS_APP_NOT_ASS_BIND
return rspAppListItem
}
}
//判断版本状态
appVers, err := as.appRepo.GetAppVerLimitByIdentity(ctx, identityType, appId, identity, config.Cfg.CheckAppVerLimit)
if err != nil {
rspAppListItem.Errcode = utility.FS_SYSTEM_CALL
if repository.NotFound(err) {
rspAppListItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR
}
return rspAppListItem
} else {
if len(appVers) == 0 {
rspAppListItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR
return rspAppListItem
}
rspAppListItem.Data.IdentityValid = as.AppVerIsValid(appVers)
}
return rspAppListItem
}
func (as *AppService) getOneAppByIdentity(ctx context.Context, t, appId, identity, sdkKey string) *pb.BatchAppsByIdentityRsp_AppListItem {
rspItem := &pb.BatchAppsByIdentityRsp_AppListItem{
Errcode: utility.OK,
Error: utility.GetErrMsg(utility.OK),
AppId: appId,
Identity: identity,
AppInfo: nil,
ExternalAppStatus: "",
}
defer func() {
rspItem.Error = utility.GetErrMsg(rspItem.Errcode)
}()
appVers, err := as.appRepo.GetAppVerLimitByIdentity(ctx, t, appId, identity, config.Cfg.CheckAppVerLimit)
if err != nil {
rspItem.Errcode = utility.FS_SYSTEM_CALL
if repository.NotFound(err) {
rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR
}
return rspItem
}
if len(appVers) == 0 {
rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR
return rspItem
}
//从获取到的三个版本列表中取得一个合适的版本
appVer := as.GetConcreteVer(appVers)
if appVer == nil {
rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR
return rspItem
}
//判断企业状态
organInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID)
if err != nil {
rspItem.Errcode = utility.FS_SYSTEM_CALL
return rspItem
} else {
if !hCaller.JudgeGroupStatusValid(organInfo.ReviewStatus) {
rspItem.Errcode = utility.FS_ORGAN_STATUS_INVALID
return rspItem
}
}
//判断是否关联
bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appVer.GroupID, sdkKey)
log.Debugf("get binding info:%+v", bindingInfo)
if err != nil {
log.Errorf("get binging info err:%s", err.Error())
rspItem.Errcode = utility.FS_SYSTEM_CALL
if repository.NotFound(err) {
rspItem.Errcode = utility.FS_BIND_NOT_FOUND
}
return rspItem
} else {
if bindingInfo.CooperateStatus.Value == entity.StBindInvalid {
rspItem.Errcode = utility.FS_COOPERATION_TERMINATED
return rspItem
}
if !repository.IsAssAppId(bindingInfo, appId) {
rspItem.Errcode = utility.FS_APP_NOT_ASS_BIND
return rspItem
}
}
rspItem.AppInfo = new(pb.AppInfoRspData)
as.tool.CovertAppVerToAppRspData(appVer, rspItem.AppInfo)
//custom 包装
domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, appVer.GroupID) //域名
if err != nil {
log.Errorf("get domain err:%s", err.Error())
} else {
as.tool.PackDomainToAppRspCustom(rspItem.AppInfo, domainInfo)
}
rspItem.AppInfo.CustomData.MenuInfo = nil //菜单
apiData, err := hCaller.GetApiList(ctx, appVer.GroupID) //api管理
if err != nil {
log.Errorf("get api list err:%s", err.Error())
} else {
as.tool.PackApiInfoToAppRspCustom(rspItem.AppInfo, &apiData)
}
rspItem.AppInfo.GroupName = organInfo.GroupName //企业名称
rspItem.ExternalAppStatus = as.getAppVerExternalStatus(appVer.Status.Value, appVer.UnpublishedStatus.Type) //做一个状态的转换
//放入缓存
//e.erc.SetAppVerCacheInfo(ctx, appId, identity, &ExternalAppVerCacheInfo{AppInfo: rspItem.AppInfo, ExternalStatus: rspItem.ExternalAppStatus})
return rspItem
}
func (as *AppService) GetConcreteVer(appVers []entity.AppVersion) *entity.AppVersion {
if len(appVers) == 0 {
return nil
}
appVer := appVers[0]
for _, v := range appVers {
if v.Status.Value == entity.StPublished {
appVer = v
break
}
if v.Status.Value == entity.StUnpublished &&
v.UnpublishedStatus.Type == entity.TypeUnpublishedDueToNewSeq {
appVer = v
break
}
}
return &appVer
}
func (as *AppService) getAppVerExternalStatus(statusValue, unPubType string) string {
//做一个状态的转换
result := ""
switch statusValue {
case entity.StInDevelopment:
result = AppExternalStatusInDevelopment
case entity.StPublishing:
result = AppExternalStatusPublishing
case entity.StPublishWithdrawed:
result = AppExternalStatusPublishWithdrawed
case entity.StPublishApproved:
result = AppExternalStatusPublishApproved
case entity.StPublishRejected:
result = AppExternalStatusPublishRejected
case entity.StPublished:
result = AppExternalStatusPublished
case entity.StUnpublished:
switch unPubType {
case entity.TypeUnpublishedByDev:
result = AppExternalStatusUnpublishedByDev
case entity.TypeUnpublishedByAdmin:
result = AppExternalStatusUnpublishedByAdmin
case entity.TypeUnpublishedDueToNewSeq:
result = AppExternalStatusUnpublishedByNewSeq
}
}
return result
}
/*
* 第一优先级:AppID 为已上架 ,则可继续使用;如下架则全部不允许使用
* 第二优先级:
* 当AppID上架的情况下,MD5对应 已上架 / 系统下架,则允许继续使用;
* 如对应状态为在途(审核中/审核已撤销)的,则向下轮询3个序列号,如果3个序列号中包含 已上架/系统下架,则允许使用;如3个序列号均为在途状态,则返回不可用
* 如为其他状态(不在上述内容内),则返回不可用
*/
func (as *AppService) AppVerIsValid(appVers []entity.AppVersion) bool {
valid := false
for _, appVerInfo := range appVers {
if appVerInfo.Status.Value == entity.StPublishing ||
appVerInfo.Status.Value == entity.StPublishWithdrawed {
continue
}
//首先判断该版本是否可用
if appVerInfo.Status.Value != entity.StPublished &&
appVerInfo.Status.Value != entity.StUnpublished {
log.Errorf("app ver info invalid,app ver:%+v", appVerInfo)
valid = false
break
}
log.Debugf("get app ver info status:%+v", appVerInfo.Status)
//判断该版本下架方式:被运营端下架、被机构端下架、新版本下架
if appVerInfo.Status.Value == entity.StUnpublished {
if appVerInfo.UnpublishedStatus.Type == entity.TypeUnpublishedDueToNewSeq {
valid = true
break
}
}
if appVerInfo.Status.Value == entity.StPublished {
valid = true
break
}
}
log.Debugf("valid:[%v],appvers:%v", valid, appVers)
return valid
}
func (as *AppService) GenOfflinePackageInfo(ctx context.Context, appId string, seq int, userId string) (string, error) {
userInfo, err := hCaller.GetAccountInfo(ctx, userId)
if err != nil {
log.Errorf("GenOfflinePackageInfo GetDeveloperInfo err:%s", err.Error())
return "", err
}
appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq)
if err != nil {
log.Errorf("GenOfflinePackageInfo db err:%s", err.Error())
return "", err
}
if userInfo.OrganId != appVerInfo.GroupID {
log.Errorf("GenOfflinePackageInfo organ id no match app ver info group id")
return "", errors.New("group id not match")
}
//文件生成
if len(appVerInfo.CustomData.SourceFile) == 0 {
log.Errorf("GenOfflinePackageInfo CustomData.SourceFile empty!")
return "", errors.New("db info err")
}
//miniprogram.json
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVerInfo.GroupID)
if err != nil {
log.Errorf("get group info err:%s", err.Error())
return "", err
}
miniprogramInfo := covertAppVerToRuleEngineRsp(&appVerInfo)
//获取域名
domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVerInfo.GroupID)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error())
return "", err
}
err, _, customData := ConvertModelCustomDataToRpc(ctx, appVerInfo.GroupID, appVerInfo.CustomData, domainData, "cache")
if err != nil {
log.Errorf("covertCacheInfoToRsp ConvertModelCustomDataToRpc err:[%s]", err.Error())
return "", err
}
wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId)
if err != nil {
log.Errorf("covertCacheInfoToRsp ConvertModelCustomDataToRpc err:[%s]", err.Error())
return "", err
}
miniprogramInfo.CustomData = *customData
miniprogramInfo.GroupName = groupInfo.GroupName //附加
miniprogramInfo.NeedCrt = domainData.NeedCrt
miniprogramInfo.WechatLoginInfo = *wechatLoginInfo
sourceFile := appVerInfo.CustomData.SourceFile[0]
miniprogramJsonRsp := gin.H{
"error": "OK",
"errcode": "",
"data": miniprogramInfo,
}
dir := path.Join("/opt/finclip-offline-packages/", bson.NewObjectId().Hex())
fileDir := path.Join(dir, appVerInfo.AppID)
err = os.MkdirAll(fileDir, os.ModePerm)
if err != nil {
log.Errorf("mkdir err:%s", err.Error())
return "", err
}
defer os.RemoveAll(dir)
miniprogramJsonFileName := path.Join(fileDir, "miniprogram.json")
log.Debugf("file dir:%s", fileDir)
miniprogramJsonFile, err := os.OpenFile(miniprogramJsonFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
log.Errorf("open file err:%s", err.Error())
return "", err
}
defer miniprogramJsonFile.Close()
miniprogramJsonByte, _ := json.Marshal(miniprogramJsonRsp)
_, err = miniprogramJsonFile.Write(miniprogramJsonByte)
if err != nil {
log.Errorf("write file err:%s", err.Error())
return "", err
}
var fileList = make([]string, 0)
fileList = append(fileList, miniprogramJsonFileName)
log.Debugf("sourceFile:%+v", sourceFile)
if len(sourceFile.EncryptPackages) > 0 { //分包
//分包小程序存储位置
splitPackFileDir := path.Join(fileDir, "miniprogram")
log.Debugf("splitPackFileDir:%s", splitPackFileDir)
err = os.Mkdir(splitPackFileDir, os.ModePerm)
if err != nil {
log.Errorf("mkdir splitPackFileDir err:%s", err.Error())
return "", err
}
//下载多个包
splitPackFileList := make([]string, 0)
for _, p := range sourceFile.EncryptPackages {
tempList := strings.Split(p.FileUrl, "/")
fileBody, err := hCaller.DownloadByNetdiskId(ctx, tempList[len(tempList)-1])
if err != nil {
log.Errorf("download file err:%s", err.Error())
return "", err
}
fName := path.Join(splitPackFileDir, p.Filename)
tempFile, err := os.Create(fName)
if err != nil {
log.Errorf("create splitPackFileDir err:%s", err.Error())
return "", err
}
_, err = tempFile.Write(fileBody)
if err != nil {
log.Errorf("tempFile write err:%s", err.Error())
return "", err
}
tempFile.Close()
splitPackFileList = append(splitPackFileList, fName)
}
//压缩之后再删除源文件
miniprogramZipFileName := path.Join(fileDir, "miniprogram.zip")
err = ZipList(splitPackFileList, miniprogramZipFileName)
if err != nil {
log.Errorf("splitPackFileDir zip err:%s", err.Error())
return "", err
}
err = os.RemoveAll(splitPackFileDir)
if err != nil {
log.Errorf("splitPackFileDir remove err:%s", err.Error())
return "", err
}
fileList = append(fileList, miniprogramZipFileName)
} else { //整包
var fileUrl = sourceFile.SourceFileUrl
if sourceFile.EncryptedUrl != "" {
fileUrl = sourceFile.EncryptedUrl
}
if fileUrl == "" {
log.Errorf("file url empty,appId:[%s],sequence:[%d]", appId, seq)
return "", errors.New("db info err")
}
fileBody, err := hCaller.DownloadByNetdiskId(ctx, getFileId(fileUrl))
if err != nil {
log.Errorf("download file err:%s", err.Error())
return "", err
}
appFileName := path.Join(fileDir, "app.zip")
//appFileName := path.Join(fileDir, "miniprogram.zip")
appFile, err := os.OpenFile(appFileName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
log.Errorf("one packege open err:%s", err.Error())
return "", err
}
_, err = appFile.Write(fileBody)
appFile.Close()
if err != nil {
log.Errorf("one packege write file err:%s", err.Error())
return "", err
}
//再将小程序包压缩为miniprogram.zip
miniprogramZipFileName := path.Join(fileDir, "miniprogram.zip")
err = ZipList([]string{appFileName}, miniprogramZipFileName)
if err != nil {
log.Errorf("zip app file err:%s", err.Error())
return "", err
}
os.Remove(appFileName)
fileList = append(fileList, miniprogramZipFileName)
}
encryptPwd := utils.GenMd5("miniprogram" + appVerInfo.AppID)
log.Debugf("encryptPwd:%s", encryptPwd)
encryptFileName := fileDir + ".zip"
//err = EncryptZip(fileDir, encryptFileName, encryptPwd)
err = EncryptList(fileList, encryptFileName, encryptPwd)
if err != nil {
log.Errorf("EncryptZip err:%s", err.Error())
return "", err
}
encryptFile, err := os.Open(encryptFileName)
if err != nil {
log.Errorf("open file err:%s", err.Error())
return "", err
}
resultUrl, err := hCaller.Upload(ctx, appVerInfo.AppID+".zip", encryptFile, false)
if err != nil {
log.Errorf("upload err:%s", err.Error())
return "", err
}
log.Debugf("upload id:%s", resultUrl)
return getFileId(resultUrl), nil
}
func (as *AppService) GetAppClassList(ctx context.Context) ([]entity.CItem, error) {
appClassList, err := as.appRepo.GetAppClassList(ctx)
if err != nil {
return make([]entity.CItem, 0), err
}
return appClassList, err
}
func (as *AppService) GetAppTagList(ctx context.Context) ([]entity.TagItem, error) {
appTagList, err := as.appRepo.GetAppTagList(ctx)
if err != nil {
return make([]entity.TagItem, 0), err
}
return appTagList, err
}
func (as *AppService) SavePrivacySetting(ctx context.Context, req apiproto.PrivacySettingReq) error {
info := entity.PrivacySettingInfo{}
info.AppId = req.AppId
/*userMessageTypeObj:=entity.UserMessageTypeObj{}
userMessageTypeObj.UserMes=req.UserMessageType.UserMes
userMessageTypeObj.LocationMes=req.UserMessageType.LocationMes
userMessageTypeObj.Microphone=req.UserMessageType.Microphone
userMessageTypeObj.Camera=req.UserMessageType.Camera
userMessageTypeObj.EquipmentMes=req.UserMessageType.EquipmentMes
userMessageTypeObj.AddressBook=req.UserMessageType.AddressBook
userMessageTypeObj.PhotoAlbum=req.UserMessageType.PhotoAlbum
userMessageTypeObj.Calendar=req.UserMessageType.Calendar
userMessageTypeObj.OperationLog=req.UserMessageType.OperationLog
userMessageTypeObj.Bluetooth=req.UserMessageType.Bluetooth
userMessageTypeObj.Others=req.UserMessageType.Others*/
info.CommitType = req.CommitType
info.UserMessageType = utility.InterfaceToJsonString(req.UserMessageType)
info.SdkMessage = utility.InterfaceToJsonString(req.SdkMessage)
info.ContactInfoEmail = req.ContactInfo.Email
info.ContactInfoPhone = req.ContactInfo.Phone
info.ContactInfoWeChat = req.ContactInfo.WeChat
info.ContactInfoOther = req.ContactInfo.Other
info.AdditionalDocName = req.AdditionalDocName
info.AdditionalDocNetDiskId = req.AdditionalDocNetDiskId
info.IsFirstSave = false
info.AdditionalDocContent = req.AdditionalDocContent
info.FixedStorageTime = req.FixedStorageTime
info.EffectiveTime = time.Now().UnixNano() / 1e6
info.CreateTime = time.Now().UnixNano() / 1e6
info.UpdateTime = time.Now().UnixNano() / 1e6
total, err := as.prviacySettingRepo.Count(ctx, req.AppId)
if err != nil {
log.Errorf("PrviacySettingRepo Count err:%s", err.Error())
return err
}
if total > 0 {
err := as.prviacySettingRepo.UpdateInfo(ctx, info)
if err != nil {
log.Errorf("PrviacySettingRepo insert err:%s", err.Error())
return err
}
} else {
err := as.prviacySettingRepo.Insert(ctx, info)
if err != nil {
log.Errorf("PrviacySettingRepo insert err:%s", err.Error())
return err
}
}
appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId)
if err != nil {
log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error())
if repository.NotFound(err) {
log.Errorf("DevPublishApp get appVer not found!")
return err
}
}
appInfo.PrivacySettingType = req.CommitType
err = as.appRepo.UpdateApp(ctx, appInfo)
if err != nil {
log.Errorf("UpdateAppIsPrivacySetting repo err:%s", err.Error())
return err
}
return nil
}
type GetPrivacySettingInfoRsp struct {
AppId string `json:"appId"`
CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况
UserMessageType entity.UserMessageTypeObj `json:"userMessageType"` //用户使用类型
SdkMessage []entity.SdkMessageInfoObj `json:"sdkMessage"` //sdk信息
ContactInfo entity.ContactInfoObj `json:"contactInfo"` //联系方式
FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间
IsShortestTime bool `json:"isShortestTime"` //是否是最短时间
AdditionalDocName string `json:"additionalDocName"` //补充文档名称
AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容
AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id
IsFirstSave bool `json:"isFirstSave"`
EffectiveTime int64 `json:"effectiveTime"`
CreateTime int64 `json:"createTime"`
UpdateTime int64 `json:"updateTime"`
}
func (as *AppService) GetPrivacySettingInfo(ctx context.Context, appId string) (GetPrivacySettingInfoRsp, error) {
rsp := GetPrivacySettingInfoRsp{}
item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId)
if err != nil {
log.Errorf("PrviacySettingRepo insert err:%s", err.Error())
if NotFound(err) {
rsp.IsFirstSave = true
return rsp, nil
}
return rsp, err
}
rsp.AppId = item.AppId
rsp.FixedStorageTime = item.FixedStorageTime
rsp.IsShortestTime = item.IsShortestTime
var userMessageTypeObj entity.UserMessageTypeObj
json.Unmarshal([]byte(item.UserMessageType), &userMessageTypeObj)
rsp.UserMessageType = userMessageTypeObj
var sdkMessage []entity.SdkMessageInfoObj
json.Unmarshal([]byte(item.SdkMessage), &sdkMessage)
rsp.SdkMessage = sdkMessage
rsp.CommitType = item.CommitType
rsp.ContactInfo.Phone = item.ContactInfoPhone
rsp.ContactInfo.Email = item.ContactInfoEmail
rsp.ContactInfo.WeChat = item.ContactInfoWeChat
rsp.ContactInfo.Other = item.ContactInfoOther
rsp.AdditionalDocNetDiskId = item.AdditionalDocNetDiskId
rsp.AdditionalDocName = item.AdditionalDocName
rsp.IsFirstSave = item.IsFirstSave
rsp.AdditionalDocContent = item.AdditionalDocContent
rsp.EffectiveTime = item.EffectiveTime
rsp.CreateTime = item.CreateTime
rsp.UpdateTime = item.UpdateTime
return rsp, nil
}
func (as *AppService) DelPrivacySettingInfo(ctx context.Context, appId string) error {
err := as.prviacySettingRepo.DelInfoByAppId(ctx, appId)
if err != nil {
log.Errorf("PrviacySettingRepo DelInfoByAppId err:%s", err.Error())
return err
}
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error())
return err
}
appInfo.PrivacySettingType = 1
err = as.appRepo.UpdateApp(ctx, appInfo)
if err != nil {
log.Errorf("UpdateAppIsPrivacySetting repo err:%s", err.Error())
return err
}
return nil
}
type InternalGetPrivacySettingInfoRsp struct {
AppId string `json:"appId"`
AppName string `json:"appName"`
OrganName string `json:"organName"`
CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况
UserMessageType entity.UserMessageTypeObj `json:"userMessageType"` //用户使用类型
SdkMessage []entity.SdkMessageInfoObj `json:"sdkMessage"` //sdk信息
ContactInfo entity.ContactInfoObj `json:"contactInfo"` //联系方式
FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间
IsShortestTime bool `json:"isShortestTime"` //是否是最短时间
AdditionalDocName string `json:"additionalDocName"` //补充文档名称
AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id
AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容
IsFirstSave bool `json:"isFirstSave"`
EffectiveTime int64 `json:"effectiveTime"`
CreateTime int64 `json:"createTime"`
UpdateTime int64 `json:"updateTime"`
}
func (as *AppService) InternalGetPrivacySettingInfo(ctx context.Context, appId string) (InternalGetPrivacySettingInfoRsp, error) {
rsp := InternalGetPrivacySettingInfoRsp{}
/*appVerInfo, err := as.appRepo.GetOnlineAppVer(ctx, appId)
if err != nil {
log.Debugf("getApp GetOnlineAppVer err:%s", err.Error())
if !NotFound(err) {
log.Errorf("getApp err:%s", err.Error())
return rsp, err
}
}*/
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Debugf("getApp err:%s", err.Error())
if !NotFound(err) {
log.Errorf("getApp err:%s", err.Error())
return rsp, err
}
}
groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID)
log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo)
if err != nil {
log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error())
return rsp, err
}
item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId)
if err != nil {
log.Errorf("PrviacySettingRepo insert err:%s", err.Error())
return rsp, err
}
rsp.AppName = appInfo.Name
rsp.OrganName = groupInfo.GroupName
rsp.AppId = item.AppId
rsp.FixedStorageTime = item.FixedStorageTime
rsp.IsShortestTime = item.IsShortestTime
var userMessageTypeObj entity.UserMessageTypeObj
json.Unmarshal([]byte(item.UserMessageType), &userMessageTypeObj)
rsp.UserMessageType = userMessageTypeObj
var sdkMessage []entity.SdkMessageInfoObj
json.Unmarshal([]byte(item.SdkMessage), &sdkMessage)
rsp.SdkMessage = sdkMessage
rsp.CommitType = item.CommitType
rsp.AdditionalDocContent = item.AdditionalDocContent
rsp.ContactInfo.Phone = item.ContactInfoPhone
rsp.ContactInfo.Email = item.ContactInfoEmail
rsp.ContactInfo.WeChat = item.ContactInfoWeChat
rsp.ContactInfo.Other = item.ContactInfoOther
rsp.AdditionalDocNetDiskId = item.AdditionalDocNetDiskId
rsp.AdditionalDocName = item.AdditionalDocName
rsp.IsFirstSave = item.IsFirstSave
rsp.EffectiveTime = item.EffectiveTime
rsp.CreateTime = item.CreateTime
rsp.UpdateTime = item.UpdateTime
return rsp, nil
}
type InternalGetAppSearchDataInfoRsp struct {
AppId string `json:"appId"` //小程序Id
GroupID string `json:"groupId"`
Resource string `json:"resource"` //小程序源码地址
AppName string `json:"appName"` //小程序名称
OrganName string `json:"organName"` //机构名称
AppDesc string `json:"appDesc"` //小程序简介
SdkKeys []string `json:"sdkKeys"` //sdk关联列表
AppTag string `json:"appTag"`
AppClass string `json:"appClass"`
}
func (as *AppService) InternalGetAppSearchDataInfo(ctx context.Context, appId string) (InternalGetAppSearchDataInfoRsp, error) {
rsp := InternalGetAppSearchDataInfoRsp{}
appInfo, err := as.appRepo.GetAppInfo(ctx, appId)
if err != nil {
log.Debugf("getApp GetAppInfo err:%s", err.Error())
if !NotFound(err) {
log.Errorf("getApp err:%s", err.Error())
return rsp, err
}
}
appVerInfo, err := as.appRepo.GetOnlineAppVer(ctx, appId)
if err != nil {
log.Debugf("getApp GetOnlineAppVer err:%s", err.Error())
if !NotFound(err) {
log.Errorf("getApp err:%s", err.Error())
return rsp, err
}
}
appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx)
if err != nil {
log.Errorln("appTagInfo error:%s", err.Error())
return rsp, err
}
//log.Debugln("appTagInfo:", appTagInfo.Data.AppTag)
appTagStr := ""
if len(appVerInfo.AppTag) > 0 {
log.Debugln("AppTag:", appVerInfo.AppTag)
for _, v := range appVerInfo.AppTag {
for _, tag := range appTagInfo.Data.AppTag {
if v == tag.Key {
appTagStr += tag.Name + ","
log.Debugln("appTagStr", appTagStr)
}
}
}
if len(appTagStr) > 0 {
appTagStr = appTagStr[0 : len(appTagStr)-1]
}
}
appClassStr := ""
if len(appVerInfo.AppTag) > 0 {
for _, v := range appTagInfo.Data.AppClass {
if v.Key == appVerInfo.AppClass {
appClassStr = v.Name
}
}
}
bindRepo := impl.InitBindingRepo()
result, err := bindRepo.GetAllAssBinds(ctx, appId)
if err != nil {
log.Errorf("notifySpiderPubApp err:%s", err.Error())
return rsp, err
}
var sdkKeyListMap = make(map[string]bool, 0)
var sdkKeyList = make([]string, 0)
for _, v := range result {
for _, sdkKeyInfo := range v.BundleInfos {
if sdkKeyInfo.IsForbidden == 0 {
if _, ok := sdkKeyListMap[sdkKeyInfo.SDKKey]; !ok {
sdkKeyListMap[sdkKeyInfo.SDKKey] = true
}
}
}
}
for k, _ := range sdkKeyListMap {
sdkKeyList = append(sdkKeyList, k)
}
rsp.AppId = appInfo.AppID
rsp.GroupID = appVerInfo.GroupID
rsp.Resource = appVerInfo.CustomData.SourceFile[0].SourceFileUrl
rsp.AppName = appInfo.Name
rsp.AppDesc = appVerInfo.CoreDescription
rsp.AppTag = appTagStr
rsp.AppClass = appClassStr
rsp.SdkKeys = sdkKeyList
return rsp, nil
}
type AppObject struct {
AppId string `json:"appId"` //小程序Id
AppName string `json:"appName"` //小程序名称
Logo string `json:"logo"`
}
type InternalGetAppInfoBySearchTextRsp struct {
AppInfo []AppObject `json:"appInfo"`
}
func (as *AppService) InternalGetAppInfoBySearchText(ctx context.Context, searchText string) (InternalGetAppInfoBySearchTextRsp, error) {
rsp := InternalGetAppInfoBySearchTextRsp{}
result, err := as.appRepo.GetAppsBySearchText(ctx, searchText)
if err != nil {
log.Debugf("getApp GetAppsBySearchText err:%s", err.Error())
return rsp, err
}
for _, v := range result {
item := AppObject{}
item.AppId = v.AppID
item.Logo = v.Logo
item.AppName = v.Name
rsp.AppInfo = append(rsp.AppInfo, item)
}
return rsp, nil
}
func EncryptZip(src, dst, passwd string) error {
zipfile, err := os.Create(dst)
if err != nil {
return err
}
defer zipfile.Close()
archive := ezip.NewWriter(zipfile)
defer archive.Close()
err = filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if err != nil {
return err
}
header, err := ezip.FileInfoHeader(info)
if err != nil {
return err
}
header.Name = strings.TrimPrefix(path, filepath.Dir(src)+"/")
//if info.IsDir() {
// header.Name += "/"
//} else {
// header.Method = zip.Deflate
//} // 设置密码
header.Method = zip.Deflate
header.SetPassword(passwd)
writer, err := archive.CreateHeader(header)
if err != nil {
return err
}
if !info.IsDir() {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
}
return err
})
archive.Flush()
return err
}
func Zip(pathToZip, destinationPath string) error {
destinationFile, err := os.Create(destinationPath)
if err != nil {
return err
}
myZip := zip.NewWriter(destinationFile)
err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if err != nil {
return err
}
relPath := strings.TrimPrefix(filePath, filepath.Dir(pathToZip))
zipFile, err := myZip.Create(relPath)
if err != nil {
return err
}
fsFile, err := os.Open(filePath)
if err != nil {
return err
}
_, err = io.Copy(zipFile, fsFile)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
err = myZip.Close()
if err != nil {
return err
}
return nil
}
func ZipList(fileList []string, destinationPath string) error {
fmt.Println(fileList)
destinationFile, err := os.Create(destinationPath)
if err != nil {
return err
}
myZip := zip.NewWriter(destinationFile)
for _, fileName := range fileList {
f, err := os.Open(fileName)
if err != nil {
return err
}
fInfo, err := f.Stat()
if err != nil {
return err
}
if fInfo.IsDir() {
return fmt.Errorf("file:[%s] is dir", fileName)
}
_, name := filepath.Split(fileName)
zipFile, err := myZip.Create(name)
if err != nil {
return err
}
fsFile, err := os.Open(fileName)
if err != nil {
return err
}
_, err = io.Copy(zipFile, fsFile)
if err != nil {
return err
}
}
err = myZip.Close()
if err != nil {
return err
}
return nil
}
func EncryptList(fileList []string, dst, passwd string) error {
fmt.Println(fileList)
zipfile, err := os.Create(dst)
if err != nil {
return err
}
defer zipfile.Close()
archive := ezip.NewWriter(zipfile)
defer archive.Close()
for _, fileName := range fileList {
fmt.Println("fileName:", fileName)
f, err := os.Open(fileName)
if err != nil {
return err
}
fInfo, err := f.Stat()
if err != nil {
return err
}
if fInfo.IsDir() {
return fmt.Errorf("file:[%s] is dir", fileName)
}
header, err := ezip.FileInfoHeader(fInfo)
if err != nil {
return err
}
_, name := filepath.Split(fileName)
header.Name = name
fmt.Println("header.Name:", header.Name)
header.Method = zip.Deflate
header.SetPassword(passwd)
writer, err := archive.CreateHeader(header)
if err != nil {
return err
}
file, err := os.Open(fileName)
if err != nil {
return err
}
_, err = io.Copy(writer, file)
file.Close()
}
archive.Flush()
return err
}
func getFileId(fileUrl string) string {
tempList := strings.Split(fileUrl, "/")
return tempList[len(tempList)-1]
}