2333 lines
83 KiB
Go
2333 lines
83 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"finclip-app-manager/domain/entity"
|
||
"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"
|
||
"finclip-app-manager/infrastructure/utility"
|
||
"finclip-app-manager/infrastructure/utils"
|
||
"fmt"
|
||
"net/http"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
"unicode"
|
||
|
||
"gitlab.finogeeks.club/finclip-backend/apm"
|
||
|
||
"github.com/Chain-Zhang/pinyin"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/jinzhu/copier"
|
||
"gopkg.in/mgo.v2/bson"
|
||
)
|
||
|
||
const (
|
||
MAX_EXPIRE_DATA = 9999999999999
|
||
)
|
||
|
||
var gAutoBindMap = new(sync.Map)
|
||
|
||
type BindingService struct {
|
||
appRepo repository.AppRepository
|
||
bindRepo repository.IBindingRepo
|
||
bundleRepo repository.IBundleRepo
|
||
}
|
||
|
||
func NewBindingService() *BindingService {
|
||
return &BindingService{
|
||
appRepo: impl.InitAppRepo(),
|
||
bindRepo: impl.InitBindingRepo(),
|
||
bundleRepo: impl.InitBundleRepo(),
|
||
}
|
||
}
|
||
|
||
func (s BindingService) CheckReviewBySdkKey(ctx context.Context, sdkKey string) string {
|
||
//return s.bindRepo.CheckReviewBySdkKey(ctx, sdkKey)
|
||
reviewItem, err := s.bindRepo.GetReviewBindBySdkKey(ctx, sdkKey)
|
||
if err != nil || reviewItem == nil || reviewItem.IsReview == 0 {
|
||
return utility.FS_NOT_REVIEW_BINDING_ERR
|
||
}
|
||
if reviewItem.Status == entity.StBindInvalid {
|
||
return utility.FS_COOPERATION_TERMINATED
|
||
}
|
||
if reviewItem.IsForbidden == 1 {
|
||
return utility.FS_BIND_IS_FORBIDDEN
|
||
}
|
||
return utility.OK
|
||
}
|
||
|
||
func (s BindingService) SyncOrganBinding(ctx context.Context, req apiproto.SyncOrganBindingReq) (int, string, interface{}) {
|
||
errRsp := make(map[string]interface{})
|
||
if req.Operation == "modify-group" {
|
||
err := s.bindRepo.UpdateBindingGroupName(ctx, req.GroupID, req.GroupName)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("SyncOrganBinding UpdateBindingGroupName groupId:%s groupName:%s err:%s", req.GroupID, req.GroupName, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
log.Infof("SyncOrganBinding UpdateBindingGroupName groupId:%s groupName:%s succ", req.GroupID, req.GroupName)
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
bindList, _, err := s.bindRepo.GetBindingsBySearch(ctx, 10000, 1, "", "", "", "all", entity.BINGING_PLATFORM_OPER)
|
||
if err != nil {
|
||
log.Errorf("SyncOrganBinding get bindings list err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
log.Infof("groupId:%s groupName:%s sync bind len:%d", req.GroupID, req.GroupName, len(bindList))
|
||
for _, bind := range bindList {
|
||
copyBind := &entity.Binding{}
|
||
copier.Copy(©Bind, &bind)
|
||
copyBind.BindingID = bson.NewObjectId().Hex()
|
||
copyBind.FromBindingID = bind.BindingID
|
||
copyBind.GroupID = req.GroupID
|
||
copyBind.GroupName = req.GroupName
|
||
accountInfo := &httpcall.AccountInfoData{Account: copyBind.CreatedInfo.CreatedAccount}
|
||
if copyBind.AutoBind == entity.BINGING_AUTO_BIND {
|
||
s.operAutoAppBind(ctx, copyBind, accountInfo)
|
||
}
|
||
err = s.bindRepo.Insert(ctx, copyBind)
|
||
if err != nil {
|
||
log.Errorf("SyncOrganBinding insert groupId:%s groupName:%s copybind err:%s", req.GroupID, req.GroupName, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
} else {
|
||
log.Infof("SyncOrganBinding insert groupId:%s groupName:%s copybind origin binding:%s succ", req.GroupID, req.GroupName, bind.BindingID)
|
||
}
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) GetBindingUsed(ctx context.Context) (int, string, interface{}) {
|
||
rsp := make(map[string]interface{})
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("GetBindingUsed bind err:%s", err.Error())
|
||
return http.StatusBadRequest, utility.FS_BAD_JSON, rsp
|
||
}
|
||
bindTotal, err := s.bindRepo.GetCountByStatus(ctx, "Valid", entity.BINGING_PLATFORM_ALL)
|
||
if err != nil {
|
||
log.Errorf("BindingLicenseCheck count err:", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, err
|
||
}
|
||
log.Infof("license CooAppCount:%d bindTotal:%d", licenseInfo.CooAppCount, bindTotal)
|
||
return http.StatusOK, utility.OK, entity.BindingUsed{
|
||
LimitNum: licenseInfo.CooAppCount,
|
||
HasUseNum: bindTotal,
|
||
RemainNum: licenseInfo.CooAppCount - bindTotal,
|
||
}
|
||
}
|
||
|
||
func (s BindingService) Create(ctx context.Context, c *gin.Context, bind *entity.Binding, isAdmin bool) (int, string, interface{}) {
|
||
//license 校验
|
||
rsp := make(map[string]interface{})
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding bind err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, rsp
|
||
}
|
||
developerID := c.Request.Header.Get("X-Consumer-Custom-ID")
|
||
if !isAdmin && (config.Cfg.PublishEnv == entity.ENV_PRIVATE) {
|
||
bindLimit, err := hCaller.GetBindLimitInfo(ctx, developerID)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding bind err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, rsp
|
||
}
|
||
if bindLimit.CreateBinding != 1 {
|
||
return http.StatusBadRequest, utility.FS_MANAGE_APP_NO_AUTH, rsp
|
||
}
|
||
}
|
||
//if config.Cfg.PublishEnv == common.ENV_PRIVATE {
|
||
httpCode, errCode, err := s.BindingLicenseCheck(ctx, licenseInfo, bind, isAdmin)
|
||
if err != nil {
|
||
return httpCode, errCode, rsp
|
||
}
|
||
//}
|
||
groupInfo := &httpcall.GroupIDData{}
|
||
if !isAdmin {
|
||
groupInfo, err = hCaller.GetGroupInfoByUserId(ctx, developerID)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding GetGroupInfoByUserId err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, rsp
|
||
}
|
||
}
|
||
accountInfo := &httpcall.AccountInfoData{}
|
||
if isAdmin {
|
||
operAccount, err := hCaller.GetAdminAccountInfo(ctx, developerID)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding GetAccountInfo err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR, rsp
|
||
}
|
||
accountInfo.Account = operAccount.Account
|
||
accountInfo.Name = operAccount.Name
|
||
} else {
|
||
organAccount, err := hCaller.GetAccountInfo(ctx, developerID)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding GetAccountInfo err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR, rsp
|
||
}
|
||
accountInfo.Account = organAccount.Account
|
||
accountInfo.Name = organAccount.Name
|
||
}
|
||
timestamp := time.Now().UnixNano() / 1000000
|
||
bind.BindingID = bson.NewObjectId().Hex()
|
||
bind.CreatedInfo = entity.CreatedInfo{
|
||
CreatedBy: developerID,
|
||
CreatedAt: timestamp,
|
||
CreatedAccount: accountInfo.Account,
|
||
}
|
||
if isAdmin {
|
||
bind.PlatForm = entity.BINGING_PLATFORM_OPER
|
||
}
|
||
//这里将group name也加进来,供查找用
|
||
//todo 修改group name的时候需要进行同步
|
||
bind.GroupName = groupInfo.GroupName
|
||
bind.GroupID = groupInfo.GroupID
|
||
bind.CooperateStatus = entity.Status{
|
||
Value: entity.StBindValid,
|
||
LastUpdated: timestamp,
|
||
ModifiedBy: accountInfo.Account,
|
||
}
|
||
|
||
repo := impl.InitBindingRepo()
|
||
_, err = repo.GetByGroupIdAndName(ctx, groupInfo.GroupID, bind.Name, isAdmin)
|
||
if err != nil && !repo.NotFound(err) {
|
||
log.Errorf("CreateBinding get binding info err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, rsp
|
||
}
|
||
|
||
if !repo.NotFound(err) {
|
||
log.Errorln("CreateBinding get binding info not found!")
|
||
return http.StatusBadRequest, utility.FS_BINDING_NAME_REPEAT, rsp
|
||
}
|
||
if isAdmin {
|
||
httpCode, statusCode := s.operBundle(ctx, bind, accountInfo)
|
||
if httpCode != http.StatusOK {
|
||
return httpCode, statusCode, nil
|
||
}
|
||
}
|
||
//调用支付系统进行权限校验
|
||
if config.GetConfig().OpenPurchAuth && config.GetConfig().PublishEnv == entity.ENV_UAT {
|
||
applyReq := httpcall.PayAddLimitReq{}
|
||
applyReq.Type = httpcall.PAY_ADD_TYPE_BINDING
|
||
applyReq.AccountId = developerID
|
||
applyReq.BusinessId = bind.BindingID
|
||
applyReq.BusinessName = bind.Name
|
||
|
||
payAddRsp, httpCode, err := hCaller.PayAddLimit(ctx, &applyReq)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, rsp
|
||
}
|
||
if httpCode != http.StatusOK {
|
||
return httpCode, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, rsp
|
||
}
|
||
if payAddRsp.Data.EndTime == 0 {
|
||
payAddRsp.Data.EndTime = MAX_EXPIRE_DATA
|
||
}
|
||
bind.Expire = payAddRsp.Data.EndTime
|
||
} else {
|
||
if !isAdmin {
|
||
n := httpcall.AddLimitInfoReq{
|
||
Type: "binding",
|
||
OrganId: bind.GroupID,
|
||
AddNum: 1,
|
||
}
|
||
_, _, err = hCaller.AddLimitInfo(ctx, &n)
|
||
if err != nil {
|
||
log.Errorf("Failed to notify: %v\n", err)
|
||
return http.StatusBadRequest, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, nil
|
||
}
|
||
}
|
||
bind.Expire = getExpire(bind.Expire, licenseInfo.ExpireTime)
|
||
}
|
||
|
||
//生成子域名
|
||
if config.GetConfig().PublishEnv == entity.ENV_FDEP {
|
||
resultDomain, err := getResultSubDomain(ctx, bind.GroupName, bind.Name)
|
||
if err != nil {
|
||
log.Errorf("get result domain error: %v,groupName:%s,bindName:%s", err, bind.GroupName, bind.Name)
|
||
return http.StatusBadRequest, utility.FS_ALIYUN_ADD_ERR, nil
|
||
}
|
||
bind.ApiServer = resultDomain
|
||
}
|
||
|
||
if config.GetConfig().PublishEnv == entity.ENV_UAT {
|
||
bind.ApiServer = config.GetConfig().ApiServer //"https://api.finclip.com"
|
||
}
|
||
if config.GetConfig().PublishEnv == entity.ENV_PRIVATE {
|
||
bind.ApiServer = ""
|
||
}
|
||
|
||
//再插入
|
||
err = repo.Insert(ctx, bind)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding insert binding info err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, rsp
|
||
}
|
||
if isAdmin {
|
||
err = s.copyOperBinding(ctx, bind, accountInfo)
|
||
if err != nil {
|
||
log.Errorf("CreateBinding insert copy binding info err:%s", err.Error())
|
||
}
|
||
}
|
||
//生成操作日志
|
||
logExp := make(map[string]interface{})
|
||
go hCaller.AddOperateLog(c, groupInfo.GroupID, kafka.GenContent(kafka.BIND_ADD_LOG, bind.Name), logExp, accountInfo.Account)
|
||
|
||
//移除kafka,这段代码不需要
|
||
/*if config.GetConfig().PublishEnv == entity.ENV_FDEP { //fdep才会上报tam备案
|
||
go kafka.GenTamRecordContentData(ctx, groupInfo.GroupID, bind.Owner, groupInfo.SocialCreditCode)
|
||
}*/
|
||
|
||
return http.StatusCreated, utility.OK, bind
|
||
}
|
||
|
||
func (s BindingService) operBundle(ctx context.Context, bind *entity.Binding, accountInfo *httpcall.AccountInfoData) (int, string) {
|
||
dupBundle := make(map[string]bool)
|
||
bundleIds := []string{}
|
||
for _, bundle := range bind.BundleInfos {
|
||
if _, ok := dupBundle[bundle.BundleID]; ok {
|
||
return http.StatusBadRequest, utility.FS_OPER_REPEAT_BUNDLE_ERR
|
||
}
|
||
dupBundle[bundle.BundleID] = true
|
||
bundleIds = append(bundleIds, bundle.BundleID)
|
||
}
|
||
bundles, err := s.bundleRepo.GetListByBundleIds(ctx, bundleIds)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR
|
||
}
|
||
bundleMap := make(map[string]entity.Bundle)
|
||
for _, bundle := range bundles {
|
||
bundleMap[bundle.BundleID] = bundle
|
||
}
|
||
bundleReq := []apiproto.CreateBundleReq{}
|
||
for _, item := range bind.BundleInfos {
|
||
if bundle, ok := bundleMap[item.BundleID]; ok {
|
||
if bundle.IsForbidden == 0 {
|
||
bundleReq = append(bundleReq, apiproto.CreateBundleReq{
|
||
BundleId: item.BundleID,
|
||
Platform: bundle.Remark,
|
||
SDKKey: item.SDKKey,
|
||
SDKID: item.SDKID,
|
||
IsFirstCreate: item.IsFirstCreate,
|
||
CreatedAt: item.CreatedAt,
|
||
CreatedAccount: item.CreatedAccount,
|
||
CreatedBy: item.CreatedBy,
|
||
IsForbidden: item.IsForbidden,
|
||
})
|
||
}
|
||
}
|
||
}
|
||
if len(bundleReq) <= 0 {
|
||
return http.StatusBadRequest, utility.FS_OPER_CREATE_BUNDLE_ERR
|
||
}
|
||
statusCode, _ := s.BindBundles(ctx, bind.BindingID, bind.GroupID, accountInfo, bundleReq, bind, true)
|
||
if statusCode != utility.OK {
|
||
return http.StatusInternalServerError, statusCode
|
||
}
|
||
return http.StatusOK, utility.OK
|
||
}
|
||
|
||
func (s BindingService) operAutoMergeAppBind(ctx context.Context, bind *entity.Binding, accountName string) {
|
||
_, apps, err := s.appRepo.ListApps(ctx, bind.GroupID, 1, 10000, "", "", "")
|
||
if err != nil {
|
||
log.Errorf("operAutoMergeAppBind organ:%s name:%s list app err:%s", bind.GroupID, bind.GroupName, err.Error())
|
||
return
|
||
}
|
||
exsitApps := make(map[string]bool)
|
||
for _, app := range bind.AppInfos {
|
||
exsitApps[app.AppID] = true
|
||
}
|
||
appendApps := []entity.AppInfo{}
|
||
now := time.Now().UnixNano() / 1e6
|
||
for _, app := range apps {
|
||
if _, ok := exsitApps[app.AppID]; !ok {
|
||
appendApps = append(appendApps, entity.AppInfo{
|
||
AppID: app.AppID,
|
||
AssociatedAt: now,
|
||
AssociatedBy: accountName,
|
||
})
|
||
}
|
||
}
|
||
err = s.bindRepo.AppendApps(ctx, bind.BindingID, appendApps)
|
||
if err != nil {
|
||
log.Errorf("operAutoMergeAppBind AppendApps err:%s", err.Error())
|
||
}
|
||
}
|
||
|
||
func (s BindingService) operAutoAppBind(ctx context.Context, bind *entity.Binding, accountInfo *httpcall.AccountInfoData) {
|
||
_, apps, err := s.appRepo.ListApps(ctx, bind.GroupID, 1, 10000, "", "", "")
|
||
if err != nil {
|
||
log.Errorf("oper auto organ:%s name:%s app bind err:%s", bind.GroupID, bind.GroupName, err.Error())
|
||
return
|
||
}
|
||
now := time.Now().UnixNano() / 1e6
|
||
for _, app := range apps {
|
||
bind.AppInfos = append(bind.AppInfos, entity.AppInfo{
|
||
AppID: app.AppID,
|
||
AssociatedAt: now,
|
||
AssociatedBy: accountInfo.Account,
|
||
})
|
||
}
|
||
}
|
||
|
||
func (s BindingService) mergeOrganBundle(ctx context.Context, bind *entity.Binding) (bool, error) {
|
||
list, _, err := s.bindRepo.GetDevListBinding(ctx, 10000, 1, "", "", "", bind.GroupID, "", entity.BINGING_PLATFORM_ORGAN)
|
||
if err != nil {
|
||
log.Errorf("get organ binding list err:%s", err.Error())
|
||
return false, err
|
||
}
|
||
exsitBundle := make(map[string]bool)
|
||
for _, item := range list {
|
||
for _, bundle := range item.BundleInfos {
|
||
exsitBundle[bundle.BundleID] = true
|
||
}
|
||
}
|
||
hasAppend := false
|
||
newBundle := []entity.BundleInfo{}
|
||
for _, bundle := range bind.BundleInfos {
|
||
if _, ok := exsitBundle[bundle.BundleID]; !ok {
|
||
newBundle = append(newBundle, bundle)
|
||
hasAppend = true
|
||
}
|
||
}
|
||
bind.BundleInfos = newBundle
|
||
return hasAppend, nil
|
||
}
|
||
|
||
func (s BindingService) copyOperBinding(ctx context.Context, bind *entity.Binding, accountInfo *httpcall.AccountInfoData) error {
|
||
log.Infof("copy oper binding begin")
|
||
list, err := hCaller.GetOrganList(ctx)
|
||
if err != nil {
|
||
log.Errorf("copyOperBinding get organ list err:%s", err.Error())
|
||
return err
|
||
}
|
||
log.Infof("get organ list len:%d", len(list))
|
||
repo := impl.InitBindingRepo()
|
||
for _, item := range list {
|
||
copyBind := &entity.Binding{}
|
||
copier.Copy(©Bind, &bind)
|
||
copyBind.BindingID = bson.NewObjectId().Hex()
|
||
copyBind.FromBindingID = bind.BindingID
|
||
copyBind.GroupID = item.OrganId
|
||
copyBind.GroupName = item.Name
|
||
s.mergeOrganBundle(ctx, copyBind)
|
||
// 有bundleID才同步合作应用
|
||
if len(copyBind.BundleInfos) <= 0 {
|
||
continue
|
||
}
|
||
if copyBind.AutoBind == entity.BINGING_AUTO_BIND {
|
||
s.operAutoAppBind(ctx, copyBind, accountInfo)
|
||
}
|
||
err = repo.Insert(ctx, copyBind)
|
||
if err != nil {
|
||
log.Errorf("copyOperBinding insert groupId:%s groupName:%s copybind err:%s", item.OrganId, item.Name, err.Error())
|
||
return err
|
||
}
|
||
log.Infof("copy oper binding to organ:%s succ", item.OrganId)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (s BindingService) AutoBindingAppByCreate(app *entity.App, accountId string) {
|
||
start := time.Now().UnixNano() / 1e6
|
||
log.Debugf("AutoBindingAppByCreate app:%s accountId:%s binding start", app.AppID, accountId)
|
||
ctx := context.Background()
|
||
accountInfo, err := httpcall.NewClient().GetAccountInfo(ctx, accountId)
|
||
if err != nil {
|
||
log.Errorf("AutoBindingAppByCreate get account info err:%s", err.Error())
|
||
return
|
||
}
|
||
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, accountId)
|
||
if err != nil {
|
||
log.Errorf("AutoBindingAppByCreate GetGroupInfoByUserId err:%s", err.Error())
|
||
return
|
||
}
|
||
bindingIds, err := s.bindRepo.ListAutoBindAppBinding(ctx, groupInfo.GroupID)
|
||
if err != nil {
|
||
log.Errorf("AutoBindingAppByCreate ListAutoBindAppBinding err:%s", err.Error())
|
||
return
|
||
}
|
||
list, err := s.bindRepo.GetByBindIdList(ctx, bindingIds)
|
||
if err != nil {
|
||
log.Errorf("AutoBindingAppByCreate GetByBindIdList err:%s", err.Error())
|
||
return
|
||
}
|
||
now := time.Now().UnixNano() / 1e6
|
||
for idx := range list {
|
||
appInfo := entity.AppInfo{
|
||
AppID: app.AppID,
|
||
AssociatedAt: now,
|
||
AssociatedBy: accountInfo.Account,
|
||
}
|
||
list[idx].AppInfos = append(list[idx].AppInfos, appInfo)
|
||
err = s.UpdateByBindId(ctx, list[idx].BindingID, &list[idx])
|
||
if err != nil {
|
||
log.Errorf("AutoBindingAppByCreate UpdateByBindId bindingID:%s err:%s", list[idx].BindingID, err.Error())
|
||
}
|
||
}
|
||
end := time.Now().UnixNano() / 1e6
|
||
log.Debugf("AutoBindingAppByCreate app:%s accountId:%s binding finish handle len:%d spend:%d ms", app.AppID, accountId, len(list), end-start)
|
||
}
|
||
|
||
func (s BindingService) BindingLicenseCheck(ctx context.Context, licenseInfo *httpcall.LicenseData, bindingReq *entity.Binding, isAdmin bool) (int, string, error) {
|
||
log.Infof("BindingLicenseCheck get license info:%+v", licenseInfo)
|
||
//校验应用数量
|
||
repo := impl.InitBindingRepo()
|
||
platform := entity.BINGING_PLATFORM_ORGAN
|
||
if isAdmin {
|
||
platform = entity.BINGING_PLATFORM_OPER
|
||
}
|
||
bindTotal, err := repo.GetCountByStatus(ctx, "Valid", platform)
|
||
if err != nil {
|
||
log.Errorf("BindingLicenseCheck count err:", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, err
|
||
}
|
||
if licenseInfo.CooAppCount <= bindTotal {
|
||
log.Errorf("BindingLicenseCheck bind total over limit,bind num:%d,license num:%d", bindTotal, licenseInfo.CooAppCount)
|
||
return http.StatusForbidden, utility.FC_PRI_OPERA_LIMIT_BIND_OVER_ERROR, errors.New("binding limit over license limit")
|
||
}
|
||
|
||
/*
|
||
//校验bundleId总数
|
||
bundleIdTotal, err := repo.GetBundleIdNum(ctx)
|
||
if err != nil {
|
||
log.Errorf("BindingLicenseCheck count bundle id err:", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, err
|
||
}
|
||
|
||
if licenseInfo.BundleIdCount < bundleIdTotal+len(bindingReq.BundleInfos) {
|
||
log.Errorf("BindingLicenseCheck BundleId total over limit,bundleIdTotal:%d, len(bindingReq.BundleInfos):%d, license num:%d", bundleIdTotal, len(bindingReq.BundleInfos), licenseInfo.BundleIdCount)
|
||
return http.StatusForbidden, utility.FS_BUNDLE_ID_COUNT_OVER, errors.New("bundle id limit over license limit")
|
||
}
|
||
*/
|
||
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
type DetailRsp struct {
|
||
BindingID string `json:"bindingId"` //应用的id
|
||
Name string `json:"name"` //应用名称
|
||
BundleInfos []entity.BundleInfo `json:"bundleInfos"` //bundle ids
|
||
}
|
||
|
||
func (s BindingService) Detail(c *gin.Context, ctx context.Context, bindingId string) {
|
||
repo := impl.InitBindingRepo()
|
||
bindingInfo, err := repo.GetInfo(ctx, bindingId)
|
||
if err != nil {
|
||
log.Errorf("BindingService Detail err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_BAD_JSON, make(map[string]interface{}))
|
||
return
|
||
}
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("get license info err:%v", err)
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, make(map[string]interface{}))
|
||
return
|
||
}
|
||
bindingInfo.Expire = getExpire(bindingInfo.Expire, licenseInfo.ExpireTime)
|
||
rspData := DetailRsp{
|
||
BindingID: bindingInfo.BindingID,
|
||
Name: bindingInfo.Name,
|
||
}
|
||
for _, v := range bindingInfo.BundleInfos {
|
||
rspData.BundleInfos = append(rspData.BundleInfos, v)
|
||
}
|
||
utility.MakeLocRsp(c, http.StatusOK, utility.OK, bindingInfo)
|
||
return
|
||
}
|
||
|
||
func (s BindingService) GetInfo(ctx context.Context, bindingId string) (*entity.Binding, error) {
|
||
return s.bindRepo.GetInfo(ctx, bindingId)
|
||
}
|
||
|
||
func (s BindingService) BindBundles(ctx context.Context, bindingId, groupId string, accountInfo *httpcall.AccountInfoData, bundleReqs []apiproto.CreateBundleReq, binding *entity.Binding, isCreateBinding bool) (string, interface{}) {
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("BindBundles get license err:%s", err.Error())
|
||
return utility.FS_SYSTEM_CALL, nil
|
||
}
|
||
//repo := impl.InitBindingRepo()
|
||
bundleCount, err := s.bindRepo.BundleIdCount(ctx, "")
|
||
if err != nil {
|
||
log.Errorf("BindBundles bundle count err:%s", err.Error())
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
//数量只校验bundleReqs中,isForbidden为0(未禁用)
|
||
lenCount := 0
|
||
for _, v := range bundleReqs {
|
||
if v.IsForbidden == 0 {
|
||
lenCount++
|
||
}
|
||
}
|
||
|
||
if config.Cfg.PublishEnv != entity.ENV_PRIVATE &&
|
||
config.Cfg.PublishEnv != entity.ENV_COMMUNITY {
|
||
if licenseInfo.BundleIdCount < bundleCount+lenCount {
|
||
log.Errorf("BindBundles over limit,license info:%+v,bundle id count:%d", licenseInfo, bundleCount)
|
||
return utility.FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR, nil
|
||
}
|
||
}
|
||
|
||
statusCode, appendBundles := s.handleBundles(ctx, groupId, accountInfo, bundleReqs, licenseInfo, false)
|
||
if statusCode != utility.OK {
|
||
return statusCode, nil
|
||
}
|
||
if binding == nil {
|
||
binding, err = s.bindRepo.GetBindingByGroupIdAndBindingId(ctx, groupId, bindingId)
|
||
if err != nil {
|
||
log.Errorln(fmt.Sprintf("GetOne err: %s", err))
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
log.Infoln("binding %v", binding)
|
||
}
|
||
if isCreateBinding {
|
||
if lenCount > config.GetConfig().AddAvailableBundleNum {
|
||
return utility.FS_BUNDLE_AVAILABLE_NUM_LIMIT, nil
|
||
}
|
||
if len(bundleReqs) > config.GetConfig().AddALLBundleNum {
|
||
return utility.FS_BUNDLE_ALL_NUM_LIMIT, nil
|
||
}
|
||
binding.BundleInfos = appendBundles
|
||
} else {
|
||
num := 0
|
||
for _, v := range binding.BundleInfos {
|
||
if v.IsForbidden == 0 {
|
||
num++
|
||
}
|
||
}
|
||
if num+lenCount > config.GetConfig().AddAvailableBundleNum {
|
||
return utility.FS_BUNDLE_AVAILABLE_NUM_LIMIT, nil
|
||
}
|
||
|
||
if len(bundleReqs)+len(binding.BundleInfos) > config.GetConfig().AddALLBundleNum {
|
||
return utility.FS_BUNDLE_ALL_NUM_LIMIT, nil
|
||
}
|
||
err = s.bindRepo.AppendBundles(ctx, bindingId, groupId, appendBundles)
|
||
//err = s.bindRepo.UpdateBundleInfosByGroupIdAndBindId(ctx, groupId, bindingId, binding.BundleInfos)
|
||
if err != nil {
|
||
if err.Error() == utility.FS_BIND_IS_FORBIDDEN {
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return utility.FS_BIND_IS_FORBIDDEN, nil
|
||
}
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
binding.BundleInfos = append(binding.BundleInfos, appendBundles...)
|
||
}
|
||
|
||
appIds := []string{}
|
||
for _, v := range binding.AppInfos {
|
||
appIds = append(appIds, v.AppID)
|
||
}
|
||
|
||
go s.AdminNotifySdkKey(ctx, appIds, binding, httpcall.BIND_SDK)
|
||
|
||
return utility.OK, binding
|
||
}
|
||
|
||
func (s BindingService) AdminUpdateBundles(ctx context.Context, binding *entity.Binding, groupId string, bundleReqs []apiproto.CreateBundleReq) (int, string, interface{}) {
|
||
errRsp := make(map[string]interface{})
|
||
originBundleReview := make(map[string]int)
|
||
for _, bundle := range binding.BundleInfos {
|
||
originBundleReview[bundle.BundleID] = bundle.IsReview
|
||
}
|
||
checkRepeat := make(map[string]bool)
|
||
removeRepeat := []apiproto.CreateBundleReq{}
|
||
for idx, bundle := range bundleReqs {
|
||
if _, ok := checkRepeat[bundle.BundleId]; !ok {
|
||
checkRepeat[bundle.BundleId] = true
|
||
if v, exsit := originBundleReview[bundle.BundleId]; exsit {
|
||
bundleReqs[idx].IsReview = v
|
||
} else {
|
||
bundleReqs[idx].IsReview = 0
|
||
}
|
||
removeRepeat = append(removeRepeat, bundleReqs[idx])
|
||
}
|
||
}
|
||
bundleReqs = removeRepeat
|
||
// 先修改运营端自身
|
||
statusCode, _ := s.UpdateBundles(ctx, binding.BindingID, groupId, bundleReqs)
|
||
if statusCode != utility.OK {
|
||
return http.StatusBadRequest, statusCode, errRsp
|
||
}
|
||
// 再修改从运营端复制的
|
||
bindingIds, _, err := s.bindRepo.ListCopyOperBinding(ctx, binding.BindingID)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles ListCopyOperBinding bindingID:%s err:%s", binding.BindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
bindList, err := s.bindRepo.GetByBindIdList(ctx, bindingIds)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles GetByBindIdList bindingID:%s err:%s", binding.BindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
updateReq := make(map[string]entity.BundleInfo)
|
||
for _, bundleReq := range bundleReqs {
|
||
updateReq[bundleReq.BundleId] = entity.BundleInfo{
|
||
BundleID: bundleReq.BundleId,
|
||
Remark: bundleReq.Platform,
|
||
IsForbidden: bundleReq.IsForbidden,
|
||
CreatedBy: bundleReq.CreatedBy,
|
||
CreatedAccount: bundleReq.CreatedAccount,
|
||
CreatedAt: bundleReq.CreatedAt,
|
||
IsFirstCreate: bundleReq.IsFirstCreate,
|
||
SDKID: bundleReq.SDKID,
|
||
SDKKey: bundleReq.SDKKey,
|
||
}
|
||
}
|
||
for _, item := range bindList {
|
||
updateBundles := []entity.BundleInfo{}
|
||
for _, bundle := range item.BundleInfos {
|
||
if v, ok := updateReq[bundle.BundleID]; ok {
|
||
updateBundles = append(updateBundles, v)
|
||
} else {
|
||
updateBundles = append(updateBundles, bundle)
|
||
}
|
||
}
|
||
err = s.bindRepo.UpdateBundles(ctx, item.BindingID, groupId, updateBundles)
|
||
if err != nil {
|
||
if err.Error() == utility.FS_BIND_IS_FORBIDDEN {
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return http.StatusInternalServerError, utility.FS_BIND_IS_FORBIDDEN, nil
|
||
} else {
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
}
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) MoveBundles(ctx context.Context, bind *entity.Binding, req *apiproto.BindingUpdateRequest, platform int) (int, string, interface{}) {
|
||
errRsp := make(map[string]interface{})
|
||
toBind, err := s.bindRepo.GetInfo(ctx, req.ToBindingID)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("MoveBundles get bindingId:%s binding info err:%s", req.ToBindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
if s.bindRepo.NotFound(err) {
|
||
log.Errorf("MoveBundles get bindingId:%s binding info err:%s", req.ToBindingID, "NOT FOUND ID")
|
||
return http.StatusNotFound, utility.FS_NOT_FOUND, errRsp
|
||
}
|
||
if bind.PlatForm != platform || (platform == entity.BINGING_PLATFORM_ORGAN && bind.PlatForm != toBind.PlatForm) || (platform == entity.BINGING_PLATFORM_OPER && (bind.PlatForm != toBind.PlatForm || bind.GroupID != "" || toBind.GroupID != "")) {
|
||
log.Errorf("MoveBundles source platform:%d to platform:%d handle platform:%d", bind.PlatForm, toBind.PlatForm, platform)
|
||
return http.StatusBadRequest, utility.FC_MOVE_BINDING_NO_AUTH, errRsp
|
||
}
|
||
if len(req.BundlesInfo) <= 0 {
|
||
return http.StatusBadRequest, utility.FC_LACK_OF_BUNDLE_ERR, nil
|
||
}
|
||
num := 0
|
||
for _, v := range toBind.BundleInfos {
|
||
if v.IsForbidden == 0 {
|
||
num++
|
||
}
|
||
}
|
||
if num >= config.GetConfig().AddAvailableBundleNum {
|
||
return http.StatusBadRequest, utility.FS_BUNDLE_AVAILABLE_NUM_LIMIT, nil
|
||
}
|
||
if len(toBind.BundleInfos) >= config.GetConfig().AddALLBundleNum {
|
||
return http.StatusBadRequest, utility.FS_BUNDLE_ALL_NUM_LIMIT, nil
|
||
}
|
||
// 确认来源binding
|
||
sourceBind, err := s.bindRepo.GetBundleByGroupIdAndBundleId(ctx, bind.GroupID, req.BundlesInfo[0].BundleId)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("MoveBundles get bundle err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
if sourceBind.BindingID != bind.BindingID {
|
||
log.Errorf("MoveBundles bind:%s exsit other bind:%s has same bundle", bind.BindingID, sourceBind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_APP_BUNDLEID_REPEAT, nil
|
||
}
|
||
sourceBundle := entity.BundleInfo{}
|
||
for _, bundle := range sourceBind.BundleInfos {
|
||
if bundle.BundleID == req.BundlesInfo[0].BundleId {
|
||
sourceBundle = bundle
|
||
break
|
||
}
|
||
}
|
||
// 将bundle的源bindingId改为目标bindingId
|
||
err = s.bindRepo.UpdateBundleBindingId(ctx, req.BundlesInfo[0].BundleId, bind.BindingID, toBind.BindingID)
|
||
if err != nil {
|
||
log.Errorf("MoveBundles UpdateBundleBindingId err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
|
||
//由于bundleId移动,应用数据发生变化,需更新小程序搜索数据
|
||
//if config.Cfg.PublishEnv == entity.ENV_UAT {
|
||
//根据bundleId获取sdkkey
|
||
reqBundleSdkkey := ""
|
||
for _, v := range sourceBind.BundleInfos {
|
||
if v.BundleID == req.BundlesInfo[0].BundleId {
|
||
reqBundleSdkkey = v.SDKKey
|
||
break
|
||
}
|
||
}
|
||
|
||
notifyInfo := httpcall.UpdateForbiddenSdkKeys{}
|
||
//小程序搜索数据中删除原应用绑定的appid中所移动的sdkkey
|
||
for _, v := range sourceBind.AppInfos {
|
||
removeItem := httpcall.SdkKeyUpdate{}
|
||
removeItem.AppId = v.AppID
|
||
removeItem.SdkKey = reqBundleSdkkey
|
||
notifyInfo.RemoveSdkKeys = append(notifyInfo.RemoveSdkKeys, removeItem)
|
||
}
|
||
//2 to 小程序数据中添加现应用绑定的appid中所移动的sdkkey
|
||
moveToBind, err := s.bindRepo.GetInfo(ctx, req.ToBindingID)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("MoveBundles get bindingId:%s binding info err:%s", req.ToBindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
for _, v := range moveToBind.AppInfos {
|
||
addItem := httpcall.SdkKeyUpdate{}
|
||
addItem.AppId = v.AppID
|
||
addItem.SdkKey = reqBundleSdkkey
|
||
notifyInfo.AddSdkKeys = append(notifyInfo.AddSdkKeys, addItem)
|
||
}
|
||
hCaller.UpdateBundleForbiddenInfo(ctx, ¬ifyInfo)
|
||
//}
|
||
|
||
//企业端更改结束
|
||
if platform == entity.BINGING_PLATFORM_ORGAN {
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
// 如果是运营端移动,还需要对复制的应用进行移动操作
|
||
// 没复制,说明源应用下的bundle在没复制的企业下已经有其他应用包括源应用的所有bundleId,则不用处理
|
||
_, sourceBinds, err := s.bindRepo.ListCopyOperBinding(ctx, bind.BindingID)
|
||
if err != nil {
|
||
log.Errorf("MoveBundles List sourceBinds CopyOperBinding err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
_, toBinds, err := s.bindRepo.ListCopyOperBinding(ctx, toBind.BindingID)
|
||
if err != nil {
|
||
log.Errorf("MoveBundles List toBinds CopyOperBinding err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
organMap := make(map[string]string)
|
||
for _, item := range toBinds {
|
||
organMap[item.GroupID] = item.BindingID
|
||
}
|
||
for _, item := range sourceBinds {
|
||
//如果当前企业存在目标应用,则直接更改bundle的bindingId
|
||
if v, ok := organMap[item.GroupID]; ok {
|
||
err = s.bindRepo.UpdateBundleBindingId(ctx, req.BundlesInfo[0].BundleId, item.BindingID, v)
|
||
// 如果源应用下不存在此bundle,说明当前企业在其他企业端应用下有此bundle信息,则不用处理
|
||
if err != nil && !s.bindRepo.NotFound(err) {
|
||
log.Errorf("MoveBundles UpdateBundleBindingId err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
} else {
|
||
//当前企业没有复制目标应用,即目标应用在复制时,所有bundleId已经在企业端应用下有
|
||
//如果这个新移动的bundleID在企业端应用下有,即企业端创建的应用下有此bundle,则不做处理
|
||
targetBind, err := s.bindRepo.GetBundleByGroupIdAndBundleId(ctx, item.GroupID, req.BundlesInfo[0].BundleId)
|
||
if err != nil {
|
||
// 不存在,则已此bundleId复制应用
|
||
if s.bindRepo.NotFound(err) {
|
||
copyBind := &entity.Binding{}
|
||
copier.Copy(©Bind, &toBind)
|
||
copyBind.BindingID = bson.NewObjectId().Hex()
|
||
copyBind.FromBindingID = toBind.BindingID
|
||
copyBind.GroupID = item.GroupID
|
||
copyBind.GroupName = item.GroupName
|
||
accountInfo := &httpcall.AccountInfoData{Account: copyBind.CreatedInfo.CreatedAccount}
|
||
if copyBind.AutoBind == entity.BINGING_AUTO_BIND {
|
||
s.operAutoAppBind(ctx, copyBind, accountInfo)
|
||
}
|
||
|
||
copyBind.BundleInfos = []entity.BundleInfo{sourceBundle}
|
||
err = s.bindRepo.Insert(ctx, copyBind)
|
||
if err != nil {
|
||
log.Errorf("MoveBundles insert groupId:%s groupName:%s copybind err:%s", item.GroupID, item.GroupName, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
} else {
|
||
log.Infof("MoveBundles insert groupId:%s groupName:%s copybind origin binding:%s succ", item.GroupID, item.GroupName, bind.BindingID)
|
||
}
|
||
} else {
|
||
log.Errorf("MoveBundles GetBundleByGroupIdAndBundleId err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, nil
|
||
}
|
||
} else {
|
||
//存在,则不做处理
|
||
log.Infof("groupId:%s bundleId:%s has exsit in other binding:%s", item.GroupID, req.BundlesInfo[0].BundleId, targetBind.BindingID)
|
||
}
|
||
}
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) UpdateBundles(ctx context.Context, bindingId, groupId string, bundleReqs []apiproto.CreateBundleReq) (string, interface{}) {
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("BindBundles get license err:%s", err.Error())
|
||
return utility.FS_SYSTEM_CALL, nil
|
||
}
|
||
|
||
num := 0
|
||
for _, v := range bundleReqs {
|
||
if v.IsForbidden == 0 {
|
||
num++
|
||
}
|
||
}
|
||
if num > config.GetConfig().AddAvailableBundleNum {
|
||
return utility.FS_BUNDLE_AVAILABLE_NUM_LIMIT, nil
|
||
}
|
||
|
||
if len(bundleReqs) > config.GetConfig().AddALLBundleNum {
|
||
return utility.FS_BUNDLE_ALL_NUM_LIMIT, nil
|
||
}
|
||
|
||
//repo := impl.InitBindingRepo()
|
||
bundleCount, err := s.bindRepo.BundleIdCount(ctx, "")
|
||
if err != nil {
|
||
log.Errorf("BindBundles bundle count err:%s", err.Error())
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
//数量只校验bundleReqs中,isForbidden为0(未禁用)
|
||
lenCount := 0
|
||
updateBundles := make([]entity.BundleInfo, 0)
|
||
for _, v := range bundleReqs {
|
||
item := entity.BundleInfo{}
|
||
if v.IsForbidden == 0 {
|
||
lenCount++
|
||
}
|
||
item.BundleID = v.BundleId
|
||
item.Remark = v.Platform
|
||
item.IsForbidden = v.IsForbidden
|
||
item.CreatedBy = v.CreatedBy
|
||
item.CreatedAccount = v.CreatedAccount
|
||
item.CreatedAt = v.CreatedAt
|
||
item.IsFirstCreate = v.IsFirstCreate
|
||
item.SDKID = v.SDKID
|
||
item.SDKKey = v.SDKKey
|
||
item.IsReview = v.IsReview
|
||
updateBundles = append(updateBundles, item)
|
||
|
||
if config.Cfg.PublishEnv != entity.ENV_PRIVATE && config.Cfg.PublishEnv != entity.ENV_COMMUNITY {
|
||
if v.IsForbidden == 0 {
|
||
if licenseInfo.BundleIdCount < bundleCount+lenCount {
|
||
log.Errorf("BindBundles over limit,license info:%+v,bundle id count:%d", licenseInfo, bundleCount)
|
||
return utility.FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR, nil
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/*statusCode, appendBundles := s.handleBundles(ctx, groupId, accountInfo, bundleReqs, licenseInfo.IsConfiguration, operationType)
|
||
if statusCode != utility.OK {
|
||
return statusCode, nil
|
||
}*/
|
||
|
||
/*binding, err := s.bindRepo.GetBindingByGroupIdAndBindingId(ctx, groupId, bindingId)
|
||
if err != nil {
|
||
log.Errorln(fmt.Sprintf("GetOne err: %s", err))
|
||
return utility.FS_DB_ERR, nil
|
||
}*/
|
||
|
||
/*if len(binding.BundleInfos) > 1 {
|
||
return utility.FS_BIND_BUNDLE_LIMIT, nil
|
||
}*/
|
||
|
||
//binding.BundleInfos = append(binding.BundleInfos, bundles...)
|
||
|
||
err = s.bindRepo.UpdateBundles(ctx, bindingId, groupId, updateBundles)
|
||
//binding.BundleInfos = append(binding.BundleInfos, appendBundles...)
|
||
//binding.BundleInfos = binding.BundleInfos
|
||
//err = s.bindRepo.UpdateBundleInfosByGroupIdAndBindId(ctx, groupId, bindingId, binding.BundleInfos)
|
||
if err != nil {
|
||
if err.Error() == utility.FS_BIND_IS_FORBIDDEN {
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return utility.FS_BIND_IS_FORBIDDEN, nil
|
||
} else {
|
||
log.Errorln(fmt.Sprintf("UpdateOne err: %s", err))
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
}
|
||
|
||
bind, err := s.bindRepo.GetInfo(ctx, bindingId)
|
||
if err != nil && !s.bindRepo.NotFound(err) {
|
||
log.Errorf("UpdateBinding get binding info err:%s", err.Error())
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
|
||
appIds := []string{}
|
||
for _, v := range bind.AppInfos {
|
||
appIds = append(appIds, v.AppID)
|
||
}
|
||
|
||
notifyInfo := httpcall.UpdateForbiddenSdkKeys{}
|
||
|
||
//if config.Cfg.PublishEnv == entity.ENV_UAT {
|
||
for _, appInfo := range bind.AppInfos {
|
||
for _, v := range bind.BundleInfos {
|
||
if v.IsForbidden == 1 {
|
||
removeItem := httpcall.SdkKeyUpdate{}
|
||
removeItem.AppId = appInfo.AppID
|
||
removeItem.SdkKey = v.SDKKey
|
||
notifyInfo.RemoveSdkKeys = append(notifyInfo.RemoveSdkKeys, removeItem)
|
||
} else {
|
||
addItem := httpcall.SdkKeyUpdate{}
|
||
addItem.AppId = appInfo.AppID
|
||
addItem.SdkKey = v.SDKKey
|
||
notifyInfo.AddSdkKeys = append(notifyInfo.AddSdkKeys, addItem)
|
||
}
|
||
}
|
||
}
|
||
hCaller.UpdateBundleForbiddenInfo(ctx, ¬ifyInfo)
|
||
//}
|
||
return utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) NotFound(err error) bool {
|
||
return s.bindRepo.NotFound(err)
|
||
}
|
||
|
||
func (s BindingService) recooperate(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string, isAdmin bool) (int, string, interface{}) {
|
||
traceCtx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
if bind.CooperateStatus.Value != entity.StBindInvalid {
|
||
log.Errorf("bind cooperate status Invalid,bind id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp
|
||
}
|
||
timestamp := time.Now().UnixNano() / 1000000
|
||
bind.CooperateStatus = entity.Status{
|
||
Value: entity.StBindValid,
|
||
LastUpdated: timestamp,
|
||
ModifiedBy: account,
|
||
}
|
||
bind.CooperateValidStatus = entity.SpecificStatus{
|
||
LastUpdated: timestamp,
|
||
ModifiedBy: account,
|
||
}
|
||
|
||
licenseInfo, err := hCaller.GetLicense(traceCtx)
|
||
if err != nil {
|
||
log.Errorf("GetBundleIdLimitHand get err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_LICENSE_SERVER_ERROR, errRsp
|
||
}
|
||
|
||
httpCode, errCode, err := s.BindingLicenseCheck(traceCtx, licenseInfo, nil, isAdmin)
|
||
if err != nil {
|
||
return httpCode, errCode, errRsp
|
||
}
|
||
|
||
//调用支付系统进行权限校验
|
||
if config.GetConfig().OpenPurchAuth && config.GetConfig().PublishEnv == entity.ENV_UAT {
|
||
applyReq := httpcall.PayAddLimitReq{}
|
||
applyReq.Type = httpcall.PAY_ADD_TYPE_BINDING
|
||
applyReq.AccountId = developerID
|
||
applyReq.BusinessId = bind.BindingID
|
||
applyReq.BusinessName = bind.Name
|
||
|
||
payAddRsp, httpCode, err := hCaller.PayAddLimit(traceCtx, &applyReq)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp
|
||
}
|
||
if httpCode != http.StatusOK {
|
||
return httpCode, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp
|
||
}
|
||
if payAddRsp.Data.EndTime == 0 {
|
||
payAddRsp.Data.EndTime = MAX_EXPIRE_DATA
|
||
}
|
||
bind.Expire = payAddRsp.Data.EndTime
|
||
} else {
|
||
if !isAdmin {
|
||
n := httpcall.AddLimitInfoReq{
|
||
Type: "binding",
|
||
OrganId: bind.GroupID,
|
||
AddNum: 1,
|
||
}
|
||
_, _, err := hCaller.AddLimitInfo(traceCtx, &n)
|
||
if err != nil {
|
||
log.Errorf("Failed to AddLimitInfo: %v\n", err)
|
||
return http.StatusBadRequest, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp
|
||
}
|
||
}
|
||
}
|
||
err = s.UpdateByBindId(traceCtx, req.BindingID, bind)
|
||
if err != nil {
|
||
log.Errorf("bind update err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
if isAdmin {
|
||
s.updateRelateRecooperate(traceCtx, bind)
|
||
}
|
||
logExp := make(map[string]interface{})
|
||
go hCaller.AddOperateLog(c, bind.GroupID, kafka.GenContent(kafka.BIND_RECOVE_COOP_LOG, bind.Name), logExp, account)
|
||
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) updateRelateRecooperate(ctx context.Context, bind *entity.Binding) error {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.UpdateRelatedBindingCooperate(ctx, bind.BindingID, bind.CooperateStatus, bind.CooperateValidStatus, true)
|
||
}
|
||
|
||
func (s BindingService) updateRelateDiscooperate(ctx context.Context, bind *entity.Binding) error {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.UpdateRelatedBindingCooperate(ctx, bind.BindingID, bind.CooperateStatus, bind.CooperateInvalidStatus, false)
|
||
}
|
||
|
||
func (s BindingService) discooperate(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string, isAdmin bool) (int, string, interface{}) {
|
||
traceCtx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
if bind.CooperateStatus.Value != entity.StBindValid {
|
||
log.Errorf("discooperate bind CooperateStatus invalid,bind id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp
|
||
}
|
||
timestamp := time.Now().UnixNano() / 1000000
|
||
bind.CooperateStatus = entity.Status{
|
||
Value: entity.StBindInvalid,
|
||
LastUpdated: timestamp,
|
||
ModifiedBy: account,
|
||
}
|
||
bind.CooperateInvalidStatus = entity.SpecificStatus{
|
||
LastUpdated: timestamp,
|
||
ModifiedBy: account,
|
||
}
|
||
//调用支付系统进行权限校验
|
||
if config.GetConfig().OpenPurchAuth && config.GetConfig().PublishEnv == entity.ENV_UAT {
|
||
applyReq := httpcall.PayAddLimitReq{}
|
||
applyReq.Type = httpcall.PAY_ADD_TYPE_BINDING
|
||
applyReq.AccountId = developerID
|
||
applyReq.BusinessId = bind.BindingID
|
||
applyReq.BusinessName = bind.Name
|
||
_, httpCode, err := hCaller.PayUpdateLimit(traceCtx, &applyReq)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp
|
||
}
|
||
if httpCode != http.StatusOK {
|
||
return httpCode, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp
|
||
}
|
||
} else {
|
||
if !isAdmin {
|
||
n := httpcall.AddLimitInfoReq{
|
||
Type: "binding",
|
||
OrganId: bind.GroupID,
|
||
AddNum: -1,
|
||
}
|
||
_, _, err := hCaller.AddLimitInfo(traceCtx, &n)
|
||
if err != nil {
|
||
log.Errorf("Failed to notify: %v\n", err)
|
||
return http.StatusBadRequest, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp
|
||
}
|
||
}
|
||
}
|
||
err := s.UpdateByBindId(traceCtx, req.BindingID, bind)
|
||
if err != nil {
|
||
log.Errorf("discooperate update err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
if isAdmin {
|
||
s.updateRelateDiscooperate(traceCtx, bind)
|
||
}
|
||
logExp := make(map[string]interface{})
|
||
go hCaller.AddOperateLog(c, bind.GroupID, kafka.GenContent(kafka.BIND_STOP_COOP_LOG, bind.Name), logExp, account)
|
||
//更新小程序详情缓存
|
||
//rs := service.NewRuntimeService()
|
||
//rs.Discooperate(traceCtx, req.BindingID)
|
||
////更新小程序版本详情缓存
|
||
//appVerSvr := service.NewAppVerService()
|
||
//appVerSvr.BindCancelCoop(traceCtx, req.BindingID)
|
||
//model.NewAsyncMessageRepo().GenAppStatusChangeInfo(traceCtx, model.AppStatusChangeInfo{Event: model.BindingCancelCoopreate, Info: map[string]interface{}{"bindingId": bind.BindingID}})
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) AdminReviewBundleList(ctx context.Context, c *gin.Context, req *apiproto.ListReviewBundleReq) (int, string, interface{}) {
|
||
rsp := make(map[string]interface{})
|
||
total, list, err := s.bindRepo.ListReviewBundle(ctx, req.PageSize, req.PageNo, req.SearchText, req.Type)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, rsp
|
||
}
|
||
rsp["total"] = total
|
||
rsp["list"] = list
|
||
return http.StatusOK, utility.OK, rsp
|
||
}
|
||
|
||
func (s BindingService) UpdateReviewBundle(ctx context.Context, c *gin.Context, req *apiproto.UpdateReviewBundleReq) (int, string, interface{}) {
|
||
rsp := make(map[string]interface{})
|
||
switch req.Operation {
|
||
case entity.OpBindingReviewAdd:
|
||
err := s.bindRepo.UpdateBundleIsView(ctx, req.Reviews, 1)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, rsp
|
||
}
|
||
case entity.OpBindingReviewRemove:
|
||
err := s.bindRepo.UpdateBundleIsView(ctx, req.Reviews, 0)
|
||
if err != nil {
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, rsp
|
||
}
|
||
default:
|
||
return http.StatusBadRequest, utility.FS_OPER_HANDLE_ERR, rsp
|
||
}
|
||
|
||
return http.StatusOK, utility.OK, rsp
|
||
}
|
||
|
||
func (s BindingService) AdminBindingUpdate(ctx context.Context, c *gin.Context, req *apiproto.BindingUpdateRequest) (int, string, interface{}) {
|
||
traceCtx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
//bind := entity.Binding{}
|
||
repo := impl.InitBindingRepo()
|
||
bind, err := repo.GetInfo(ctx, req.BindingID)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("BindingUpdate get binding info err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
if repo.NotFound(err) {
|
||
log.Errorf("BindingUpdate get binding info err:%s", "NOT FOUND ID")
|
||
return http.StatusNotFound, utility.FS_NOT_FOUND, errRsp
|
||
}
|
||
developerID := c.Request.Header.Get("X-Consumer-Custom-ID")
|
||
accountInfo, err := hCaller.GetAdminAccountInfo(ctx, developerID)
|
||
if err != nil {
|
||
log.Errorf("UpdateBinding get account info err:%s", err.Error())
|
||
return http.StatusBadRequest, utility.FS_MANAGE_APP_NO_AUTH, errRsp
|
||
}
|
||
switch req.Operation {
|
||
case entity.OpBindingRecooperate:
|
||
return s.recooperate(c, req, bind, developerID, accountInfo.Account, true)
|
||
case entity.OpBindingDiscooperate:
|
||
return s.discooperate(c, req, bind, developerID, accountInfo.Account, true)
|
||
case entity.OpBindingModifyName:
|
||
return s.modifyBindingName(c, req, bind, developerID, accountInfo.Account, true)
|
||
case entity.OpBindingAutoBind, entity.OpBindingHiddenBundle:
|
||
return s.updateBindingInfo(c, req, bind, developerID, accountInfo.Account, true)
|
||
case entity.OpBindBundle:
|
||
accountInfoData := &httpcall.AccountInfoData{
|
||
Account: accountInfo.Account,
|
||
Name: accountInfo.Name,
|
||
}
|
||
return s.AdminBindBundles(traceCtx, "", accountInfoData, req.BundlesInfo, bind, false)
|
||
case entity.OpUpdateBundle:
|
||
return s.AdminUpdateBundles(traceCtx, bind, "", req.BundlesInfo)
|
||
case entity.OpBindingDisassociate:
|
||
if req.Reason == "" {
|
||
log.Errorf("AdminUpdateBinding OpBindingDisassociate reason empty !!!")
|
||
return http.StatusBadRequest, utility.FS_PARAM_ERR, errRsp
|
||
}
|
||
return s.disassociate(traceCtx, bind, req)
|
||
case entity.OpMoveBundle:
|
||
if req.ToBindingID == "" {
|
||
log.Errorf("UpdateBinding to binding id empty !!!")
|
||
return http.StatusBadRequest, utility.FC_LACK_OF_TO_BINDING_ID, errRsp
|
||
}
|
||
if req.BindingID == req.ToBindingID {
|
||
log.Errorf("UpdateBinding binding id:%s equal to binding id:%s", req.BindingID, req.ToBindingID)
|
||
return http.StatusBadRequest, utility.FC_BINDING_ID_EQUAL_TO_INDING_ID, errRsp
|
||
}
|
||
return s.MoveBundles(traceCtx, bind, req, entity.BINGING_PLATFORM_OPER)
|
||
default:
|
||
return http.StatusBadRequest, utility.FS_OPER_HANDLE_ERR, errRsp
|
||
}
|
||
}
|
||
|
||
func (s BindingService) adminDisassociate(c *gin.Context, appIds []string, bind *entity.Binding, account string) (int, string, interface{}) {
|
||
ctx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
if bind.CooperateStatus.Value != entity.StBindValid {
|
||
log.Errorf("disassociate bind CooperateStatus invalid,bind id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp
|
||
}
|
||
removeApps := []string{}
|
||
//产品要求,加一个校验,已经取消关联的,不可重复取消
|
||
for _, id := range appIds {
|
||
found := false
|
||
for _, info := range bind.AppInfos {
|
||
if id == info.AppID {
|
||
found = true
|
||
}
|
||
}
|
||
if !found {
|
||
log.Errorf("disassociate repeat,binding id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_APP_NOT_ASSOCIATED, errRsp
|
||
}
|
||
removeApps = append(removeApps, id)
|
||
}
|
||
err := s.bindRepo.RemoveApps(ctx, bind.BindingID, removeApps)
|
||
if err != nil {
|
||
log.Errorf("disassociate update err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
//这里做个上报
|
||
appSvr := NewAppService()
|
||
logAppMap := make(map[string]string)
|
||
for _, appId := range appIds {
|
||
app, err := appSvr.GetAppInfoByAppId(ctx, appId)
|
||
if err != nil {
|
||
log.Errorf("GetAppInfoByAppId err:%s", err.Error())
|
||
continue
|
||
}
|
||
logAppMap[appId] = app.Name
|
||
}
|
||
logExp := make(map[string]interface{})
|
||
go hCaller.AddOperateLog(c, bind.GroupID, kafka.GenContentAssApp(kafka.BIND_CANCEL_ASS_APP_LOG, bind.Name, logAppMap), logExp, account)
|
||
|
||
////更新运行时获取小程序缓存
|
||
//rs := service.NewRuntimeService()
|
||
//rs.Disassociate(traceCtx, bind.BindingID, appIds)
|
||
////更新小程序版本详情缓存
|
||
//appVerSvr := service.NewAppVerService()
|
||
//appVerSvr.BindDisAssApp(traceCtx, bind.BindingID, appIds)
|
||
//model.NewAsyncMessageRepo().GenAppStatusChangeInfo(traceCtx, model.AppStatusChangeInfo{Event: model.BindingDisassApps, Info: map[string]interface{}{"bindingId": bind.BindingID, "appIds": appIds}})
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) getMergeBundle(ctx context.Context, bundleInfos []entity.BundleInfo, groupID string) ([]entity.BundleInfo, error) {
|
||
list, _, err := s.bindRepo.GetDevListBinding(ctx, 10000, 1, "", "", "", groupID, "", entity.BINGING_PLATFORM_ORGAN)
|
||
if err != nil {
|
||
log.Errorf("get organ binding list err:%s", err.Error())
|
||
return nil, err
|
||
}
|
||
exsitBundle := make(map[string]bool)
|
||
for _, item := range list {
|
||
for _, bundle := range item.BundleInfos {
|
||
exsitBundle[bundle.BundleID] = true
|
||
}
|
||
}
|
||
appendBundle := []entity.BundleInfo{}
|
||
for _, bundle := range bundleInfos {
|
||
if _, ok := exsitBundle[bundle.BundleID]; !ok {
|
||
appendBundle = append(appendBundle, bundle)
|
||
}
|
||
}
|
||
return appendBundle, nil
|
||
}
|
||
|
||
func (s BindingService) AdminBindBundles(ctx context.Context, groupId string, accountInfo *httpcall.AccountInfoData, bundleReqs []apiproto.CreateBundleReq, binding *entity.Binding, isCreateBinding bool) (int, string, interface{}) {
|
||
errRsp := make(map[string]interface{})
|
||
// 先修改运营端自身
|
||
statusCode, _ := s.BindBundles(ctx, binding.BindingID, groupId, accountInfo, bundleReqs, binding, isCreateBinding)
|
||
if statusCode != utility.OK {
|
||
return http.StatusBadRequest, statusCode, errRsp
|
||
}
|
||
// 再修改从运营端复制的
|
||
bindingIds, _, err := s.bindRepo.ListCopyOperBinding(ctx, binding.BindingID)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles ListCopyOperBinding bindingID:%s err:%s", binding.BindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
bindList, err := s.bindRepo.GetByBindIdList(ctx, bindingIds)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles GetByBindIdList bindingID:%s err:%s", binding.BindingID, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
hasCopyedOrgans, notCopyedOrgans := make(map[string]entity.Binding), make(map[string]*httpcall.OrganListItem)
|
||
for _, item := range bindList {
|
||
hasCopyedOrgans[item.GroupID] = item
|
||
}
|
||
list, err := hCaller.GetOrganList(ctx)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles get organ list err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp
|
||
}
|
||
for _, item := range list {
|
||
if _, ok := hasCopyedOrgans[item.OrganId]; !ok {
|
||
notCopyedOrgans[item.OrganId] = item
|
||
}
|
||
}
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("BindBundles get license err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp
|
||
}
|
||
// 以前复制了的企业端
|
||
for _, v := range hasCopyedOrgans {
|
||
statusCode, appendBundles := s.handleBundles(ctx, v.GroupID, accountInfo, bundleReqs, licenseInfo, true)
|
||
if statusCode != utility.OK {
|
||
return http.StatusInternalServerError, statusCode, errRsp
|
||
}
|
||
if len(appendBundles) <= 0 {
|
||
continue
|
||
}
|
||
err = s.bindRepo.AppendBundles(ctx, v.BindingID, v.GroupID, appendBundles)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles AppendBundles err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
}
|
||
// 以前没有复制的企业端
|
||
for _, v := range notCopyedOrgans {
|
||
statusCode, appendBundles := s.handleBundles(ctx, v.OrganId, accountInfo, bundleReqs, licenseInfo, true)
|
||
if statusCode != utility.OK {
|
||
return http.StatusInternalServerError, statusCode, errRsp
|
||
}
|
||
if len(appendBundles) <= 0 {
|
||
continue
|
||
}
|
||
// 这次新加的bundle需要创建新的合作应用
|
||
copyBind := &entity.Binding{}
|
||
copier.Copy(©Bind, &binding)
|
||
copyBind.BindingID = bson.NewObjectId().Hex()
|
||
copyBind.FromBindingID = binding.BindingID
|
||
copyBind.GroupID = v.OrganId
|
||
copyBind.GroupName = v.Name
|
||
copyBind.BundleInfos = appendBundles
|
||
if copyBind.AutoBind == entity.BINGING_AUTO_BIND {
|
||
s.operAutoAppBind(ctx, copyBind, accountInfo)
|
||
}
|
||
err = s.bindRepo.Insert(ctx, copyBind)
|
||
if err != nil {
|
||
log.Errorf("AdminBindBundles copy new insert groupId:%s groupName:%s copybind err:%s", v.OrganId, v.Name, err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) updateBindingInfo(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string, isAdmin bool) (int, string, interface{}) {
|
||
traceCtx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
platform := entity.BINGING_PLATFORM_ORGAN
|
||
if isAdmin {
|
||
platform = entity.BINGING_PLATFORM_OPER
|
||
}
|
||
repo := impl.InitBindingRepo()
|
||
switch req.Operation {
|
||
case entity.OpBindingAutoBind:
|
||
_, ok := gAutoBindMap.Load(req.BindingID)
|
||
if ok {
|
||
return http.StatusBadRequest, utility.FS_OPER_AUTO_BIND_DOING_ERR, errRsp
|
||
}
|
||
gAutoBindMap.Store(req.BindingID, true)
|
||
if req.AutoBind == 1 {
|
||
bindingIds, _, err := repo.ListCopyOperBinding(traceCtx, req.BindingID)
|
||
if err != nil {
|
||
log.Errorf("OpBindingAutoBind ListCopyOperBinding err:%s", err.Error())
|
||
gAutoBindMap.Delete(req.BindingID)
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
bindings, err := repo.GetByBindIdList(traceCtx, bindingIds)
|
||
if err != nil {
|
||
log.Errorf("OpBindingAutoBind GetByBindIdList err:%s", err.Error())
|
||
gAutoBindMap.Delete(req.BindingID)
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
for _, binding := range bindings {
|
||
s.operAutoMergeAppBind(traceCtx, &binding, account)
|
||
}
|
||
}
|
||
err := repo.UpdateBindingInfo(traceCtx, req.BindingID, map[string]interface{}{
|
||
"auto_bind": req.AutoBind,
|
||
}, platform)
|
||
if err != nil {
|
||
log.Errorf("OpBindingAutoBind UpdateBindingInfo err:%s", err.Error())
|
||
gAutoBindMap.Delete(req.BindingID)
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
gAutoBindMap.Delete(req.BindingID)
|
||
return http.StatusOK, utility.OK, nil
|
||
case entity.OpBindingHiddenBundle:
|
||
err := repo.UpdateBindingInfo(traceCtx, req.BindingID, map[string]interface{}{
|
||
"hidden_bundle": req.HiddenBundle,
|
||
}, platform)
|
||
if err != nil {
|
||
log.Errorf("OpBindingHiddenBundle update binding err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s BindingService) modifyBindingName(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string, isAdmin bool) (int, string, interface{}) {
|
||
traceCtx := apm.ApmClient().TraceContextFromGin(c)
|
||
errRsp := make(map[string]interface{})
|
||
if bind.CooperateStatus.Value != entity.StBindValid {
|
||
log.Errorf("modifyBindingName bind CooperateStatus invalid,bind id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp
|
||
}
|
||
groupInfo := &httpcall.GroupIDData{}
|
||
var err error
|
||
if !isAdmin {
|
||
//上报用
|
||
groupInfo, err = hCaller.GetGroupInfoByUserId(traceCtx, developerID)
|
||
if err != nil || groupInfo == nil || groupInfo.GroupID == "" {
|
||
log.Errorf("modifyBindingName get group info err:%+v", err)
|
||
return http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, errRsp
|
||
}
|
||
}
|
||
result, err := s.GetBindingByGroupIdAndName(traceCtx, groupInfo.GroupID, req.AppName, isAdmin)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("modifyBindingName get info err:%+v", err)
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
if !s.NotFound(err) && result.BindingID != req.BindingID {
|
||
log.Errorf("modifyBindingName found binding !!!")
|
||
return http.StatusInternalServerError, utility.FS_BINDING_NAME_REPEAT, errRsp
|
||
}
|
||
|
||
logExp := make(map[string]interface{})
|
||
|
||
go hCaller.AddOperateLog(c, groupInfo.GroupID, kafka.GenContent(kafka.BIND_UP_LOG, bind.Name, req.AppName), logExp, account)
|
||
|
||
/*bind.Name = req.AppName
|
||
bind.Owner = req.Owner
|
||
err = s.UpdateByBindId(traceCtx, req.BindingID, bind)
|
||
if err != nil {
|
||
log.Errorf("modifyBindingName up binding err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}*/
|
||
platform := entity.BINGING_PLATFORM_ORGAN
|
||
if isAdmin {
|
||
platform = entity.BINGING_PLATFORM_OPER
|
||
}
|
||
repo := impl.InitBindingRepo()
|
||
err = repo.UpdateBindingInfo(traceCtx, req.BindingID, map[string]interface{}{
|
||
"name": req.AppName,
|
||
"owner": req.Owner,
|
||
}, platform)
|
||
if err != nil {
|
||
log.Errorf("modifyBindingName up binding err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
return http.StatusOK, utility.OK, nil
|
||
}
|
||
|
||
func (s *BindingService) AdminNotifySdkKey(ctx context.Context, appIds []string, bind *entity.Binding, bindType string) {
|
||
notifys := &httpcall.NotifySpiderUpdate{Type: bindType}
|
||
for _, info := range bind.BundleInfos {
|
||
//if info.IsForbidden == 0 {
|
||
for _, appID := range appIds {
|
||
notifys.SdkKeys = append(notifys.SdkKeys, httpcall.SdkKeyUpdate{AppId: appID, SdkKey: info.SDKKey})
|
||
}
|
||
//}
|
||
}
|
||
_, err := hCaller.Notify(ctx, notifys)
|
||
if err != nil {
|
||
log.Errorf("notfiy spider updates:%+v err:%s", notifys, err.Error())
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *BindingService) disassociate(ctx context.Context, bind *entity.Binding, req *apiproto.BindingUpdateRequest) (int, string, interface{}) {
|
||
errRsp := make(map[string]interface{})
|
||
if bind.CooperateStatus.Value != entity.StBindValid {
|
||
log.Errorf("disassociate bind CooperateStatus invalid,bind id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp
|
||
}
|
||
//产品要求,加一个校验,已经取消关联的,不可重复取消
|
||
removeApps := []string{}
|
||
for _, id := range req.AppIDs {
|
||
found := false
|
||
for _, info := range bind.AppInfos {
|
||
if id == info.AppID {
|
||
found = true
|
||
}
|
||
}
|
||
if !found {
|
||
log.Errorf("disassociate not binding id:%s", bind.BindingID)
|
||
return http.StatusBadRequest, utility.FS_APP_NOT_ASSOCIATED, errRsp
|
||
}
|
||
removeApps = append(removeApps, id)
|
||
}
|
||
err := s.bindRepo.RemoveApps(ctx, bind.BindingID, removeApps)
|
||
if err != nil {
|
||
log.Errorf("disassociate update err:%s", err.Error())
|
||
return http.StatusInternalServerError, utility.FS_DB_ERR, errRsp
|
||
}
|
||
// 临时注释app
|
||
//apps := make([]entity.App, 0)
|
||
//appT := db.NewTable(db.TableApp)
|
||
logAppMap := make(map[string]string)
|
||
//filter := bson.M{"appId": bson.M{"$in": req.AppIds}}
|
||
//_, err := appT.GetAll(ctx, filter, []string{}, &apps)
|
||
//if err != nil {
|
||
// log.Errorf("disassociate get log man err:%s", err.Error())
|
||
// return http.StatusInternalServerError, common.FS_DB_ERR, errRsp
|
||
//}
|
||
//for _, appInfo := range apps {
|
||
// logAppMap[appInfo.AppID] = appInfo.Name
|
||
//}
|
||
|
||
notifyContent := kafka.NotifyContent{}
|
||
notifyContent.Title = "【重要】小程序关联应用被取消"
|
||
notifyContent.Result = "fail"
|
||
notifyContent.Msg = fmt.Sprintf("与 %s 关联的 %s(App ID:%s )被运营端取消关联,"+
|
||
"该应用上的小程序服务将不可用。但其他应用上的该小程序服务仍将正常运行。取消关联说明为:%s", bind.Name, logAppMap[req.AppIDs[0]], req.AppIDs[0], req.Reason)
|
||
notifyContent.Reason = req.Reason
|
||
go kafka.GenNotifyData(ctx, bind.GroupID, 1001, notifyContent)
|
||
|
||
//更新缓存
|
||
//rs := NewRuntimeService()
|
||
//rs.Disassociate(ctx, req.BindingId, req.AppIds)
|
||
////更新小程序版本详情缓存
|
||
//appVerSvr := NewAppVerService()
|
||
//appVerSvr.BindDisAssApp(ctx, req.BindingId, req.AppIds)
|
||
//model.NewAsyncMessageRepo().GenAppStatusChangeInfo(ctx, model.AppStatusChangeInfo{Event: model.BindingCancelCoopreate, Info: map[string]interface{}{"bindingId": bind.BindingID, "appIds": req.AppIds}})
|
||
return http.StatusOK, utility.OK, errRsp
|
||
}
|
||
|
||
func (s BindingService) GetBindingsByIds(ctx context.Context, ids []string) ([]entity.Binding, error) {
|
||
repo := impl.InitBindingRepo()
|
||
result, err := repo.GetByBindIdList(ctx, ids)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
func (s BindingService) GetBindingByGroupId(ctx context.Context, groupId string, pageSize int, pageNo int) ([]entity.Binding, int, error) {
|
||
return s.bindRepo.GetBindListByGroupId(ctx, groupId, pageSize, pageNo)
|
||
}
|
||
|
||
func (s BindingService) GetAssBindsByAppId(ctx context.Context, appId string) ([]entity.Binding, error) {
|
||
return s.bindRepo.GetAllAssBinds(ctx, appId)
|
||
}
|
||
|
||
type ListBindingListRsp struct {
|
||
Total int `json:"total"`
|
||
List []DevListBindingListItem `json:"list"`
|
||
}
|
||
|
||
type DevListBindingListItem struct {
|
||
BindingID string `json:"bindingId"`
|
||
Name string `json:"name"`
|
||
GroupName string `json:"groupName"` //企业名称(为了查询)
|
||
AppInfos []entity.AppInfo `json:"appInfos"`
|
||
BundleInfos []entity.BundleInfo `json:"bundleInfos"`
|
||
CreatedInfo entity.CreatedInfo `json:"createdInfo"` //创建信息
|
||
GroupID string `json:"groupId"`
|
||
CooperateStatus entity.Status `json:"cooperateStatus"` //合作状态
|
||
CooperateValidStatus entity.SpecificStatus `json:"cooperateValidStatus"` //合作状态详情
|
||
CooperateInvalidStatus entity.SpecificStatus `json:"cooperateInvalidStatus"` //解除合作状态详情
|
||
Owner string `json:"owner"` //所属企业
|
||
Expire int64 `json:"expire"`
|
||
ApiServer string `json:"apiServer"`
|
||
ApmServer string `json:"apmServer"`
|
||
PlatForm int `json:"platform" bson:"platform"` //来源平台
|
||
AutoBind int `json:"autoBind" bson:"autoBind"` //自动关联小程序
|
||
HiddenBundle int `json:"hiddenBundle" bson:"hiddenBundle"` //隐藏bundle信息
|
||
FromBindingID string `json:"fromBindingId" bson:"fromBindingId"` //来源ID
|
||
}
|
||
|
||
func (s BindingService) ListBinding(c *gin.Context, ctx context.Context, req apiproto.ListBindingsReq) {
|
||
var rspData ListBindingListRsp
|
||
repo := impl.InitBindingRepo()
|
||
bindList, total, err := repo.GetBindingsBySearch(ctx, req.PageSize, req.PageNo, req.Sort, req.SearchText, req.SearchFields, req.CooperateStatus, req.Platform)
|
||
if err != nil {
|
||
log.Errorf("BindingService DevListBindingList db err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData)
|
||
return
|
||
}
|
||
|
||
rspData.Total = total
|
||
rspData.List = []DevListBindingListItem{}
|
||
for _, v := range bindList {
|
||
item := DevListBindingListItem{
|
||
BindingID: v.BindingID,
|
||
Name: v.Name,
|
||
GroupName: v.GroupName,
|
||
Owner: v.Owner,
|
||
AppInfos: v.AppInfos,
|
||
CreatedInfo: v.CreatedInfo,
|
||
GroupID: v.GroupID,
|
||
BundleInfos: v.BundleInfos,
|
||
CooperateStatus: v.CooperateStatus,
|
||
CooperateValidStatus: v.CooperateValidStatus,
|
||
CooperateInvalidStatus: v.CooperateInvalidStatus,
|
||
Expire: v.Expire,
|
||
ApiServer: v.ApiServer,
|
||
ApmServer: config.Cfg.ApmServer,
|
||
PlatForm: v.PlatForm,
|
||
AutoBind: v.AutoBind,
|
||
HiddenBundle: v.HiddenBundle,
|
||
FromBindingID: v.FromBindingID,
|
||
}
|
||
if item.ApiServer == "" {
|
||
item.ApiServer = config.Cfg.ApiServer
|
||
}
|
||
|
||
rspData.List = append(rspData.List, item)
|
||
}
|
||
|
||
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData)
|
||
return
|
||
}
|
||
|
||
func (s BindingService) GetBindingsByAppId(c *gin.Context, ctx context.Context, req apiproto.GetBindingsByAppIdReq) {
|
||
var rspData ListBindingListRsp
|
||
repo := impl.InitBindingRepo()
|
||
bindList, total, err := repo.GetBindingsByAppId(ctx, req.PageSize, req.PageNo, req.AppId)
|
||
if err != nil {
|
||
log.Errorf("BindingService DevListBindingList db err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData)
|
||
return
|
||
}
|
||
|
||
rspData.Total = total
|
||
|
||
for _, v := range bindList {
|
||
item := DevListBindingListItem{
|
||
BindingID: v.BindingID,
|
||
Name: v.Name,
|
||
GroupName: v.GroupName,
|
||
Owner: v.Owner,
|
||
AppInfos: v.AppInfos,
|
||
CreatedInfo: v.CreatedInfo,
|
||
GroupID: v.GroupID,
|
||
BundleInfos: v.BundleInfos,
|
||
CooperateStatus: v.CooperateStatus,
|
||
CooperateValidStatus: v.CooperateValidStatus,
|
||
CooperateInvalidStatus: v.CooperateInvalidStatus,
|
||
Expire: v.Expire,
|
||
ApiServer: v.ApiServer,
|
||
ApmServer: config.Cfg.ApmServer,
|
||
}
|
||
if item.ApiServer == "" {
|
||
item.ApiServer = config.Cfg.ApiServer
|
||
}
|
||
|
||
rspData.List = append(rspData.List, item)
|
||
}
|
||
|
||
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData)
|
||
return
|
||
}
|
||
|
||
type DevListBindingListRsp struct {
|
||
Total int `json:"total"`
|
||
List []DevListBindingListItem `json:"list"`
|
||
}
|
||
|
||
func (s BindingService) DevListBinding(c *gin.Context, ctx context.Context, req *apiproto.DevListBindingReq) {
|
||
errRspData := make(map[string]interface{})
|
||
groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, req.UserId)
|
||
if err != nil {
|
||
log.Errorf("BindingService DevListBinding get group id by user id err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRspData)
|
||
return
|
||
}
|
||
|
||
bindList, total, err := s.bindRepo.GetDevListBinding(ctx, req.PageSize, req.PageNo, req.SortType, req.SearchTxt, req.PullType, groupInfo.GroupID, req.BindStatus, req.Platform)
|
||
if err != nil {
|
||
log.Errorf("DevListBinding GetDevListBinding err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRspData)
|
||
}
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil && config.Cfg.PublishEnv != entity.ENV_UAT {
|
||
log.Errorf("AppService DevListApps get license info err:%s", err.Error())
|
||
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRspData)
|
||
return
|
||
}
|
||
succRspData := DevListBindingListRsp{Total: total, List: make([]DevListBindingListItem, 0)}
|
||
for _, v := range bindList {
|
||
item := DevListBindingListItem{
|
||
BindingID: v.BindingID,
|
||
Name: v.Name,
|
||
GroupName: v.GroupName,
|
||
Owner: v.Owner,
|
||
AppInfos: v.AppInfos,
|
||
BundleInfos: v.BundleInfos,
|
||
CooperateStatus: v.CooperateStatus,
|
||
CooperateValidStatus: v.CooperateValidStatus,
|
||
CooperateInvalidStatus: v.CooperateInvalidStatus,
|
||
Expire: v.Expire,
|
||
ApiServer: v.ApiServer,
|
||
ApmServer: config.Cfg.ApmServer,
|
||
CreatedInfo: v.CreatedInfo,
|
||
PlatForm: v.PlatForm,
|
||
AutoBind: v.AutoBind,
|
||
HiddenBundle: v.HiddenBundle,
|
||
FromBindingID: v.FromBindingID,
|
||
GroupID: v.GroupID,
|
||
}
|
||
if item.ApiServer == "" {
|
||
item.ApiServer = config.Cfg.ApiServer
|
||
}
|
||
item.Expire = getExpire(item.Expire, licenseInfo.ExpireTime)
|
||
//if item.Expire == MAX_EXPIRE_DATA {
|
||
// common.GLog.Infof("item expire is max expire data:%+v", v)
|
||
// item.Expire = 0
|
||
//}
|
||
////非uat环境取license过期时间
|
||
//if config.Cfg.PublishEnv != common.ENV_UAT {
|
||
// item.Expire = licenseInfo.ExpireTime
|
||
//}
|
||
if req.Platform == entity.BINGING_PLATFORM_OPER && item.HiddenBundle == 1 {
|
||
item.BundleInfos = []entity.BundleInfo{}
|
||
}
|
||
succRspData.List = append(succRspData.List, item)
|
||
}
|
||
utility.MakeLocRsp(c, http.StatusOK, utility.OK, succRspData)
|
||
return
|
||
}
|
||
|
||
func (s BindingService) GetBindingByGroupIdAndName(ctx context.Context, groupId string, name string, isAdmin bool) (*entity.Binding, error) {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.GetByGroupIdAndName(ctx, groupId, name, isAdmin)
|
||
}
|
||
|
||
func (s BindingService) UpdateByBindId(ctx context.Context, bindingId string, bind *entity.Binding) error {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.UpdateByBindId(ctx, bindingId, bind)
|
||
}
|
||
|
||
func (s BindingService) RemoveApps(ctx context.Context, bindingId string, apps []string) error {
|
||
return s.bindRepo.RemoveApps(ctx, bindingId, apps)
|
||
}
|
||
|
||
//更新应用过期时间
|
||
func (s *BindingService) UpExpire(ctx context.Context, bindingId string, expire int64) *utility.SvrRsp {
|
||
rsp := utility.DefaultSvrRsp()
|
||
repo := impl.InitBindingRepo()
|
||
err := repo.UpdateExpire(ctx, bindingId, 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)
|
||
}
|
||
|
||
func (s BindingService) AssApps(ctx context.Context, c *gin.Context, bindingId string, appIds []string, account string) *utility.SvrRsp {
|
||
var (
|
||
rsp = utility.DefaultSvrRsp()
|
||
now = utils.GetNowMs()
|
||
logAppMap = make(map[string]string)
|
||
)
|
||
bind, err := s.bindRepo.GetInfo(ctx, bindingId)
|
||
if err != nil {
|
||
log.Errorf("AssApps get binding info err:%s,binding id:%s", err.Error(), bindingId)
|
||
return rsp.SetLoc(http.StatusBadRequest, utility.FS_DB_ERR)
|
||
}
|
||
appendsApps := []entity.AppInfo{}
|
||
//log.Infof("before ass apps binding binding_id:%s len bundle:%d len apps:%d", bind.BindingID, len(bind.BundleInfos), len(bind.AppInfos))
|
||
for _, appID := range appIds {
|
||
appDevInfo, err := s.appRepo.GetAppInfo(ctx, appID)
|
||
if err != nil {
|
||
log.Errorf("AssApps appid:[%s] err:%s", appID, err.Error())
|
||
return rsp.SetLoc(http.StatusBadRequest, utility.FS_DB_ERR)
|
||
}
|
||
//判断该应用是否已经关联了该小程序
|
||
found := false
|
||
for _, info := range bind.AppInfos {
|
||
if appID == info.AppID {
|
||
found = true
|
||
break
|
||
}
|
||
}
|
||
if found {
|
||
log.Errorf("associate app has exist !!")
|
||
return rsp.SetLoc(http.StatusBadRequest, utility.FS_APP_ASSOCIATED)
|
||
}
|
||
appInfo := entity.AppInfo{
|
||
AppID: appID,
|
||
AssociatedAt: now,
|
||
AssociatedBy: account,
|
||
}
|
||
//bind.AppInfos = append(bind.AppInfos, appInfo)
|
||
logAppMap[appID] = appDevInfo.Name
|
||
appendsApps = append(appendsApps, appInfo)
|
||
}
|
||
//log.Infof("after ass apps binding binding_id:%s len bundle:%d len apps:%d", bind.BindingID, len(bind.BundleInfos), len(bind.AppInfos))
|
||
err = s.bindRepo.AppendApps(ctx, bindingId, appendsApps)
|
||
if err != nil {
|
||
log.Errorf("AppendApps err:%s", err.Error())
|
||
return rsp.SetLoc(http.StatusBadRequest, utility.FS_DB_ERR)
|
||
}
|
||
//日志
|
||
logExp := make(map[string]interface{})
|
||
logReq := httpcall.GenOperateDataV2Req{
|
||
OrganId: bind.GroupID,
|
||
Content: kafka.GenContentAssApp(kafka.BIND_ASS_APP_LOG, bind.Name, logAppMap),
|
||
Extra: logExp,
|
||
Oper: "",
|
||
AccountId: c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY),
|
||
IsDev: true,
|
||
}
|
||
hCaller.AddOperateLogV2(c, logReq)
|
||
return rsp
|
||
}
|
||
|
||
func (s BindingService) handleBundles(ctx context.Context, groupId string, accountInfo *httpcall.AccountInfoData, bundles []apiproto.CreateBundleReq, license *httpcall.LicenseData, copyOper bool) (string, []entity.BundleInfo) {
|
||
newBundIds := make([]entity.BundleInfo, 0)
|
||
createAt := time.Now().UnixNano() / 1e6
|
||
for _, v := range bundles {
|
||
if v.BundleId == "" {
|
||
continue
|
||
}
|
||
//bundle id不能重
|
||
repo := impl.InitBindingRepo()
|
||
_, err := repo.GetBundleByGroupIdAndBundleId(ctx, groupId, v.BundleId)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("CreateBinding get bundle repeat err:%s", err.Error())
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
if !s.NotFound(err) {
|
||
if copyOper {
|
||
continue
|
||
}
|
||
log.Errorf("CreateBinding bundle Id has exist,bundle Id:%s", v.BundleId)
|
||
return utility.FS_APP_BUNDLEID_REPEAT, nil
|
||
}
|
||
|
||
//去除首位空格
|
||
v.BundleId = strings.TrimSpace(v.BundleId)
|
||
//var newV model.BundleInfo
|
||
var newV = entity.BundleInfo{
|
||
BundleID: v.BundleId,
|
||
Remark: v.Platform,
|
||
SDKKey: "",
|
||
SDKID: "",
|
||
IsFirstCreate: true,
|
||
CreatedAt: createAt,
|
||
CreatedAccount: accountInfo.Account,
|
||
CreatedBy: accountInfo.Name,
|
||
IsForbidden: v.IsForbidden,
|
||
}
|
||
//创建的时候对白名单做特殊处理
|
||
if utils.InArry(v.BundleId, config.WhiteBundleIdArry) {
|
||
log.Debugf("CreateBinding bundleId in white list!!!")
|
||
key, secret := config.WhiteListGetSDKKeyAndId(v.BundleId)
|
||
newV.SDKID = secret
|
||
newV.SDKKey = key
|
||
} else {
|
||
//先生成sdkkey
|
||
newSdkey := genSdkKeyV2(v.BundleId, "1", license.IsConfiguration, license.IsApiCover, license.DeviceNum)
|
||
newSdkeyId := utils.GenAppSecret(newSdkey)
|
||
|
||
//先获取下是否已经存在这个sdkKey
|
||
exiResult, err := s.bindRepo.GetbundlesByBundleId(ctx, v.BundleId)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("CreateBinding get binding info err:%s", err.Error())
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
log.Infof("exiResult result:%+v", exiResult)
|
||
if !s.NotFound(err) {
|
||
for _, b := range exiResult.BundleInfos {
|
||
if b.BundleID == v.BundleId {
|
||
//newV = b
|
||
newV.SDKKey = b.SDKKey
|
||
newV.SDKID = b.SDKID
|
||
newV.IsFirstCreate = false
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
if config.Cfg.PublishEnv == entity.ENV_PRIVATE {
|
||
bundleInfo, err := s.bundleRepo.GetInfoByBundleId(ctx, v.BundleId)
|
||
if err != nil && !s.NotFound(err) {
|
||
log.Errorf("update get bundle info err:%s", err)
|
||
return utility.FS_DB_ERR, nil
|
||
}
|
||
if s.NotFound(err) {
|
||
log.Errorf("update get bundle info err:%s", err)
|
||
return utility.FS_BUNDLE_ID_NOT_FOUND, nil
|
||
}
|
||
newV.SDKKey = bundleInfo.SDKKey
|
||
newV.SDKID = bundleInfo.SDKID
|
||
} else {
|
||
newV.SDKKey = newSdkey //genSdkKey(v.BundleId, "1")
|
||
newV.SDKID = newSdkeyId //utils.GenAppSecret(newV.SDKKey)
|
||
newV.IsFirstCreate = true
|
||
newV.Remark = v.Platform
|
||
newV.CreatedAt = createAt
|
||
newV.CreatedAccount = accountInfo.Account
|
||
newV.CreatedBy = accountInfo.Name
|
||
}
|
||
}
|
||
}
|
||
|
||
//将SDKKey与对应的SDKId存储redis
|
||
//authCache := cache.NewRuntimeAuthCheckCache()
|
||
//err := authCache.SetSecret(ctx, newV.SDKKey, newV.SDKID)
|
||
//if err != nil {
|
||
// log.Errorf("CreateBinding set secret to cache err:%s", err.Error())
|
||
// return common.FS_DB_ERR, nil
|
||
//}
|
||
newV.BundleID = v.BundleId
|
||
newBundIds = append(newBundIds, newV)
|
||
log.Infoln(newV.SDKKey)
|
||
}
|
||
|
||
return utility.OK, newBundIds
|
||
}
|
||
|
||
func (s BindingService) BundleLimit(ctx context.Context, c *gin.Context) (limitNum, hasUseNum int, statusCode string) {
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("CreateBundles GetLicense err:%s", err.Error())
|
||
return 0, 0, utility.FS_LICENSE_SERVER_ERROR
|
||
}
|
||
|
||
log.Infof("BundleLicenseCheck get license info:%+v", licenseInfo)
|
||
repo := impl.InitBindingRepo()
|
||
//bindTotal, err := repo.GetBundleIdNum(ctx)
|
||
bindTotal, err := repo.GetBundleLimit(ctx)
|
||
if err != nil {
|
||
log.Errorf("BundleLicenseCheck count err:", err.Error())
|
||
return 0, 0, utility.FS_DB_ERR
|
||
}
|
||
|
||
return licenseInfo.BundleIdCount, bindTotal, utility.OK
|
||
}
|
||
|
||
func (s BindingService) GetBundleIdLimitHand(ctx context.Context, groupId string) (int, error) {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.GetBundleIdLimitHand(ctx, groupId)
|
||
}
|
||
|
||
func (s BindingService) GetBindingBySdkKey(ctx context.Context, sdkKey string) (*entity.Binding, error) {
|
||
repo := impl.InitBindingRepo()
|
||
return repo.GetBindingBySdkKey(ctx, sdkKey)
|
||
}
|
||
|
||
func (s BindingService) GetBindInfoByParam(ctx context.Context, sdkKey, organId, appId string) (*entity.Binding, error) {
|
||
return s.bindRepo.GetInfoByParams(ctx, sdkKey, organId, appId)
|
||
}
|
||
|
||
func (s BindingService) ListBindings(ctx context.Context, groupId string, searchText string, pageNo int, pageSize int) ([]entity.Binding, int, error) {
|
||
return s.bindRepo.ListBindings(ctx, groupId, searchText, pageNo, pageSize)
|
||
}
|
||
|
||
func (s BindingService) ListAllBundleInfos(ctx context.Context, searchText string, selectType, pageNo int, pageSize int) (int, []entity.Bundle, error) {
|
||
return s.bundleRepo.ListAllBundleInfos(ctx, searchText, selectType, pageNo, pageSize)
|
||
}
|
||
|
||
func genSdkKey(bundleId string, openApm string) string {
|
||
str := config.Cfg.SDKVersion + "&" + bundleId + "&" + openApm
|
||
fmt.Println("encry str:%s", str)
|
||
switch config.Cfg.EncryType {
|
||
case "", "MD5":
|
||
fmt.Println("encry type md5!!!")
|
||
return utils.Encrypt(str)
|
||
case "SM":
|
||
fmt.Println("encry type sm!!!")
|
||
return utils.EncryptSM4(str)
|
||
}
|
||
fmt.Println("encry type default !!!")
|
||
return utils.Encrypt(str)
|
||
}
|
||
|
||
func genSdkKeyV2(bundleId string, openApm string, isConfiguration, isApiCover bool, deviceNum int) string {
|
||
str := config.Cfg.SDKVersion + "&" + bundleId + "&" + openApm + "&0"
|
||
if isConfiguration {
|
||
if deviceNum > 0 {
|
||
str += "&2"
|
||
} else {
|
||
str += "&1"
|
||
}
|
||
} else {
|
||
str += "&0"
|
||
}
|
||
|
||
if isApiCover {
|
||
str += "&1"
|
||
} else {
|
||
str += "&0"
|
||
}
|
||
|
||
fmt.Printf("encry str:%s\n", str)
|
||
switch config.Cfg.EncryType {
|
||
case "", "MD5":
|
||
fmt.Println("encry type md5!!!")
|
||
return utils.Encrypt(str)
|
||
case "SM":
|
||
fmt.Println("encry type sm!!!")
|
||
return utils.EncryptSM4(str)
|
||
}
|
||
fmt.Println("encry type default !!!")
|
||
return utils.Encrypt(str)
|
||
}
|
||
|
||
//获取生成的域名
|
||
func getResultSubDomain(ctx context.Context, groupName string, bindingName string) (string, error) {
|
||
leftStr, err := getDomainRuleResultStr(groupName)
|
||
if err != nil {
|
||
log.Errorf("get str error: %v\n", err)
|
||
return "", err
|
||
}
|
||
rightStr, err := getDomainRuleResultStr(bindingName)
|
||
if err != nil {
|
||
log.Errorf("get str error: %v\n", err)
|
||
return "", err
|
||
}
|
||
subName := leftStr + "-" + rightStr
|
||
i := 0
|
||
resultSubName, err := getSubDomainRecord(ctx, subName, i)
|
||
if err != nil {
|
||
log.Errorf("search subdomain err: %v\n", err)
|
||
return "", err
|
||
}
|
||
log.Infof("resultSubName=%s\n", resultSubName)
|
||
|
||
return "https://" + resultSubName + "-" + config.GetConfig().AliyunMainDomainSuffix + "." + config.GetConfig().AliyunMainDomain, nil
|
||
}
|
||
|
||
func getExpire(ms int64, licenseExp int64) int64 {
|
||
if ms == MAX_EXPIRE_DATA {
|
||
return 0
|
||
}
|
||
//非uat环境取license过期时间
|
||
if config.GetConfig().PublishEnv != entity.ENV_UAT {
|
||
return licenseExp
|
||
}
|
||
return ms
|
||
}
|
||
|
||
func getDomainRuleResultStr(str string) (string, error) {
|
||
//这里只保留字母和中文
|
||
reg, err := regexp.Compile("[\u4e00-\u9fa5a-zA-Z]") //中文
|
||
if reg == nil {
|
||
return "", err
|
||
}
|
||
regResult := reg.FindAllStringSubmatch(str, -1)
|
||
var s = ""
|
||
for _, v := range regResult {
|
||
for _, v1 := range v {
|
||
s += v1
|
||
}
|
||
}
|
||
if len(s) == 0 {
|
||
return "", errors.New("format err")
|
||
}
|
||
//rs := []rune(str)
|
||
rs := []rune(s)
|
||
var result string
|
||
for k, v := range rs {
|
||
isAble := IsChinese(string(v))
|
||
if isAble {
|
||
str, err := pinyin.New(string(rs[k])).Split(" ").Mode(pinyin.WithoutTone).Convert()
|
||
if err != nil {
|
||
log.Errorf("Hanzi to pingyin err:", err.Error())
|
||
return "", err
|
||
} else {
|
||
rs := []rune(str)
|
||
result += string(rs[0])
|
||
}
|
||
} else {
|
||
result += string(rs[k])
|
||
}
|
||
}
|
||
if len(result) > 6 {
|
||
//todo
|
||
resultStr := []rune(result)
|
||
return string(resultStr[0:6]), nil
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
func getSubDomainRecord(ctx context.Context, subName string, i int) (string, error) {
|
||
|
||
leftDomain := "https://" + config.GetConfig().AliyunMainDomainPrefix
|
||
rightDomain := "-" + config.GetConfig().AliyunMainDomainSuffix + "." + config.GetConfig().AliyunMainDomain
|
||
|
||
var apiServer string
|
||
if i < 1 {
|
||
apiServer = leftDomain + subName + rightDomain
|
||
} else {
|
||
apiServer = leftDomain + subName + strconv.Itoa(i) + rightDomain
|
||
}
|
||
repo := impl.InitBindingRepo()
|
||
result, err := repo.GetByApiServer(ctx, apiServer)
|
||
if err != nil && !repo.NotFound(err) {
|
||
log.Errorf("get apiServer err:%s", err.Error())
|
||
return "", err
|
||
}
|
||
if result.BindingID == "" {
|
||
if i == 0 {
|
||
return subName, nil
|
||
} else {
|
||
return subName + strconv.Itoa(i), nil
|
||
}
|
||
} else {
|
||
i++
|
||
return getSubDomainRecord(ctx, subName, i)
|
||
}
|
||
}
|
||
|
||
func IsChinese(str string) bool {
|
||
for _, v := range str {
|
||
if unicode.Is(unicode.Han, v) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
type CreateBundlesReq struct {
|
||
List []CreateBundleReq `json:"list"`
|
||
DeveloperID string
|
||
}
|
||
|
||
type CreateBundleReq struct {
|
||
BundleId string `json:"bundleId"`
|
||
Platform string `json:"platform"`
|
||
}
|
||
|
||
type UpdateBundleIsForbiddenReq struct {
|
||
BundleId string `json:"bundleId"`
|
||
IsForbidden int `json:"isForbidden"` //0:可用 1:禁用
|
||
}
|
||
|
||
type UpdateBundlePlatformReq struct {
|
||
BundleId string `json:"bundleId"`
|
||
Platform string `json:"platform"` //平台
|
||
}
|
||
|
||
func (s BindingService) CreateBundles(ctx context.Context, c *gin.Context, req CreateBundlesReq) string {
|
||
length := len(req.List)
|
||
if length == 0 {
|
||
return utility.OK
|
||
}
|
||
|
||
limitNum, hasUseNum, statusCode := s.BundleLimit(ctx, c)
|
||
if statusCode != utility.OK {
|
||
return statusCode
|
||
}
|
||
|
||
if limitNum < hasUseNum+length {
|
||
log.Errorf("BundleLicenseCheck bind total over limit,bind num:%d,createNum:%d,license num:%d", hasUseNum, length, limitNum)
|
||
return utility.FC_OPERA_LIMIT_BIND_OVER_ERROR
|
||
}
|
||
|
||
bundleIds := make([]string, 0, length)
|
||
for _, val := range req.List {
|
||
if val.BundleId == "" || val.Platform == "" {
|
||
log.Errorf("CreateBundles req param empty!")
|
||
return utility.FS_BAD_JSON
|
||
}
|
||
bundleIds = append(bundleIds, val.BundleId)
|
||
}
|
||
|
||
existBundleIds, statusCode := s.BundleIsExist(ctx, bundleIds)
|
||
if statusCode != utility.OK {
|
||
return statusCode
|
||
}
|
||
|
||
if len(existBundleIds) != 0 {
|
||
return utility.FS_APP_BUNDLEID_REPEAT
|
||
}
|
||
|
||
accountInfo, err := hCaller.GetAdminAccountInfo(ctx, req.DeveloperID)
|
||
if err != nil {
|
||
log.Errorln(fmt.Sprintf(fmt.Sprintf("GetAccountInfo err:%s", err.Error())))
|
||
return utility.FS_GET_ACCOUNTINFO_ERROR
|
||
}
|
||
|
||
licenseInfo, err := hCaller.GetLicense(ctx)
|
||
if err != nil {
|
||
log.Errorf("CreateBundles GetLicense err:%s", err.Error())
|
||
return utility.FS_LICENSE_SERVER_ERROR
|
||
}
|
||
|
||
bundles := s.reqToBundleInfos(req, accountInfo, time.Now().UnixNano()/1e6, licenseInfo)
|
||
//将SDKKey与对应的SDKId存储redis
|
||
//authCache := cache.NewRuntimeAuthCheckCache()
|
||
//datas := make([]interface{}, 0, len(bundles))
|
||
//for _, val := range bundles {
|
||
// err = authCache.SetSecret(ctx, val.SDKKey, val.SDKID)
|
||
// if err != nil {
|
||
// log.Errorf("CreateBundles set secret to cache err:%s", err.Error())
|
||
// return common.FS_DB_ERR
|
||
// }
|
||
// datas = append(datas, val)
|
||
//}
|
||
|
||
log.Debugln("bundles", bundles)
|
||
repo := impl.InitBundleRepo()
|
||
err = repo.Insert(ctx, bundles)
|
||
if err != nil {
|
||
log.Errorf("CreateBundles insert bundle info err:%s", err.Error())
|
||
return utility.FS_DB_ERR
|
||
} else {
|
||
return utility.OK
|
||
}
|
||
}
|
||
|
||
func (s BindingService) UpdateBundleIsForbidden(ctx context.Context, req UpdateBundleIsForbiddenReq) string {
|
||
|
||
limitNum, hasUseNum, statusCode := s.BundleLimit(ctx, nil)
|
||
if statusCode != utility.OK {
|
||
return statusCode
|
||
}
|
||
|
||
if req.IsForbidden == 0 {
|
||
if limitNum < hasUseNum+1 {
|
||
log.Errorf("BundleLicenseCheck bind total over limit,bind num:%d,createNum:%d,license num:%d", hasUseNum, limitNum)
|
||
return utility.FS_OPER_BUNDLE_NUM_LIMIT
|
||
}
|
||
}
|
||
|
||
repo := impl.InitBundleRepo()
|
||
err := repo.UpdateBundleForbidden(ctx, req.BundleId, req.IsForbidden)
|
||
if err != nil {
|
||
log.Errorf("UpdateBundleIsForbidden bundle info err:%s", err.Error())
|
||
return utility.FS_DB_ERR
|
||
}
|
||
if req.IsForbidden == 1 {
|
||
err := impl.InitBindingRepo().UpdateBundleIdIsForbidden(ctx, req.BundleId)
|
||
if err != nil {
|
||
log.Errorf("UpdateBundleIsForbidden bundle info err:%s", err.Error())
|
||
return utility.FS_DB_ERR
|
||
}
|
||
}
|
||
return utility.OK
|
||
}
|
||
|
||
func (s BindingService) UpdateBundlesPlatform(ctx context.Context, req UpdateBundlePlatformReq) string {
|
||
repo := impl.InitBundleRepo()
|
||
err := repo.UpdateBundlePlatform(ctx, req.BundleId, req.Platform)
|
||
if err != nil {
|
||
log.Errorf("UpdateBundlesPlatform bundle info err:%s", err.Error())
|
||
return utility.FS_DB_ERR
|
||
}
|
||
err = impl.InitBindingRepo().UpdateBundleIdPlatform(ctx, req.BundleId, req.Platform)
|
||
if err != nil {
|
||
log.Errorf("UpdateBundleIsForbidden bundle info err:%s", err.Error())
|
||
return utility.FS_DB_ERR
|
||
}
|
||
return utility.OK
|
||
}
|
||
|
||
func (s *BindingService) reqToBundleInfos(req CreateBundlesReq, account *httpcall.AdminAccountInfo, createAt int64, license *httpcall.LicenseData) []entity.Bundle {
|
||
bundles := make([]entity.Bundle, 0, len(req.List))
|
||
for _, val := range req.List {
|
||
//SDKKey := genSdkKey(val.BundleId, "1")
|
||
SDKKey := genSdkKeyV2(val.BundleId, "1", license.IsConfiguration, license.IsApiCover, license.DeviceNum)
|
||
SDKID := utils.GenAppSecret(SDKKey)
|
||
|
||
bundle := entity.Bundle{
|
||
BundleID: val.BundleId,
|
||
Remark: val.Platform,
|
||
SDKKey: SDKKey,
|
||
SDKID: SDKID,
|
||
IsFirstCreate: true,
|
||
CreatedAt: createAt,
|
||
CreatedAccount: account.Account,
|
||
CreatedBy: account.Name,
|
||
IsForbidden: 0,
|
||
}
|
||
|
||
bundles = append(bundles, bundle)
|
||
}
|
||
|
||
return bundles
|
||
}
|
||
|
||
func (s BindingService) BundleIsExist(ctx context.Context, bundleIds []string) (existBundleIds []string, statusCode string) {
|
||
length := len(bundleIds)
|
||
if length == 0 {
|
||
return nil, utility.OK
|
||
}
|
||
existBundleIds = make([]string, 0)
|
||
bundleInfos, err := s.bundleRepo.GetListByBundleIds(ctx, bundleIds)
|
||
log.Errorf("bundleInfos", utility.InterfaceToJsonString(bundleInfos))
|
||
if err != nil {
|
||
log.Errorf("BundleIsExist GetListByBundleIds err:%s", err.Error())
|
||
return
|
||
} else if len(bundleInfos) == 0 {
|
||
return existBundleIds, utility.OK
|
||
} else {
|
||
for _, val := range bundleInfos {
|
||
existBundleIds = append(existBundleIds, val.BundleID)
|
||
}
|
||
return existBundleIds, utility.OK
|
||
}
|
||
}
|