finclip-app-manager/domain/service/app.go

3419 lines
128 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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("小程序 %sApp 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("小程序 %sAPP ID: %s已经通过审核可进行后续操作。<br>申请时间:%s审核时间%s",
// appVerInfo.Name, appVerInfo.AppID, st, at)
notifyContent.Msg = fmt.Sprintf("小程序 %sAPP ID: %s您提交的小程序已经通过审核请在小程序详情中进行版本上架操作。<br>申请时间:%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("小程序 %sAPP ID: %s未通过审核可进行后续操作。<br>申请时间:%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]
}