finclip-app-manager/application/binding.go

1871 lines
59 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 application
import (
"errors"
"finclip-app-manager/domain/entity"
"finclip-app-manager/domain/entity/proto/apiproto"
"finclip-app-manager/domain/service"
"finclip-app-manager/infrastructure/client/httpcall"
"finclip-app-manager/infrastructure/config"
"finclip-app-manager/infrastructure/kafka"
"finclip-app-manager/infrastructure/utility"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"gitlab.finogeeks.club/finclip-backend/apm"
)
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiParam (RequestBody) {string} name
* @apiParam (RequestBody) {string} owner
* @apiParamExample {json} Request-Example:
* {
* "name": "sdfasd",
* "owner": "wqef"
* }
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "bindingId": "61f4f3ce5d3ef200013d9240",
* "name": "sdfasd",
* "bundleInfos": null,
* "createdInfo": {
* "createdBy": "61de2c5fe1ba8c000175c2b2",
* "createdAt": 1643443150345
* },
* "groupId": "61de2c5fe1ba8c000175c2b3",
* "groupName": "王麻子豆腐",
* "cooperateStatus": {
* "value": "Valid",
* "reason": "",
* "lastUpdated": 1643443150345,
* "modifiedBy": "18220595937"
* },
* "cooperateValidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "cooperateInvalidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "appInfos": null,
* "owner": "wqef",
* "expire": 0,
* "apiServer": "https://finchat-mop-b.finogeeks.club"
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func DevCreateBinding(c *gin.Context) {
CreateBinding(c, false)
}
func AdminCreateBinding(c *gin.Context) {
CreateBinding(c, true)
}
func CreateBinding(c *gin.Context, isAdmin bool) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
rsp := make(map[string]interface{})
bind := entity.Binding{}
if err := c.ShouldBindJSON(&bind); err != nil {
log.Errorf("CreateBinding bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp)
return
}
log.Infof("CreateBinding req:%+v", bind)
if len(bind.BundleInfos) > config.GetConfig().AddAvailableBundleNum {
log.Errorf("CreateBinding binding bundle id num err:%s", "over limit 2")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp)
return
}
svr := service.NewBindingService()
httpCode, errCode, rspData := svr.Create(traceCtx, c, &bind, isAdmin)
utility.MakeLocRsp(c, httpCode, errCode, rspData)
return
}
func GetBindingUsedInfo(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
httpCode, errCode, rspData := svr.GetBindingUsed(traceCtx)
utility.MakeLocRsp(c, httpCode, errCode, rspData)
return
}
type GetLicenseTerminalRsp struct {
IsWindows bool `json:"isWindows"`
IsMac bool `json:"isMac"`
IsLinux bool `json:"isLinux"`
IsIOS bool `json:"isIOS"`
IsAndroid bool `json:"isAndroid"`
}
func GetLicenseTerminal(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
rsp := make(map[string]interface{})
licenseInfo, err := hCaller.GetLicense(traceCtx)
if err != nil {
log.Errorf("CreateBinding bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SERVER_ERR, rsp)
}
rspData := GetLicenseTerminalRsp{}
rspData.IsAndroid = licenseInfo.IsAndroid
rspData.IsWindows = licenseInfo.IsWindows
rspData.IsMac = licenseInfo.IsMac
rspData.IsLinux = licenseInfo.IsLinux
rspData.IsIOS = licenseInfo.IsIOS
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func DevListBindings(c *gin.Context) {
listBindings(c, true)
}
type ListBindingsReq struct {
SearchText string `form:"searchText"`
SearchFields string `form:"searchFields"`
PageSize int `form:"pageSize"`
PageNo int `form:"pageNo"`
}
func listBindings(c *gin.Context, filterGroup bool) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := ListBindingsReq{}
if err := c.BindQuery(&req); err != nil {
log.Errorf("ListBindingsReq bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
log.Infof("ListBindingsReq req:%+v", req)
if filterGroup {
developerID := c.Request.Header.Get("x-consumer-custom-id")
groupInfo, err := hCaller.GetGroupInfoByUserId(traceCtx, developerID)
if err != nil {
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_GET_ACCOUNTINFO_ERROR, nil)
return
}
svr := service.NewBindingService()
binds, total, err := svr.ListBindings(traceCtx, groupInfo.GroupID, req.SearchText, req.PageNo, req.PageSize)
if err != nil {
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil)
return
}
c.JSON(http.StatusOK, gin.H{
"total": total,
"list": binds,
})
return
}
svr := service.NewBindingService()
binds, total, err := svr.ListBindings(traceCtx, "", req.SearchText, req.PageNo, req.PageSize)
if err != nil {
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil)
return
}
c.JSON(http.StatusOK, gin.H{
"total": total,
"list": binds,
})
}
type DevListBindingsV2Req struct {
PullType string `form:"pullType"`
BindStatus string `form:"bindStatus"`
PageNo int `form:"pageNo"`
PageSize int `form:"pageSize"`
SearchTxt string `form:"searchTxt"`
SortType string `form:"sortType"`
Platform int `form:"platform,default=2"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiParam (RequestBody) {string} bindStatus
* @apiParam (RequestBody) {string} searchTxt
* @apiParam (RequestBody) {string} pageSize
* @apiParam (RequestBody) {string} pageNo
* @apiParam (RequestBody) {string} sortType
* @apiParam (RequestBody) {string} pullType
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "total": 1429,
* "list": [
* {
* "bindingId": "61f4f3ce5d3ef200013d9240",
* "name": "sdfasd",
* "groupName": "王麻子豆腐",
* "appInfos": null,
* "bundleInfos": [],
* "createdInfo": {
* "createdBy": "61de2c5fe1ba8c000175c2b2",
* "createdAt": 1643443150345
* },
* "groupId": "61de2c5fe1ba8c000175c2b3",
* "cooperateStatus": {
* "value": "Valid",
* "reason": "",
* "lastUpdated": 1643443150345,
* "modifiedBy": "18220595937"
* },
* "cooperateValidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "cooperateInvalidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "owner": "wqef",
* "expire": 9999999999999,
* "apiServer": "https://finchat-mop-b.finogeeks.club",
* "apmServer": "https://finchat-mop-b.finogeeks.club"
* }
* ]
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func DevListBindingsV2(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := DevListBindingsV2Req{}
if err := c.Bind(&req); err != nil {
log.Errorf("DevListBindingsV2 bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, make(map[string]interface{}))
return
}
userId := c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY)
if userId == "" {
log.Errorf("DevListBindingsV2 bind err:%s", "user id empty")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, make(map[string]interface{}))
return
}
if req.PageSize == 0 {
req.PageSize = 10
}
svrReq := apiproto.DevListBindingReq{
PullType: req.PullType,
BindStatus: req.BindStatus,
SortType: req.SortType,
PageNo: req.PageNo,
PageSize: req.PageSize,
SearchTxt: req.SearchTxt,
UserId: userId,
Platform: req.Platform,
}
log.Infof("DevListBindingsV2 req:%+v", svrReq)
svr := service.NewBindingService()
svr.DevListBinding(c, traceCtx, &svrReq)
return
}
func SyncOrganBinding(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := apiproto.SyncOrganBindingReq{}
if err := c.ShouldBindJSON(&req); err != nil {
log.Errorf("SyncOrganBinding ShouldBindJSON err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, make(map[string]interface{}))
return
}
svr := service.NewBindingService()
httpCode, errCode, rsp := svr.SyncOrganBinding(traceCtx, req)
utility.MakeLocRsp(c, httpCode, errCode, rsp)
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "bindingId": "609b93a80f0ca30001292df2",
* "name": "autockwms",
* "bundleInfos": [
* {
* "bundleId": "autofpgwj",
* "remark": "ios_android",
* "SDKKey": "lvqyfRXHkVyNY0GnY6a6SQ==",
* "SDKID": "775f549788c238b5",
* "isFirstCreate": true,
* "createdAt": 1620808617522,
* "createdAccount": "15473501296",
* "createdBy": "autotest"
* }
* ],
* "createdInfo": {
* "createdBy": "",
* "createdAt": 0
* },
* "groupId": "609b92452a68150001e7875d",
* "groupName": "autotxdzr",
* "cooperateStatus": {
* "value": "Valid",
* "reason": "",
* "lastUpdated": 1620808616325,
* "modifiedBy": "15473501296"
* },
* "cooperateValidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "cooperateInvalidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "appInfos": [],
* "owner": "test",
* "expire": 0,
* "apiServer": "https://finchat-mop-b.finogeeks.club"
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func GetBindingDetail(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
bindingId := c.Param("bindingId")
if bindingId == "" {
log.Errorf("GetBindingDetail bind id empty")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, make(map[string]interface{}))
return
}
svr := service.NewBindingService()
svr.Detail(c, traceCtx, bindingId)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
type DevListAllAppidInfoReq struct {
AppIdList string `form:"appIdList"`
}
func DevListAllAppidInfo(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := DevListAllAppidInfoReq{}
if err := c.BindQuery(&req); err != nil {
log.Errorf("DevListAllAppidInfo bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{})
return
}
log.Infof("DevListAllAppidInfo req:%+v", req)
if req.AppIdList == "" {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
return
}
appIdList := strings.Split(req.AppIdList, ",")
if len(appIdList) > 100 {
log.Errorf("DevListAllAppidInfo appid over limit!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{})
return
}
svr := service.NewAppService()
apps, err := svr.GetAppsByAppIds(traceCtx, appIdList)
if err != nil {
log.Errorf("DevListAllAppidInfo GetAppsByAppIds err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
return
}
pubApps := []string{}
for _, v := range apps {
_, err := svr.GetOnlineAppVer(traceCtx, v.AppID)
if err == nil {
pubApps = append(pubApps, v.AppID)
}
}
c.JSON(http.StatusOK, gin.H{"total": len(apps), "list": apps, "pubApps": pubApps})
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func UpdateBinding(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := apiproto.BindingUpdateRequest{}
errRsp := make(map[string]interface{})
if err := c.ShouldBindJSON(&req); err != nil {
log.Errorf("UpdateBinding binding err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
if req.BindingID == "" {
log.Errorf("UpdateBinding binding id empty !!!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_BINDING_ID, errRsp)
return
}
log.Infof("UpdateBinding req:%+v", req)
developerID := c.Request.Header.Get("X-Consumer-Custom-ID")
groupInfo, err := hCaller.GetGroupInfoByUserId(traceCtx, developerID)
if err != nil {
log.Errorf("UpdateBinding get group id err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, errRsp)
return
}
svr := service.NewBindingService()
bind, err := svr.GetInfo(traceCtx, req.BindingID)
if err != nil && !svr.NotFound(err) {
log.Errorf("UpdateBinding get binding info err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return
}
log.Infof("UpdateBinding bind info:%+v,err:%+v", bind, err)
if svr.NotFound(err) {
log.Errorf("UpdateBinding get binding info err:%s", "NOT FOUND ID")
utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, errRsp)
return
}
if groupInfo.GroupID != bind.GroupID {
log.Errorf("UpdateBinding group id mismatch err:%s", bind.GroupID)
utility.MakeLocRsp(c, http.StatusForbidden, utility.FS_FORBIDDEN, errRsp)
return
}
accountInfo, err := httpcall.NewClient().GetAccountInfo(traceCtx, developerID)
if err != nil {
log.Errorf("UpdateBinding get account info err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR, errRsp)
return
}
if bind.PlatForm == entity.BINGING_PLATFORM_OPER && (req.Operation != entity.OpBindingAssociate && req.Operation != entity.OpBindingDisassociate) {
log.Errorf("bind platform:%d Operation:%s not allowed", bind.PlatForm, req.Operation)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_MANAGE_APP_NO_AUTH, errRsp)
return
}
switch req.Operation {
case entity.OpBindingAssociate:
if len(req.AppIDs) <= 0 {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, errRsp)
return
}
// 直接关联
if config.Cfg.PublishEnv == entity.ENV_FDEP {
err = applyAssociate(c, req.AppIDs, bind, groupInfo.GroupID, accountInfo.Account)
} else {
associate(c, req.AppIDs, bind, groupInfo.GroupID, accountInfo.Account)
return
}
case entity.OpBindingDisassociate:
if len(req.AppIDs) <= 0 {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, errRsp)
return
}
err = disassociate(c, req.AppIDs, bind, developerID, accountInfo.Account)
case entity.OpBindingRecooperate:
err = recooperate(c, &req, bind, developerID, accountInfo.Account)
case entity.OpBindingDiscooperate:
err = discooperate(c, &req, bind, developerID, accountInfo.Account)
case entity.OpBindingModifyName:
err = modifyBindingName(c, &req, bind, developerID, accountInfo.Account, false)
case entity.OpBindBundle:
statusCode, rsp := svr.BindBundles(traceCtx, req.BindingID, groupInfo.GroupID, accountInfo, req.BundlesInfo, nil, false)
if statusCode != utility.OK && statusCode != utility.FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR {
utility.MakeLocRsp(c, http.StatusBadRequest, statusCode, errRsp)
} else {
utility.MakeLocRsp(c, http.StatusOK, statusCode, rsp)
}
return
case entity.OpUpdateBundle:
svr := service.NewBindingService()
statusCode, rsp := svr.UpdateBundles(traceCtx, req.BindingID, groupInfo.GroupID, req.BundlesInfo)
if statusCode != utility.OK && statusCode != utility.FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR {
utility.MakeLocRsp(c, http.StatusBadRequest, statusCode, errRsp)
} else {
utility.MakeLocRsp(c, http.StatusOK, statusCode, rsp)
}
return
case entity.OpMoveBundle:
if req.ToBindingID == "" {
log.Errorf("UpdateBinding to binding id empty !!!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FC_LACK_OF_TO_BINDING_ID, errRsp)
return
}
if req.BindingID == req.ToBindingID {
log.Errorf("UpdateBinding binding id:%s equal to binding id:%s", req.BindingID, req.ToBindingID)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FC_BINDING_ID_EQUAL_TO_INDING_ID, errRsp)
return
}
httpCode, errCode, rsp := svr.MoveBundles(traceCtx, bind, &req, entity.BINGING_PLATFORM_ORGAN)
utility.MakeLocRsp(c, httpCode, errCode, rsp)
return
default:
log.Errorf("UpdateBinding operation err,op:%v", req.Operation)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_BINDING_OPERATION, errRsp)
return
}
if err == nil {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, errRsp)
return
}
}
func modifyBindingName(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string, isAdmin bool) error {
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
//上报用
groupInfo, err := hCaller.GetGroupInfoByUserId(traceCtx, developerID)
if err != nil || groupInfo == nil || groupInfo.GroupID == "" {
log.Errorf("modifyBindingName get group info err:%+v", err)
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, errRsp)
return errors.New(entity.ErrFake)
}
svr := service.NewBindingService()
result, err := svr.GetBindingByGroupIdAndName(traceCtx, groupInfo.GroupID, req.AppName, isAdmin)
if err != nil && !svr.NotFound(err) {
log.Errorf("modifyBindingName get info err:%+v", err)
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
}
if !svr.NotFound(err) && result.BindingID != req.BindingID {
log.Errorf("modifyBindingName found binding !!!")
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_BINDING_NAME_REPEAT, errRsp)
return errors.New(entity.ErrFake)
}
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 = svr.UpdateByBindId(traceCtx, req.BindingID, bind)
if err != nil {
log.Errorf("modifyBindingName up binding err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
}
return nil
}
func discooperate(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string) error {
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
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 {
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp)
return errors.New(entity.ErrFake)
}
if httpCode != http.StatusOK {
utility.MakeLocRsp(c, httpCode, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp)
return errors.New(entity.ErrFake)
}
} else {
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp)
return errors.New(entity.ErrFake)
}
}
svr := service.NewBindingService()
err := svr.UpdateByBindId(traceCtx, req.BindingID, bind)
if err != nil {
log.Errorf("discooperate update err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
}
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 nil
}
func recooperate(c *gin.Context, req *apiproto.BindingUpdateRequest, bind *entity.Binding, developerID string, account string) error {
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
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())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_LICENSE_SERVER_ERROR, errRsp)
return errors.New("get license err")
}
svr := service.NewBindingService()
httpCode, errCode, err := svr.BindingLicenseCheck(traceCtx, licenseInfo, nil, false)
if err != nil {
utility.MakeLocRsp(c, httpCode, errCode, errRsp)
return err
}
//调用支付系统进行权限校验
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 {
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, errRsp)
return errors.New(entity.ErrFake)
}
if httpCode != http.StatusOK {
utility.MakeLocRsp(c, httpCode, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp)
return errors.New(entity.ErrFake)
}
if payAddRsp.Data.EndTime == 0 {
payAddRsp.Data.EndTime = MAX_EXPIRE_DATA
}
bind.Expire = payAddRsp.Data.EndTime
} else {
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FC_OPERA_LIMIT_BIND_OVER_ERROR, errRsp)
return errors.New(entity.ErrFake)
}
}
err = svr.UpdateByBindId(traceCtx, req.BindingID, bind)
if err != nil {
log.Errorf("bind update err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
}
logExp := make(map[string]interface{})
go hCaller.AddOperateLog(c, bind.GroupID, kafka.GenContent(kafka.BIND_RECOVE_COOP_LOG, bind.Name), logExp, account)
//rs := service.NewRuntimeService()
//rs.Recooperate(traceCtx, req.BindingID)
//model.NewAsyncMessageRepo().GenAppStatusChangeInfo(traceCtx, model.AppStatusChangeInfo{Event: model.BindingRecooprate, Info: map[string]interface{}{"bindingId": bind.BindingID}})
return nil
}
func disassociate(c *gin.Context, appIds []string, bind *entity.Binding, developerID string, account string) error {
traceCtx := 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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
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)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_APP_NOT_ASSOCIATED, errRsp)
return errors.New(entity.ErrFake)
}
removeApps = append(removeApps, id)
}
//更新
/*newInfos := make([]entity.AppInfo, 0)
for _, info := range bind.AppInfos {
found := false
for _, appID := range appIds {
if appID == info.AppID {
found = true
break
}
}
if !found {
newInfos = append(newInfos, info)
}
}
bind.AppInfos = newInfos*/
svr := service.NewBindingService()
err := svr.RemoveApps(traceCtx, bind.BindingID, removeApps)
if err != nil {
log.Errorf("disassociate update err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
}
//小程序搜索更新绑定的sdkKeys
go svr.AdminNotifySdkKey(traceCtx, removeApps, bind, httpcall.UNBIND_SDK)
//这里做个上报
appSvr := service.NewAppService()
logAppMap := make(map[string]string)
for _, appId := range appIds {
app, err := appSvr.GetAppInfoByAppId(traceCtx, 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 nil
}
func associate(c *gin.Context, appIds []string, bind *entity.Binding, groupId string, account string) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
errRsp := make(map[string]interface{})
if bind.CooperateStatus.Value != entity.StBindValid {
log.Errorf("associate bind CooperateStatus invalid,bind id:%s", bind.BindingID)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return
}
svr := service.NewBindingService()
rsp := svr.AssApps(traceCtx, c, bind.BindingID, appIds, account)
//小程序搜索更新绑定的sdkkeys
go svr.AdminNotifySdkKey(traceCtx, appIds, bind, httpcall.BIND_SDK)
rsp.MakeRsp(c, gin.H{})
return
}
const (
StLinkAuditApplying = "Applying"
StLinkAuditRejected = "Rejected"
StLinkAuditApplied = "Applied"
)
func applyAssociate(c *gin.Context, appIds []string, bind *entity.Binding, groupId string, account string) error {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
errRsp := make(map[string]interface{})
if bind.CooperateStatus.Value != entity.StBindValid {
log.Errorf("associate bind CooperateStatus invalid,bind id:%s", bind.BindingID)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
logAppMap := make(map[string]string)
for _, appID := range appIds {
appDevInfo, err := service.NewAppService().GetAppVerInfo(traceCtx, appID, 0)
if err != nil && !service.NotFound(err) {
log.Errorf("associate GetOne app info err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_INVALID_COOPERATE_STATUS, errRsp)
return errors.New(entity.ErrFake)
}
////一条一条校验
//vaild, appName, err := AllowAppAssociated(traceCtx, groupId, appID)
//if err != nil {
// log.Errorf("applyAssociate AllowAppAssociated err:%s", err.Error())
// MakeRsp(c, http.StatusInternalServerError, FS_DB_ERR, errRsp)
// return errors.New(ErrFake)
//}
//if !vaild {
// log.Errorf("applyAssociate AllowAppAssociated invalid !!")
// MakeRsp(c, http.StatusBadRequest, FS_APP_NOT_PUBLISHED, errRsp)
// return errors.New(ErrFake)
//}
//判断该应用是否已经关联了该小程序
found := false
for _, info := range bind.AppInfos {
if appID == info.AppID {
found = true
break
}
}
if found {
log.Errorf("applyAssociate app has exist !!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_APP_ASSOCIATED, errRsp)
return errors.New(entity.ErrFake)
}
svr := service.NewLinkAuditService()
count, err := svr.Count(traceCtx, appID, groupId, bind.BindingID, StLinkAuditApplying)
// 检查关联状态, 如果有审核中的, 报错
if err != nil && !svr.NotFound(err) {
log.Errorf("applyAssociate AllowAppAssociated err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp)
return errors.New(entity.ErrFake)
} else if count != 0 {
log.Errorf("exist an applying audit !!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LINK_AUDIT_APPLY_EXIST, errRsp)
return errors.New(entity.ErrFake)
}
logAppMap[appID] = appDevInfo.Name
}
//日志
logExp := make(map[string]interface{})
logReq := httpcall.GenOperateDataV2Req{
OrganId: bind.GroupID,
Content: kafka.GenContentAssApp(kafka.BIND_AUDIT_APPLY_LOG, bind.Name, logAppMap),
Extra: logExp,
Oper: "",
AccountId: c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY),
IsDev: true,
}
hCaller.AddOperateLogV2(c, logReq)
//临时注释
//rs := service.NewRuntimeService()
//rs.ApplyAssociate(traceCtx, bind.BindingID, c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY), appIds, logAppMap)
return nil
}
type AdminUpdateBindingReq struct {
Operation string `json:"operation"`
BindingId string `json:"bindingId"`
AppIds []string `json:"appIds"`
Reason string `json:"reason"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func AdminUpdateBinding(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
errRsp := make(map[string]interface{})
req := apiproto.BindingUpdateRequest{}
if err := c.BindJSON(&req); err != nil {
log.Errorf("AdminUpdateBinding bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
if req.Operation != entity.OpBindingAssociate &&
req.Operation != entity.OpBindingDisassociate &&
req.Operation != entity.OpBindingRecooperate &&
req.Operation != entity.OpBindingDiscooperate &&
req.Operation != entity.OpBindingModifyName &&
req.Operation != entity.OpBindBundle &&
req.Operation != entity.OpUpdateBundle &&
req.Operation != entity.OpBindingAutoBind &&
req.Operation != entity.OpBindingHiddenBundle &&
req.Operation != entity.OpMoveBundle {
log.Errorf("AdminUpdateBinding type err, type:%s", req.Operation)
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
svr := service.NewBindingService()
httpCode, errCode, rsp := svr.AdminBindingUpdate(traceCtx, c, &req)
utility.MakeLocRsp(c, httpCode, errCode, rsp)
}
func AdminReviewBundleList(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := apiproto.ListReviewBundleReq{}
if err := c.BindQuery(&req); err != nil {
log.Errorf("AdminReviewBundleList bind query err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
log.Infof("AdminReviewBundleList req:%+v", req)
svr := service.NewBindingService()
httpCode, errCode, rsp := svr.AdminReviewBundleList(traceCtx, c, &req)
utility.MakeLocRsp(c, httpCode, errCode, rsp)
}
func UpdateReviewBundle(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
errRsp := make(map[string]interface{})
req := apiproto.UpdateReviewBundleReq{}
if err := c.BindJSON(&req); err != nil {
log.Errorf("UpdateReviewBundle bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
svr := service.NewBindingService()
httpCode, errCode, rsp := svr.UpdateReviewBundle(traceCtx, c, &req)
utility.MakeLocRsp(c, httpCode, errCode, rsp)
}
func CheckReviewBySdkKey(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
sdkKey := c.Param("sdkkey")
svr := service.NewBindingService()
checkStatus := svr.CheckReviewBySdkKey(traceCtx, sdkKey)
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"isReview": checkStatus})
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func AdminListBindings(c *gin.Context) {
listBindings(c, false)
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiParam (RequestBody) {string} bindStatus
* @apiParam (RequestBody) {string} searchTxt
* @apiParam (RequestBody) {string} pageSize
* @apiParam (RequestBody) {string} pageNo
* @apiParam (RequestBody) {string} sortType
* @apiParam (RequestBody) {string} pullType
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "total": 1429,
* "list": [
* {
* "bindingId": "61f4f3ce5d3ef200013d9240",
* "name": "sdfasd",
* "groupName": "王麻子豆腐",
* "appInfos": null,
* "bundleInfos": [],
* "createdInfo": {
* "createdBy": "61de2c5fe1ba8c000175c2b2",
* "createdAt": 1643443150345
* },
* "groupId": "61de2c5fe1ba8c000175c2b3",
* "cooperateStatus": {
* "value": "Valid",
* "reason": "",
* "lastUpdated": 1643443150345,
* "modifiedBy": "18220595937"
* },
* "cooperateValidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "cooperateInvalidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "owner": "wqef",
* "expire": 9999999999999,
* "apiServer": "https://finchat-mop-b.finogeeks.club",
* "apmServer": "https://finchat-mop-b.finogeeks.club"
* }
* ]
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func NewAdminListBindings(c *gin.Context) {
var (
traceCtx = apm.ApmClient().TraceContextFromGin(c)
req = apiproto.ListBindingsReq{}
errRsp = make(map[string]interface{})
)
if err := c.BindQuery(&req); err != nil {
log.Errorf("list bindings bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
log.Infof("get bindings seq req:%+v", req)
if req.PageSize == 0 {
req.PageSize = 100
}
svr := service.NewBindingService()
svr.ListBinding(c, traceCtx, req)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiParam (RequestBody) {string} appId
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "data": {
* "total": 1429,
* "list": [
* {
* "bindingId": "61f4f3ce5d3ef200013d9240",
* "name": "sdfasd",
* "groupName": "王麻子豆腐",
* "appInfos": null,
* "bundleInfos": [],
* "createdInfo": {
* "createdBy": "61de2c5fe1ba8c000175c2b2",
* "createdAt": 1643443150345
* },
* "groupId": "61de2c5fe1ba8c000175c2b3",
* "cooperateStatus": {
* "value": "Valid",
* "reason": "",
* "lastUpdated": 1643443150345,
* "modifiedBy": "18220595937"
* },
* "cooperateValidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "cooperateInvalidStatus": {
* "reason": "",
* "lastUpdated": 0,
* "modifiedBy": ""
* },
* "owner": "wqef",
* "expire": 9999999999999,
* "apiServer": "https://finchat-mop-b.finogeeks.club",
* "apmServer": "https://finchat-mop-b.finogeeks.club"
* }
* ]
* },
* "errcode": "OK",
* "error": ""
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func GetBindingsByAppId(c *gin.Context) {
var (
traceCtx = apm.ApmClient().TraceContextFromGin(c)
req = apiproto.GetBindingsByAppIdReq{}
errRsp = make(map[string]interface{})
)
if err := c.BindQuery(&req); err != nil {
log.Errorf("list bindings bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp)
return
}
log.Infof("get bindings seq req:%+v", req)
svr := service.NewBindingService()
svr.GetBindingsByAppId(c, traceCtx, req)
return
}
type GetLimitBindingListReq struct {
OrganId string `form:"organId"`
PageNo int `form:"pageNo"`
PageSize int `form:"pageSize"`
}
type GetLimitBindingListRsp struct {
Total int `json:"total"`
List []GetLimitBindingListRspItem `json:"list"`
}
type GetLimitBindingListRspItem struct {
BindingId string `json:"bindingId"`
BindingName string `json:"bindingName"`
BundleIdNum int `json:"bundleIdNum"`
CoopStatus string `json:"coopStatus"` //合作状态
CreateTime int64 `json:"createTime"` //创建时间
ExpireTime int64 `json:"expireTime"` //过期时间
BundleInfos []entity.BundleInfo `json:"bundleInfos"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func GetLimitBindingList(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := GetLimitBindingListReq{}
rsp := GetLimitBindingListRsp{
Total: 0,
List: make([]GetLimitBindingListRspItem, 0),
}
if err := c.BindQuery(&req); err != nil {
log.Errorf("GetLimitBindingList bind req error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp)
return
}
if req.PageSize >= 100 || req.PageSize <= 0 {
req.PageSize = 100
}
//filter := bson.M{"groupId": req.OrganId}
//sortFilter := []string{"-createdInfo.createdAt"}
//binds := make([]model.Binding, 0)
//t := db.NewTable(db.TableBinding)
//total, err := t.GetSome(traceCtx, filter, sortFilter, req.PageSize, req.PageNo, &binds)
svr := service.NewBindingService()
binds, total, err := svr.GetBindingByGroupId(traceCtx, req.OrganId, req.PageSize, req.PageNo)
if err != nil && !svr.NotFound(err) {
log.Errorf("GetLimitBindingList get binding list error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rsp)
return
}
rsp.Total = total
for _, v := range binds {
item := GetLimitBindingListRspItem{}
item.BindingId = v.BindingID
item.BindingName = v.Name
item.CreateTime = v.CreatedInfo.CreatedAt / 1e3
item.CoopStatus = v.CooperateStatus.Value
item.BundleInfos = v.BundleInfos
item.BundleIdNum = len(v.BundleInfos)
if v.Expire == MAX_EXPIRE_DATA {
item.ExpireTime = 0
} else {
item.ExpireTime = v.Expire
}
rsp.List = append(rsp.List, item)
}
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func GetBindingsByIds(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
bindingIds := c.Query("ids")
if bindingIds == "" {
log.Errorf("GetBindingsByIds binding id empty!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{})
return
}
svr := service.NewBindingService()
bindings, err := svr.GetBindingsByIds(traceCtx, strings.Split(bindingIds, ","))
if err != nil {
log.Errorf("GetBindingsByIds err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
return
}
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"list": bindings})
return
}
type GetBundleIdLimitHandRsp struct {
LimitNum int `json:"limitNum"`
HasUseNum int `json:"hasUseNum"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func BundlesLimit(c *gin.Context) {
ctx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
rsp := GetBundleIdLimitHandRsp{}
var statusCode string
rsp.LimitNum, rsp.HasUseNum, statusCode = svr.BundleLimit(ctx, c)
if statusCode != utility.OK {
utility.MakeLocRsp(c, http.StatusInternalServerError, statusCode, gin.H{})
} else {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
}
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func GetBundleIdLimitHand(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
errRsp := make(map[string]interface{})
//目前saas、private环境bundleId限制数量在license里面
rsp := GetBundleIdLimitHandRsp{}
licenseInfo, err := hCaller.GetLicense(traceCtx)
if err != nil {
log.Errorf("GetBundleIdLimitHand get err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_LICENSE_SERVER_ERROR, errRsp)
return
}
log.Infof("GetBundleIdLimitHand get license info:%+v", licenseInfo)
developerID := c.Request.Header.Get("x-consumer-custom-id")
log.Infof("GetBundleIdLimitHand account id:%s", developerID)
groupInfo, err := hCaller.GetGroupInfoByUserId(traceCtx, developerID)
if err != nil {
log.Errorf("GetBundleIdLimitHand get group id err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, errRsp)
return
}
log.Infof("GetBundleIdLimitHand groupId:%s", groupInfo.GroupID)
//校验bundingId的数量
svr := service.NewBindingService()
bundleIdTotal, err := svr.GetBundleIdLimitHand(traceCtx, groupInfo.GroupID)
if err != nil {
log.Errorf("GetBundleIdLimitHand get bundleId count id err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED, errRsp)
return
}
rsp.LimitNum = licenseInfo.CooAppCount * 2
rsp.HasUseNum = bundleIdTotal
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
type GetSecretBySdkKeyHandReq struct {
SdkKey string `form:"sdkKey"`
}
//根绝sdkKey获取secret
func GetSecretBySdkKeyHand(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := GetSecretBySdkKeyHandReq{}
rsp := make(map[string]string)
if err := c.BindQuery(&req); err != nil {
log.Errorf("GetSecretBySdkKeyHand bind error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp)
return
}
if req.SdkKey == "" {
log.Errorf("GetSecretBySdkKeyHand sdk key empty")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, rsp)
return
}
log.Infof("GetSecretBySdkKeyHand req:%+v", req)
var secret string
if utility.InArry(req.SdkKey, config.WhiteSDKArry) {
log.Infof("GetSecretBySdkKeyHand in white list:%s", req.SdkKey)
for _, v := range config.WhiteSDKList {
if req.SdkKey == v.SDKKey {
secret = v.SDKID
}
}
rsp["secret"] = secret
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
svr := service.NewBindingService()
bind, err := svr.GetBindingBySdkKey(traceCtx, req.SdkKey)
if err != nil {
log.Errorf("GetSecretBySdkKeyHand db err:%s", err.Error())
if service.NotFound(err) {
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BIND_NOT_FOUND, gin.H{})
} else {
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
}
return
}
for _, v := range bind.BundleInfos {
if v.SDKKey == req.SdkKey {
secret = v.SDKID
}
}
log.Infof("GetBindingIdBySdkKeyHand sdkKey:%s,result:%+v", req.SdkKey, bind)
rsp["secret"] = secret
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
}
func GetOrganIdBySdkKey(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
rsp := make(map[string]interface{})
sdkKey := c.DefaultQuery("sdkKey", "")
if sdkKey == "" {
log.Errorf("GetOrganIdBySdkKey sdkKey empty")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
log.Infof("GetOrganIdBySdkKey sdk key:%+v", sdkKey)
if utility.InArry(sdkKey, config.WhiteSDKArry) {
rsp["isWhite"] = true
rsp["organId"] = ""
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
svr := service.NewBindingService()
result, err := svr.GetBindingBySdkKey(traceCtx, sdkKey)
if err != nil {
log.Errorf("GetOrganIdBySdkKey get binding info error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVICE_UNAVAILABLE, rsp)
return
}
log.Infof("GetOrganIdBySdkKey sdkKey:%s,result:%+v", sdkKey, result)
rsp["organId"] = ""
rsp["isWhite"] = false
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
type GetBindingInfoByIdHandReq struct {
BindingId string `form:"bindingId"`
}
type GetBindingInfoByIdHandRsp struct {
BindingID string `json:"bindingId"`
Name string `json:"name"`
CoopStatus string `json:"coopStatus"`
GroupId string `json:"groupId"`
}
func GetBindingInfoByIdHand(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := GetBindingInfoByIdHandReq{}
rsp := GetBindingInfoByIdHandRsp{}
if err := c.BindQuery(&req); err != nil {
log.Errorf("GetBindingInfoByIdHand bind error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp)
return
}
if req.BindingId == "" {
log.Errorf("GetBindingInfoByIdHand sdk key empty")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, rsp)
return
}
svr := service.NewBindingService()
result, err := svr.GetInfo(traceCtx, req.BindingId)
if err != nil && !config.GetConfig().IsHcc {
log.Errorf("GetBindingInfoByIdHand get binding info error:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVICE_UNAVAILABLE, rsp)
return
}
if config.GetConfig().IsHcc {
result.Name = config.BindingWhiteList.BindingList[0].Name
}
rsp.CoopStatus = result.CooperateStatus.Value
rsp.BindingID = result.BindingID
rsp.Name = result.Name
rsp.GroupId = result.GroupID
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
}
type BundlesReq struct {
PageSize int `form:"pageSize"`
PageNo int `form:"pageNo"`
SearchText string `form:"searchText"`
SelectType int `form:"selectType"` //0:全部 1启用 2禁用
}
/**
* @api {POST} /api/v1/finstore/dev/bindings/creation [C/S][MOP]机构端应用管理创建应用
* @apiGroup Finclip App Manager
* @apiVersion __API_VERSION__
*
* @apiParam (RequestBody) {string} name 应用名
* @apiParam (RequestBody) {[]BundleInfo} bundleInfos bundid信息
* @apiParamExample {json} Request-Example:
* {
* "name": "应用名"
* "owner":"所属企业",
* "bundleInfos":[
* {
* "bundleId":"jaogajigaigojagioagj", //bundle id
* "remark":"备注"
* },
* {
* "bundleId":"jaogajigaigojagioagj", //bundle id
* "remark":"备注"
* }
* ]
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
/**
* @api {GET} /api/v1/mop/finstore/admin/bundle/list [C/S][MOP]获取bundleId列表
* @apiGroup Finclip App Manager
* @apiVersion __API_VERSION__
*
* @apiParam (Param) {int} [pageSize] 条数
* @apiParam (Param) {int} [pageNo] 当前页
* @apiParam (Param) {string} [searchText] 搜索bundleId
* @apiParam (Param) {int} [selectType] 过滤类型 0全部 1可用 2禁用
* @apiParamExample {URL} Request-Example:
* /api/v1/mop/finstore/admin/bundle/list?pageNo=1&pageSize=100&searchType=0
* @apiSuccessExample {json} Success Status:
* {
* "list": [
* {
* "SDKID": "0b2e431bca162a8a",
* "SDKKey": "bFmSSsu7UCSbIWhwzCvbNnH0wV1QJzE3hdcwS5zRz5g=",
* "bundleId": "autonpgdh",
* "createdAccount": "admin",
* "createdAt": 1653048845379,
* "createdBy": "admin",
* "isFirstCreate": true,
* "remark": "ios",
* "isForbidden":0
* }
* ],
* "total": 1
*}
* HTTP/1.1 200 OK
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func Bundles(c *gin.Context) {
ctx := apm.ApmClient().TraceContextFromGin(c)
req := BundlesReq{}
if err := c.BindQuery(&req); err != nil {
log.Errorf("Bundles req bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
log.Infof("Bundles req:%+v", req)
svr := service.NewBindingService()
total, bundleInfos, err := svr.ListAllBundleInfos(ctx, req.SearchText, req.SelectType, req.PageNo, req.PageSize)
if err != nil {
if svr.NotFound(err) {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
return
}
}
c.JSON(http.StatusOK, gin.H{
"total": total,
"list": bundleInfos,
})
return
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func CreateBundles(c *gin.Context) {
var req service.CreateBundlesReq
err := c.ShouldBindJSON(&req)
if err != nil {
log.Errorf("CreateBinding bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
if len(req.List) == 0 {
log.Warf("CreateBundles len list empty!")
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
return
}
req.DeveloperID = c.Request.Header.Get("X-Consumer-Custom-ID")
ctx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
statusCode := svr.CreateBundles(ctx, c, req)
if statusCode != utility.OK {
utility.MakeLocRsp(c, http.StatusInternalServerError, statusCode, gin.H{})
} else {
utility.MakeLocRsp(c, http.StatusCreated, utility.OK, gin.H{})
}
}
type BundleIsExistReq struct {
List []string `json:"list"`
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func BundleIsExist(c *gin.Context) {
var req BundleIsExistReq
err := c.BindJSON(&req)
if err != nil {
log.Errorf("CreateBinding bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
log.Infof("BundleIsExist req:%+v", req)
if len(req.List) > 200 {
log.Errorf("BundleIsExist req list over limit!")
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
ctx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
existBundleIds, statusCode := svr.BundleIsExist(ctx, req.List)
log.Errorf("existBundleIds", utility.InterfaceToJsonString(existBundleIds))
if statusCode != utility.OK {
utility.MakeLocRsp(c, http.StatusInternalServerError, statusCode, gin.H{})
} else {
c.JSON(http.StatusOK, gin.H{
"list": existBundleIds,
})
}
}
type GetSdkKeyReq struct {
AppId string `uri:"appId"`
}
type GetSdkKeyRsp struct {
List []string `json:"list"`
}
func GetSdkKeyList(c *gin.Context) {
traceCtx := apm.ApmClient().TraceContextFromGin(c)
req := GetSdkKeyReq{}
rsp := GetSdkKeyRsp{
List: make([]string, 0),
}
if err := c.BindUri(&req); err != nil {
log.Errorf("AdminGetAppVerDetail bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
svr := service.NewBindingService()
binds, err := svr.GetAssBindsByAppId(traceCtx, req.AppId)
if err != nil {
if service.NotFound(err) {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
log.Errorf("GetAssBindsByAppId err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{})
return
}
var sdkKeyListMap = make(map[string]bool, 0)
for _, v := range binds {
for _, sdkKeyInfo := range v.BundleInfos {
if _, ok := sdkKeyListMap[sdkKeyInfo.SDKKey]; !ok {
sdkKeyListMap[sdkKeyInfo.SDKKey] = true
}
}
}
for k, _ := range sdkKeyListMap {
rsp.List = append(rsp.List, k)
}
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}
/**
* @api {POST} /api/v1/mop/finstore/admin/bundle/update/is_forbidden [C/S][MOP]运营端更新bundleId禁用状态
* @apiGroup Finclip App Manager
* @apiVersion __API_VERSION__
*
* @apiParam (RequestBody) {string} bundleId bundleId
* @apiParam (RequestBody) {int} isForbidden 0:可用 1禁用
* @apiParamExample {json} Request-Example:
* {
* "bundleId": "test111",
* "isForbidden": 0
* }
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "",
* "data": {
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func UpdateBundlesIsForbidden(c *gin.Context) {
var req service.UpdateBundleIsForbiddenReq
err := c.ShouldBindJSON(&req)
if err != nil {
log.Errorf("UpdateBundlesIsForbidden bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
if req.BundleId == "" {
log.Warf("UpdateBundlesIsForbidden BundleId empty!")
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
return
}
ctx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
statusCode := svr.UpdateBundleIsForbidden(ctx, req)
if statusCode != utility.OK {
utility.MakeLocRsp(c, http.StatusInternalServerError, statusCode, gin.H{})
} else {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
}
}
/**
* @api {POST} /api/v1/mop/finstore/admin/bundle/update/platform [C/S][MOP]运营端更新bundleId平台
* @apiGroup Finclip App Manager
* @apiVersion __API_VERSION__
*
* @apiParam (RequestBody) {string} bundleId bundleId
* @apiParam (RequestBody) {int} platform 平台
* @apiParamExample {json} Request-Example:
* {
* "bundleId": "test111",
* "platform": "ios"
* }
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "",
* "data": {
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
func UpdateBundlesPlatform(c *gin.Context) {
var req service.UpdateBundlePlatformReq
err := c.ShouldBindJSON(&req)
if err != nil {
log.Errorf("UpdateBundlesPlatform bind err:%s", err.Error())
utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{})
return
}
if req.BundleId == "" {
log.Warf("UpdateBundlesPlatform BundleId empty!")
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
return
}
ctx := apm.ApmClient().TraceContextFromGin(c)
svr := service.NewBindingService()
statusCode := svr.UpdateBundlesPlatform(ctx, req)
if statusCode != utility.OK {
utility.MakeLocRsp(c, http.StatusInternalServerError, statusCode, gin.H{})
} else {
utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{})
}
}
/**
* @api {GET}
* @apiGroup Finclip App Manager
* @apiSuccessExample {json} Success Status:
* HTTP/1.1 200 OK
* {
* "errcode": "OK",
* "error": "成功",
* "data":{
*
* }
* }
* @apiErrorExample Error Status:
* HTTP/1.1 !=200 服务端异常
*/
type AddBundleIdLimitNumHandRsp struct {
AddAvailableLimitNum int `json:"addAvailableLimitNum"`
AddAllLimitNum int `json:"addAllLimitNum"`
}
func AddBundleIdLimitNumConfig(c *gin.Context) {
rsp := AddBundleIdLimitNumHandRsp{}
rsp.AddAllLimitNum = config.GetConfig().AddALLBundleNum
rsp.AddAvailableLimitNum = config.GetConfig().AddAvailableBundleNum
utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp)
return
}