commit 56ac08c5763d31fa0e4d5be8748801aa53d10fe5 Author: dengxiangcun Date: Tue Oct 31 14:07:26 2023 +0800 feat:init diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..abf5947 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM docker.finogeeks.club/mop-infra/alpine:latest +MAINTAINER xuls + +RUN mkdir -p /opt/conf/ +COPY ./infrastructure/config/conf/bindingWhiteList.json /opt/conf/ +COPY ./infrastructure/config/conf/bindingWhiteListHccDev.json /opt/conf/ +COPY ./infrastructure/config/conf/bindingWhiteListHccUat.json /opt/conf/ + +RUN chown 1024 /opt/conf/ +#USER 1024 +COPY finclip-app-manager /opt/finclip-app-manager +WORKDIR /opt/ +ENTRYPOINT ./finclip-app-manager + +# FROM docker.finogeeks.club/base/alpine + +# RUN ls + +# RUN set -ex \ +# && apk add --no-cache ca-certificates + +# COPY finclip-app-manager /opt/finclip-app-manager + +# ENTRYPOINT /opt/finclip-app-manager \ No newline at end of file diff --git a/application/app.go b/application/app.go new file mode 100644 index 0000000..7cace26 --- /dev/null +++ b/application/app.go @@ -0,0 +1,3137 @@ +package application + +import ( + "bytes" + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/gin-gonic/gin" + "github.com/pkg/errors" + "github.com/tealeg/xlsx" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +const ( + MAX_EXPIRE_DATA = 9999999999999 +) + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/creation [C/S]创建小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appClass //小程序分类 + * @apiParam (RequestBody) {[]string} appTag //小程序标签 + * @apiParam (RequestBody) {string} appType //小程序类型 + * @apiParam (RequestBody) {string} coreDescription //小程序描述 + * @apiParam (RequestBody) {string} logo //小程序logo + * @apiParam (RequestBody) {string} name //小程序名称 + * @apiParam (RequestBody) {int} projectType //项目类型,默认 0,代表小程序,1 小游戏,2 H5 + * @apiParamExample {json} Request-Example: + * { + * "appClass": "jinrong", + * "appTag":["a","b"], + * "appType":"c", + * "coreDescription":"详情", + * "logo":"/api/v1/netdisk/download/243454567", + * "name":"开户" + * "projectType":0 + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevCreateApp(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + req = proto.CreateAppReq{} + ) + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("createApp bind json err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("createApp get req:%+v", req) + accountId := utility.GetUserId(c) + if accountId == "" { + log.Errorf("DevCreateApp user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("createApp get user id:%+v", accountId) + + svr := service.NewAppService() + rspData, rsp := svr.CreateApp(traceCtx, c, req, accountId) + if rspData != nil { + go autoBindingAppByCreate(rspData, accountId) + rsp.MakeRsp(c, rspData) + } else { + rsp.MakeRsp(c, gin.H{}) + } + return +} + +func autoBindingAppByCreate(app *entity.App, accountId string) { + svr := service.NewBindingService() + svr.AutoBindingAppByCreate(app, accountId) +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/update [C/S]更新编辑小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} appClass //小程序分类 + * @apiParam (RequestBody) {[]string} appTag //小程序标签 + * @apiParam (RequestBody) {string} appType //小程序类型 + * @apiParam (RequestBody) {string} coreDescription //小程序描述 + * @apiParam (RequestBody) {string} logo //小程序logo + * @apiParam (RequestBody) {string} name //小程序名称 + * @apiParam (RequestBody) {object} customData //小程序自定义内容 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "appClass": "jinrong", + * "appTag":["a","b"], + * "appType":"c", + * "coreDescription":"详情", + * "logo":"/api/v1/netdisk/download/243454567", + * "name":"开户", + * "customData":{ + * "detailDescription":"详细信息" + * } + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevUpdateApp(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := proto.AppUpdateReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("updateApp bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("updateApp get req:%+v", req) + if req.AppId == "" || req.Name == "" || req.CoreDescription == "" { + log.Errorf("update app req err:%+v", req) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("update app user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_USER_ID, gin.H{}) + return + } + rsp := service.NewAppService().UpdateApp(traceCtx, c, req, userId) + rsp.MakeRsp(c, gin.H{}) + return +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/is_forbidden/update [C/S]禁用解禁小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} isForbidden //0:解禁,1:禁用 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "isForbidden": 1 + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevUpdateAppIsForbidden(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := proto.AppIsForbiddenUpdateReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("updateAppIsForbidden bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("updateAppIsForbidden get req:%+v", req) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("update app isForbidden user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_USER_ID, gin.H{}) + return + } + rsp := service.NewAppService().UpdateAppIsForbidden(traceCtx, req, userId) + rsp.MakeRsp(c, gin.H{}) + return +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/publish-request [C/S]提交小程序上架审核 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} id //编译id + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} developerId //开发者id + * @apiParam (RequestBody) {bool} needAutoPub //是否自动发布 + * @apiParam (RequestBody) {object} testInfo //测试内容 + * @apiParamExample {json} Request-Example: + * { + * "id":"61b32654659d2b00016264a9", + * "appId":"61b32654659d2b00016264a8", + * "developerId": "61b32654659d2b00016264a7", + * "needAutoPub":true, + * "testInfo":{ + * "account":"zhangsan", + * "password":"123456", + * "description":"测试使用", + * "images":[ + * "logo1地址", + * "logo2地址" + * ] + * } + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevSubmitPublishRequest(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + req = apiproto.SubmitPublishReqest{} + ) + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("submitPublishRequest bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("submitPublishRequest req:%+v", req) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("DevSubmitPublishRequest user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + service.NewAppService().SubmitApp(traceCtx, c, req, userId).MakeRsp(c, gin.H{}) +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/publish-request-withdrawal [C/S]撤销小程序上架审核 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} developerId //开发者id + * @apiParam (RequestBody) {int} sequence //小程序序列号 + * @apiParam (RequestBody) {string} reason //原因 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "developerId":"61b32654659d2b00016264a7", + * "sequence": 1, + * "reason":"非法小程序" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +type developerRequest struct { + AppID string `json:"appId" bson:"appId"` + Sequence int `json:"sequence" bson:"sequence"` + DeveloperID string `json:"developerId" bson:"developerId"` + Reason string `json:"reason" bson:"reason"` +} + +func DevWithdrawPublishRequest(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := developerRequest{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("withdrawPublishRequest bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("withdrawPublishRequest get req:%+v", req) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("withdrawPublishRequest get user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + rsp := service.NewAppService().WithdrawPublishRequest(traceCtx, c, req.AppID, req.Sequence, userId) + rsp.MakeRsp(c, gin.H{}) + //c.JSON(http.StatusOK, gin.H{}) +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/publish [C/S]上架小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} developerId //开发者id + * @apiParam (RequestBody) {int} sequence //小程序序列号 + * @apiParam (RequestBody) {string} reason //原因 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "developerId":"61b32654659d2b00016264a7", + * "sequence": 1, + * "reason":"非法小程序" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevPublishApp(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := developerRequest{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("DevPublishApp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("DevPublishApp get req:%+v", req) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("DevPublishApp user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + rsp := service.NewAppService().PubApp(traceCtx, req.AppID, req.Sequence, userId) + rsp.MakeRsp(c, gin.H{}) +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/unpublish [C/S]下架小程序【企业端】 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} sequence //小程序序列号 + * @apiParam (RequestBody) {string} reason //原因 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "sequence": 1, + * "reason":"非法小程序" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevUnpublishApp(c *gin.Context) { + unpublishAppHelp(c, true) +} + +/** + * @api {POST} /api/v1/mop/finstore/admin/apps/unpublish [C/S]下架小程序【运营端】 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} sequence //小程序序列号 + * @apiParam (RequestBody) {string} reason //原因 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "sequence": 1, + * "reason":"非法小程序" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func AdminUnpublishApp(c *gin.Context) { + unpublishAppHelp(c, false) +} + +type unpublishRequest struct { + AppID string `json:"appId" bson:"appId"` + Sequence int `json:"sequence" bson:"sequence"` + Reason string `json:"reason" bson:"reason"` +} + +func unpublishAppHelp(c *gin.Context, isDev bool) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := unpublishRequest{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("unpublishAppHelp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + userId := utility.GetUserId(c) + svr := service.NewAppService() + rsp := svr.UnpubApp(traceCtx, c, req.AppID, req.Sequence, userId, isDev, req.Reason) + rsp.MakeRsp(c, gin.H{}) +} + +type approveRequest struct { + AppID string `json:"appId"` + Sequence int `json:"sequence"` + //AdministratorID string `json:"administratorId" bson:"administratorId"` + Status string `json:"status"` + Reason string `json:"reason"` +} + +func AdminApproveApp(c *gin.Context) { + approveApp(c, true) +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/approval [C/S]审核小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} sequence //小程序序列号 + * @apiParam (RequestBody) {string} status //状态 + * @apiParam (RequestBody) {string} reason //审核原因 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "sequence": 1, + * "status":"PublishApproved", //PublishRejected:拒绝,PublishApproved:通过 + * "reason":"通过" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevApproveApp(c *gin.Context) { + approveApp(c, false) +} + +func approveApp(c *gin.Context, isAdmin bool) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.ApproveAppReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("approveApp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + req.RequestFrom = c.GetHeader("C-Open-Api") + log.Infof("approveApp get req:%+v,isAdmin:%t requestFrom:%s", req, isAdmin, req.RequestFrom) + userId := utility.GetUserId(c) + svr := service.NewAppService() + rsp := svr.ApproveApp(traceCtx, req, isAdmin, userId) + rsp.MakeRsp(c, gin.H{}) +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/appInfo/rollbackList?appId=62986e87277a0d00017b782e [C/S]回滚列表 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId //小程序id + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": [ + * { + * "appId": "62986e87277a0d00017b782e", + * "name": "1", + * "appClass": "jinrong", + * "appTag": [ + * "zhengquankaihu" + * ], + * "appType": "Applet", + * "status": { + * "value": "Published", + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "publishingStatus": { + * "reason": "", + * "lastUpdated": 1654156994088, + * "modifiedBy": "15377373355" + * }, + * "unpublishingStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "unpublishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishedStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "unpublishedStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "", + * "type": "" + * }, + * "requestStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "approvalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "actionStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "developerId": "628b2215062d300001e36285", + * "groupId": "628b2215062d300001e36286", + * "created": 1654156994088, + * "createdBy": "15377373355", + * "customData": { + * "detailDescription": "", + * "sourceFile": [ + * { + * "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + * "name": "app.zip", + * "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + * "uploadDate": 1654156973289, + * "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + * "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + * "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + * "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + * "basicPackVer": "", + * "Packages": [], + * "EncryptPackages": [] + * } + * ], + * "versionDescription": "1.0.0", + * "developer": "15377373355" + * }, + * "version": "1.0.0", + * "sequence": 1, + * "corporationId": "", + * "coreDescription": "123", + * "logo": "https://www-cdn.finclip.com/images/ic-default.png", + * "isRollback": false, + * "testInfo": { + * "account": "", + * "password": "", + * "description": "", + * "images": [] + * }, + * "needAutoPub": true, + * "inGrayRelease": false, + * "expire": 0, + * "appBuildID": "62986ead277a0d00017b782f" + * }, + * {...} + * ] + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func RollbackListApps(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("RollbackListApps user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewAppService() + appVerList, err := svr.RollbackAppList(traceCtx, appId, userId) + if err != nil { + log.Errorf("RollbackListApps svr err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVerList) + return +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps?bindingId=6298937b277a0d00017b7860&searchText=&searchFields=name&pageSize=10000&pageNo=0 [C/S]获取未关联小程序列表 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} bindingId //应用id + * @apiParam (RequestParam) {string} searchText //模糊匹配内容 + * @apiParam (RequestParam) {string} searchFields //小程序id + * @apiParam (RequestParam) {string} pageNo //页码 + * @apiParam (RequestParam) {string} pageSize //页大小 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "list": [ + * { + * "appId": "62986e87277a0d00017b782e", + * "name": "开户", + * "appClass":"小程序类别", + * "status":{ + * "value":"小程序状态" + * }, + * {...} + * ] + * "total":100 //总数 + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevListApps(c *gin.Context) { + bindingID := c.Query("bindingId") + if bindingID == "" { + listApps(c, true, false, false) + } else { + // MOP + listAppsToBind(c, bindingID) + } +} + +func DevGetApp(c *gin.Context) { + appID := c.Param("path1") + getApp(c, appID) +} + +func AdminGetApp(c *gin.Context) { + appID := c.Param("path1") + getApp(c, appID) +} + +type InternalGetAppReq struct { + AppId string `form:"appId"` +} + +func InternalGetApp(c *gin.Context) { + req := InternalGetAppReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("InternalGetApp err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + getApp(c, req.AppId) +} + +func getApp(c *gin.Context, appId string) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + if appId == "" { + log.Errorf("getApp appid empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewAppService() + appVerInfo, err := svr.GetLatestPubAppVer(traceCtx, appId) + if err != nil { + log.Debugf("getApp GetLatestPubAppVer err:%s", err.Error()) + if !service.NotFound(err) { + log.Errorf("getApp err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + } else { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVerInfo) + return + } + appInfo, err := service.NewAppService().GetAppInfo(traceCtx, appId) + if err != nil { + log.Errorf("getApp db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_BAD_JSON, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appInfo) +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps/62986e87277a0d00017b782e/inDevelopment [C/S]获取指定小程序开发列表 + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "appId": "62986e87277a0d00017b782e", + "name": "1", + "sequence": 0, + "appClass": "jinrong", + "appTag": [ + "zhengquankaihu" + ], + "appType": "Applet", + "status": { + "value": "Published", + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "publishedStatus": { + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "unpublishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "actionStatus": { + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "developerId": "628b2215062d300001e36285", + "groupId": "628b2215062d300001e36286", + "created": 1654156935640, + "createdBy": "15377373355", + "customData": { + "detailDescription": "", + "sourceFile": [ + { + "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + "name": "app.zip", + "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + "uploadDate": 1654156973289, + "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + "basicPackVer": "", + "Packages": [], + "EncryptPackages": [] + } + ], + "versionDescription": "1.0.0", + "developer": "15377373355" + }, + "version": "1.0.0", + "coreDescription": "123", + "logo": "https://www-cdn.finclip.com/images/ic-default.png", + "testInfo": { + "account": "", + "password": "", + "description": "", + "images": null + }, + "expire": 9999999999999, + "isRollback": false, + "applyStatus": "", + "isForbidden": 1, + "privacySettingType": 0 + }, + "errcode": "OK", + "error": "" +} +* @apiErrorExample Error Status: +* HTTP/1.1 !=200 服务端异常 +*/ +func DevGetAppInDevelopment(c *gin.Context) { + getAppInDevelopment(c) +} + +func AdminGetAppInDevelopment(c *gin.Context) { + getAppInDevelopment(c) +} + +func ClientGetAppInDevelopment(c *gin.Context) { + getAppInDevelopment(c) +} + +func GetAppInDevelopment(c *gin.Context) { + getAppInDevelopment(c) +} + +func getAppInDevelopment(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("path1") + if appID == "" { + log.Errorf("getAppInDevelopment appid empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + log.Infof("getAppInDevelopment appId:%s", appID) + appInfo, err := service.NewAppService().GetAppInfoByAppId(traceCtx, appID) + if err != nil { + log.Errorf("getAppInDevelopment err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + latestBuildInfo, err := service.NewAppAppletInfoService().GetLatestInfoByAppId(traceCtx, appID) + if err != nil && !service.NotFound(err) { + log.Errorf("GetLatestInfoByAppId err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + if !service.NotFound(err) && latestBuildInfo != nil { + appInfo.Version = latestBuildInfo.Version + appInfo.CustomData.Developer = latestBuildInfo.CustomData.Developer + appInfo.CustomData.VersionDescription = latestBuildInfo.CustomData.VersionDescription + //appInfo.CustomData.DetailDescription = "" + if len(latestBuildInfo.CustomData.SourceFile) > 0 { + info := latestBuildInfo.CustomData.SourceFile[0] + appInfo.CustomData.SourceFile = append(appInfo.CustomData.SourceFile, entity.CustomDataSourceFile{ + FileMd5: info.FileMd5, + Name: info.Name, + SourceFileUrl: info.SourceFileUrl, + UploadDate: info.UploadDate, + Url: info.Url, + EncryptedUrl: info.EncryptedUrl, + EncryptedFileMd5: info.EncryptedFileMd5, + EncryptedFileSha256: info.EncryptedFileSha256, + BasicPackVer: info.BasicPackVer, + Packages: info.Packages, + EncryptPackages: info.EncryptPackages, + }) + } + } + //c.JSON(http.StatusOK, appInfo) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appInfo) +} + +type AdminListAppsReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchFields string `form:"searchFields"` + SearchText string `form:"searchText"` + PullType string `form:"pullType"` +} + +func AdminListApps(c *gin.Context) { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) +} + +func AdminListAppsV2(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminListAppsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminListApps bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + req.PageNo += 1 + if req.PageSize == 0 || req.PageSize > 200 { + req.PageSize = 200 + } + svr := service.NewAppService() + svrReq := service.ListAppsReq{ + PageNo: req.PageNo, + PageSize: req.PageSize, + SearchText: req.SearchText, + PullType: req.PullType, + } + log.Infof("AdminListAppsV2 svr req:%+v", svrReq) + total, apps, err := svr.AdminListApps(traceCtx, &svrReq) + if err != nil { + log.Errorf("AdminListAppsV2 list apps err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + c.JSON(http.StatusOK, gin.H{ + "total": total, + "list": apps, + }) +} + +func AdminListPubApps(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminListAppsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminListPubApps bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + req.PageNo += 1 + if req.PageSize == 0 || req.PageSize > 200 { + req.PageSize = 200 + } + svr := service.NewAppService() + svrReq := service.ListAppsReq{ + PageNo: req.PageNo, + PageSize: req.PageSize, + SearchText: req.SearchText, + PullType: req.PullType, + } + log.Infof("AdminListPubApps svr req:%+v", svrReq) + total, apps, err := svr.AdminListPubApps(traceCtx, &svrReq) + if err != nil { + log.Errorf("AdminListPubApps list apps err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + c.JSON(http.StatusOK, gin.H{ + "total": total, + "list": apps, + }) +} + +func listApps(c *gin.Context, isDev, isAdmin, isClient bool) { + return +} + +func listAppsV2(c *gin.Context, isDev, isAdmin, isClient bool) { + return +} + +type listAppsToBindStatus struct { + Value string `json:"value"` +} + +type ListAppsToBindRspItem struct { + AppId string `json:"appId"` + Name string `json:"name"` + AppClass string `json:"appClass"` + ApplyStatus string `json:"applyStatus"` + Status listAppsToBindStatus `json:"status"` +} + +//获取应用未关联的所有小程序 +func listAppsToBind(c *gin.Context, bindingID string) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.ListAppsToBindReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("listAppsToBind bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + req.PageNo += 1 + log.Infof("listAppsToBind req:%+v", req) + svr := service.NewAppService() + total, apps, err := svr.GetAppsToBinding(traceCtx, req) + if err != nil { + log.Errorf("GetAppsToBinding err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + rspDataList := make([]ListAppsToBindRspItem, 0) + for _, v := range apps { + rspDataList = append(rspDataList, ListAppsToBindRspItem{ + AppId: v.AppID, + Name: v.Name, + AppClass: v.AppClass, + ApplyStatus: v.ApplyStatus, + Status: listAppsToBindStatus{v.Status.Value}, + }) + } + //if config.Cfg.PublishEnv == ENV_FDEP { + // rspData, err = fillApplyStatus(traceCtx, rspData, bindingID) + // if err != nil { + // MakeRsp(c, http.StatusInternalServerError, FS_DB_ERR, gin.H{}) + // return + // } + //} + c.JSON(http.StatusOK, gin.H{"total": total, "list": rspDataList}) + // utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} + +type AdminGetAppReviewsRsp struct { + Total int `json:"total"` + List []entity.AppVersion `json:"list"` +} + +func AdminGetAppReviews(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.AdminGetAppReviewsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminGetAppReviews bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + log.Infof("AdminGetAppReviews req:%+v", req) + rsp := AdminGetAppReviewsRsp{ + Total: 0, + List: make([]entity.AppVersion, 0), + } + total, appVers, err := service.NewAppService().AdminGetAppReviews(traceCtx, req) + if err != nil { + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) + return + } + log.Errorf("AdminGetAppReviews db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rsp.Total = total + rsp.List = appVers + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/statistics/apps?distinct=true&startTime=1&endTime=2&isForbidden=1 [C/S]获取小程序不同类型总数 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {bool} distinct //是否获取分布 + * @apiParam (RequestParam) {int} startTime //开始时间 + * @apiParam (RequestParam) {int} endTime //结束时间 + * @apiParam (RequestParam) {int} isForbidden //是否包含禁用 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "created": 1, + * "submited":2, + * "approved":3, + * "published":4 + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DevGetStatistics(c *gin.Context) { + getStatistics(c, true) +} + +func AdminGetStatistics(c *gin.Context) { + getStatistics(c, false) +} + +type getStatisticsReq struct { + Distinct bool `form:"distinct"` + StartTime int64 `form:"startTime"` + EndTime int64 `form:"endTime"` + IsForbidden int `form:"isForbidden,default=2"` +} + +type getStatisticsResponse struct { + Created int `json:"created"` + Submited int `json:"submited"` + Approved int `json:"approved"` + Published int `json:"published"` +} + +func getStatistics(c *gin.Context, isDev bool) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := getStatisticsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("getStatistics bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewAppService() + var groupId string + if isDev { + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("getStatistics is dev but user id empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + accountInfo, err := hCaller.GetAccountInfo(traceCtx, userId) + if err != nil { + log.Errorf("GetAccountInfo err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + groupId = accountInfo.OrganId + } + rsp, err := svr.AppStatistics(traceCtx, req.StartTime, req.EndTime, groupId, req.Distinct, req.IsForbidden) + if err != nil { + log.Errorf("AppStatistics svr err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + c.JSON(http.StatusOK, rsp) + //utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +type DevListAppsAndReviewsReq struct { + ListType string `form:"listType"` + GroupId string `form:"groupId"` + AppId string `form:"appId"` + Query string `form:"query"` + Sort string `form:"sort"` + SearchFields string `form:"searchFields"` + SearchText string `form:"searchText"` + PageSize int `form:"pageSize"` + PageNo int `form:"pageNo"` + ReviewsPageSize int `form:"reviewsPageSize"` + ReviewsPageNo int `form:"reviewsPageNo"` +} + +type DevListAppsAndReviewsRsp struct { + Total int `json:"total"` + List []AppsAndReviewRspItem `json:"list"` +} +type ReviewsRsp struct { + Total int `json:"total"` + List []ReviewsRspItem `json:"list"` +} +type AppsAndReviewRspItem struct { + AppId string `json:"appId"` + Name string `json:"name"` + Logo string `json:"logo"` + Version string `json:"version"` + Status string `json:"status"` + ReviewTotal int `json:"reviewTotal"` + ReviewList []ReviewsRspItem `json:"reviewList"` +} +type ReviewsRspItem struct { + Sequence int `json:"sequence"` + Status string `json:"status"` + Version string `json:"version"` +} + +func DevListAppsAndReviews(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := DevListAppsAndReviewsReq{} + if err := c.ShouldBindQuery(&req); err != nil { + log.Errorf("DevListAppsAndReviews bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("DevListAppsAndReviews req:%+v", req) + if req.ListType == "" || (req.ListType != "appsAndReviews" && req.ListType != "reviews") { + log.Errorf("DevListAppsAndReviews list type err,type:%s", req.ListType) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.PageSize == 0 || req.PageSize > 50 { + req.PageSize = 10 + } + req.PageNo += 1 + if req.ReviewsPageSize == 0 || req.ReviewsPageSize > 50 { + req.ReviewsPageSize = 50 + } + data, rsp := service.NewAppService().ListAppAndReviews(traceCtx, req.AppId, req.PageNo, req.PageSize) + rsp.MakeRsp(c, data) + return +} + +func AdminGetAppVersion(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + lang := c.Request.Header.Get("lang") + appID := c.Param("path1") + seqStr := c.Param("path3") + if appID == "" { + log.Errorf("AdminGetAppVersion appid empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + sequence, err := strconv.Atoi(seqStr) + if err != nil { + log.Errorf("AdminGetAppVersion sequence err,sequence:%v", seqStr) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + userId := utility.GetUserId(c) + _, err = hCaller.GetAdminAccountInfo(traceCtx, userId) + if err != nil { + log.Errorf("DevGetAppVersion user id account info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + appVer, err := service.NewAppService().GetAppVerInfo(traceCtx, appID, sequence) + if err != nil { + log.Errorf("AdminGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + + if lang == "en" { + if appVer.ActionStatus.ModifiedBy == "自动上架" { + appVer.ActionStatus.ModifiedBy = "system" + } + if appVer.ActionStatus.ModifiedBy == "管理员" { + appVer.ActionStatus.ModifiedBy = "admin" + } + if appVer.PublishedStatus.ModifiedBy == "自动上架" { + appVer.PublishedStatus.ModifiedBy = "system" + } + if appVer.PublishedStatus.ModifiedBy == "管理员" { + appVer.PublishedStatus.ModifiedBy = "admin" + } + if appVer.Status.ModifiedBy == "自动上架" { + appVer.Status.ModifiedBy = "system" + } + if appVer.Status.ModifiedBy == "管理员" { + appVer.Status.ModifiedBy = "admin" + } + if appVer.UnpublishedStatus.ModifiedBy == "自动上架" { + appVer.UnpublishedStatus.ModifiedBy = "system" + } + if appVer.UnpublishedStatus.ModifiedBy == "管理员" { + appVer.UnpublishedStatus.ModifiedBy = "admin" + } + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVer) +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps/62986e87277a0d00017b782e/sequences/9 [C/S]获取指定小程序序列号的开发列表 + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "appId": "62986e87277a0d00017b782e", + "name": "1", + "appClass": "jinrong", + "appTag": [ + "zhengquankaihu" + ], + "appType": "Applet", + "status": { + "value": "PublishApproved", + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "publishingStatus": { + "reason": "", + "lastUpdated": 1654165260773, + "modifiedBy": "15377373355" + }, + "unpublishingStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishingApprovalStatus": { + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "unpublishingApprovalStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "unpublishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "", + "type": "" + }, + "requestStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "approvalStatus": { + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "actionStatus": { + "reason": "", + "lastUpdated": 1654165260773, + "modifiedBy": "15377373355" + }, + "developerId": "628b2215062d300001e36285", + "groupId": "628b2215062d300001e36286", + "created": 1654165260773, + "createdBy": "15377373355", + "customData": { + "detailDescription": "", + "sourceFile": [ + { + "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + "name": "app.zip", + "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + "uploadDate": 1654156973289, + "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + "basicPackVer": "", + "Packages": [], + "EncryptPackages": [] + } + ], + "versionDescription": "1.0.0", + "developer": "15377373355" + }, + "version": "1.0.0", + "sequence": 9, + "corporationId": "", + "coreDescription": "123", + "logo": "https://www-cdn.finclip.com/images/ic-default.png", + "isRollback": false, + "testInfo": { + "account": "", + "password": "", + "description": "", + "images": [] + }, + "needAutoPub": false, + "inGrayRelease": false, + "expire": 0, + "appBuildID": "62986ead277a0d00017b782f" + }, + "errcode": "OK", + "error": "" +} + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 +*/ +func DevGetAppVersion(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("path1") + seqStr := c.Param("path3") + lang := c.Request.Header.Get("lang") + if appID == "" { + log.Errorf("DevGetAppVersion appid empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + sequence, err := strconv.Atoi(seqStr) + if err != nil { + log.Errorf("DevGetAppVersion sequence err,sequence:%v", seqStr) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + userId := utility.GetUserId(c) + accountInfo, err := hCaller.GetAccountInfo(traceCtx, userId) + if err != nil { + log.Errorf("DevGetAppVersion user id account info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + appVer, err := service.NewAppService().GetAppVerInfo(traceCtx, appID, sequence) + if err != nil { + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + if appVer.GroupID != accountInfo.OrganId { + log.Errorf("DevGetAppVersion organ id not match!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + + if lang == "en" { + if appVer.ActionStatus.ModifiedBy == "自动上架" { + appVer.ActionStatus.ModifiedBy = "system" + } + if appVer.ActionStatus.ModifiedBy == "管理员" { + appVer.ActionStatus.ModifiedBy = "admin" + } + if appVer.PublishedStatus.ModifiedBy == "自动上架" { + appVer.PublishedStatus.ModifiedBy = "system" + } + if appVer.PublishedStatus.ModifiedBy == "管理员" { + appVer.PublishedStatus.ModifiedBy = "admin" + } + if appVer.Status.ModifiedBy == "自动上架" { + appVer.Status.ModifiedBy = "system" + } + if appVer.Status.ModifiedBy == "管理员" { + appVer.Status.ModifiedBy = "admin" + } + if appVer.UnpublishedStatus.ModifiedBy == "自动上架" { + appVer.UnpublishedStatus.ModifiedBy = "system" + } + if appVer.UnpublishedStatus.ModifiedBy == "管理员" { + appVer.UnpublishedStatus.ModifiedBy = "admin" + } + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVer) +} + +type AdminGetAppVerDetailReq struct { + AppId string `uri:"appId"` + Sequence int `uri:"sequence"` +} + +type GetAppVerDeTailRsp struct { + AppID string `json:"appId"` + Name string `json:"name"` + GroupName string `json:"groupName"` +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/app-ver/62986e87277a0d00017b782e/9 [C/S]获取某个企业小程序列表 + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": { + * "appId":"62986e87277a0d00017b782e", + * "name":"开户", + * "groupName":"test" + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func AdminGetAppVerDetail(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminGetAppVerDetailReq{} + errRsp := make(map[string]interface{}) + if err := c.BindUri(&req); err != nil { + log.Errorf("AdminGetAppVerDetail bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, errRsp) + return + } + appVer, err := service.NewAppService().GetAppVerInfo(traceCtx, req.AppId, req.Sequence) + if err != nil { + log.Errorf("AdminGetAppVerDetail err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp) + return + } + rspData := GetAppVerDeTailRsp{ + AppID: appVer.AppID, + Name: appVer.Name, + GroupName: "", + } + groupInfo, err := hCaller.GetGroupInfoByGroupId(traceCtx, appVer.GroupID) + if err != nil { + log.Errorf("AdminGetAppVerDetail GetGroupInfoByGroupId err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, errRsp) + return + } + rspData.GroupName = groupInfo.GroupName + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +//获取小程序关联管理列表 +type AdminGetLinkAppletsRspItem struct { + BindingInfo entity.Binding `json:"bindingInfo"` + AppIdInfo entity.AppInfo `json:"appIdInfo"` +} +type AdminGetLinkAppletsReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchText"` +} + +func AdminGetLinkApplets(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + + req := AdminGetLinkAppletsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminGetLinkApplets bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("AdminGetLinkApplets req:%+v", req) + svr := service.NewAppService() + total, rspData, err := svr.AdminGetLinkApps(traceCtx, req.SearchText, req.PageNo, req.PageSize) + if err != nil { + log.Errorf("AdminGetLinkApplets err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + c.JSON(http.StatusOK, gin.H{ + "total": total, + "list": rspData, + }) + //utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) +} + +type AdminLinkAppletAuditsReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchText"` +} + +func AdminLinkAppletAudits(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + //serachTxt := c.Query("searchText") + // + //pageNo, err := strconv.Atoi(c.Query("pageNo")) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, err, "param pageNo error", nil) + // return + //} + //pageSize, err := strconv.Atoi(c.Query("pageSize")) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, err, "param pageSize error", nil) + // return + //} + // + //applyStatusStr := c.Query("applyStatus") + //var applyStatus []string + //if applyStatusStr != "" { + // applyStatus = strings.Split(applyStatusStr, ",") + //} + // + //models, total, err := service.LinkAppletAudits(traceCtx, serachTxt, pageNo, pageSize, applyStatus) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //MakeRsp(c, http.StatusOK, OK, gin.H{ + // "total": total, + // "list": models, + //}) +} + +type AdminLinkAppletAuditDetailReq struct { + AuditId string `form:"auditId"` +} + +func AdminLinkAppletAuditDetail(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminLinkAppletAuditDetailReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminLinkAppletAuditDetail bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("AdminLinkAppletAuditDetail req:%+v", req) + //auditId := c.Query("auditId") + //if auditId == "" { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_PARAM_ERR, nil, "auditId can not be null", nil) + // return + //} + // + //audit, err := service.LinkAppletAudit(traceCtx, auditId) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //appTable := db.NewTable(db.TableApp) + //apps := make([]model.App, 0) + //if _, err := appTable.GetSome(traceCtx, bson.M{"appId": audit.AppId}, []string{"-Sequence"}, 1, 0, &apps); err != nil || len(apps) == 0 { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + //app := apps[0] + // + //t := db.NewTable(db.TableAppVersion) + //appVerInfo := model.AppVersion{} + //if err := t.GetOne(traceCtx, bson.M{"appId": app.AppID, "sequence": app.Sequence}, &appVerInfo); err != nil { + // return + //} + //if t.NotFound() { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_APP_SEQUENCE_NOT_FOUND, err, "RuntimeGetAppVersionInfo get appVer not found!", nil) + // return + //} + // + //bindingTable := db.NewTable(db.TableBinding) + //bindingInfo := model.Binding{} + //err = bindingTable.GetOne(traceCtx, bson.M{"bindingId": audit.BindingId}, &bindingInfo) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //appDetail := model.AppDetail{} + //appDetail.AppId = app.AppID + //appDetail.Name = app.Name + //appDetail.Logo = app.Logo + //appDetail.AppClass = app.AppClass + //appDetail.AppTag = app.AppTag + //appDetail.CoreDescription = app.CoreDescription + //appDetail.Version = app.Version + //appDetail.CustomData = app.CustomData + //appDetail.TestInfo = app.TestInfo + //appDetail.Created = appVerInfo.Created + //appDetail.Sequence = app.Sequence + // + //bindingDetail := model.BindingDetail{} + //bindingDetail.Name = bindingInfo.Name + //bindingDetail.BindingId = bindingInfo.BindingID + //bindingDetail.GroupID = bindingInfo.GroupID + //bindingDetail.CreatedAt = bindingInfo.CreatedInfo.CreatedAt + //bindingDetail.GroupName = bindingInfo.GroupName + //bindingDetail.BundleInfos = bindingInfo.BundleInfos + // + //audit.AppDetail = &appDetail + //audit.BindingDetail = &bindingDetail + // + //MakeRsp(c, http.StatusOK, OK, audit) +} + +type auditOperateReq struct { + Operate string `json:"operate"` + AuditId string `json:"auditId"` + Reason string `json:"reason"` +} + +func AdminLinkAppletAuditOperate(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := auditOperateReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("AdminLinkAppletAuditOperate bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("AdminLinkAppletAuditOperate req:%+v", req) + //if req.AuditId == "" { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_PARAM_ERR, nil, "auditId can not be null", nil) + // return + //} + // + //if req.Operate != StLinkAuditRejected && req.Operate != StLinkAuditApplied { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_PARAM_ERR, nil, "operate invalid with:"+req.Operate, nil) + // return + //} + // + //developerID := c.Request.Header.Get("X-Consumer-Custom-ID") + //accountInfo, err := provider.GetAdminAccountInfo(traceCtx, c, developerID) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_GET_ACCOUNTINFO_ERROR, err, "", nil) + // return + //} + // + //err = service.LinkAppletAuditUpdateOperateStatus(traceCtx, req.AuditId, req.Operate, accountInfo.Account, req.Reason) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //audit, err := service.LinkAppletAudit(traceCtx, req.AuditId) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //if req.Operate == StLinkAuditApplied { + // bindingTable := db.NewTable(db.TableBinding) + // bindingInfo := model.Binding{} + // err := bindingTable.GetOne(traceCtx, bson.M{"bindingId": audit.BindingId}, &bindingInfo) + // if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + // } + // + // err = associate(c, []string{audit.AppId}, &bindingInfo, audit.GroupID, audit.AuditBy) + // if err != nil { + // return + // } + //} + //linkAuditNotify(traceCtx, &audit, req.Operate, req.Reason) + //linkAuditSmsNotify(traceCtx, c, &audit, req.Operate) + // + //MakeRsp(c, http.StatusOK, OK, nil) + //return +} + +type associateOperateReq struct { + Operate string `json:"operate"` + AppId string `json:"appId"` + BindingId string `json:"bindingId"` + GroupId string `json:"groupId"` + Account string `json:"account"` +} + +func AdminAssociateOperate(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := associateOperateReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("AdminAssociateOperate bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.Operate != entity.StLinkAuditAssociate && req.Operate != entity.StLinkAuditUnAssociate { + log.Errorf("AdminAssociateOperate operate invalid !") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + + if req.AppId == "" || req.BindingId == "" { + log.Errorf("appId&bindingId can not be null!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + + //bindingTable := db.NewTable(db.TableBinding) + //bindingInfo := model.Binding{} + //err := bindingTable.GetOne(traceCtx, bson.M{"bindingId": req.BindingId}, &bindingInfo) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_DB_ERR, err, "", nil) + // return + //} + // + //if req.Operate == StLinkAuditAssociate { + // err = associate(c, []string{req.AppId}, &bindingInfo, req.GroupId, req.Account) + //} else { + // err = disassociate(c, []string{req.AppId}, &bindingInfo, req.GroupId, req.Account) + //} + // + //if err != nil { + // return + //} + // + //MakeRsp(c, http.StatusOK, OK, nil) + //return +} + +func AdminGetAppClassPer(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + status := c.Param("status") + tp := c.DefaultQuery("tp", "query") + log.Infof("AdminGetAppClassPer get status:%s,tp:%s", status, tp) + svr := service.NewAppService() + rspData, err := svr.GetAppClassPer(traceCtx, status) + if err != nil { + log.Errorf("AdminGetAppClassPer err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + log.Infof("AdminGetAppClassPer rsp:%+v", rspData) + if tp == "export" { + content, err := Export(traceCtx, *rspData, status) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_EXPORT_APP_CLASS_ERR, gin.H{}) + return + } else { + fileName := fmt.Sprintf("app.class.%s.xlsx", time.Now().Format("20060102")) + c.Header("Content-Disposition", `attachment; filename=`+fileName) + contentType := "application/vnd.ms-excel" + c.Data(http.StatusOK, contentType, content) + } + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +func GetLatestAppVerInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + if appId == "" { + log.Errorf("GetLatestAppVerInfo app id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewAppService() + appVerInfo, err := svr.GetMaxSeqAppVer(traceCtx, appId) + if err != nil { + log.Errorf("GetLatestAppVerInfo db err:%s", err.Error()) + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusOK, utility.FS_NOT_FOUND, gin.H{}) + } else { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + } + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVerInfo) +} + +//获取最新上下架小程序版本详情 +func GetLatestPubAppVerInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + lang := c.Request.Header.Get("lang") + if appId == "" { + log.Errorf("GetLatestPubAppVerInfo app id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("GetLatestPubAppVerInfo appId:%s", appId) + svr := service.NewAppService() + appVerInfo, err := svr.GetLatestPubAppVer(traceCtx, appId) + if err != nil { + log.Errorf("GetLatestAppVerInfo db err:%s", err.Error()) + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + } else { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + } + return + } + + if lang == "en" { + if appVerInfo.ActionStatus.ModifiedBy == "自动上架" { + appVerInfo.ActionStatus.ModifiedBy = "system" + } + if appVerInfo.ActionStatus.ModifiedBy == "管理员" { + appVerInfo.ActionStatus.ModifiedBy = "admin" + } + if appVerInfo.PublishedStatus.ModifiedBy == "自动上架" { + appVerInfo.PublishedStatus.ModifiedBy = "system" + } + if appVerInfo.PublishedStatus.ModifiedBy == "管理员" { + appVerInfo.PublishedStatus.ModifiedBy = "admin" + } + if appVerInfo.Status.ModifiedBy == "自动上架" { + appVerInfo.Status.ModifiedBy = "system" + } + if appVerInfo.Status.ModifiedBy == "管理员" { + appVerInfo.Status.ModifiedBy = "admin" + } + if appVerInfo.UnpublishedStatus.ModifiedBy == "自动上架" { + appVerInfo.UnpublishedStatus.ModifiedBy = "system" + } + if appVerInfo.UnpublishedStatus.ModifiedBy == "管理员" { + appVerInfo.UnpublishedStatus.ModifiedBy = "admin" + } + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appVerInfo) +} + +type TitleClass struct { + Name string + Type string +} + +type ExportAppClass struct { +} + +func Export(ctx context.Context, data service.GetAppClassPerRsp, status string) ([]byte, error) { + return fillData(ctx, data, status) +} + +func export(titlesClass []TitleClass, matrix [][]string) ([]byte, error) { + file := xlsx.NewFile() + titles := []string{} + for _, t := range titlesClass { + titles = append(titles, t.Name) + } + sheet, err := addSheet(file, "Sheet1", titles) + if err != nil { + return nil, err + } + for _, cells := range matrix { + row := sheet.AddRow() + for idx, value := range cells { + cell := row.AddCell() + if titlesClass[idx].Type == "int" { + intVal, _ := strconv.Atoi(value) + cell.SetInt(intVal) + } else if titlesClass[idx].Type == "percent" { + float64Val, _ := strconv.ParseFloat(value, 64) + cell.SetFloatWithFormat(float64Val, "0.00%") + } else { + cell.Value = value + } + } + } + buf := new(bytes.Buffer) + file.Write(buf) + return buf.Bytes(), nil +} + +func addSheet(file *xlsx.File, name string, titles []string) (*xlsx.Sheet, error) { + if file == nil { + return nil, errors.New("xlsx file is nil") + } + sheet, err := file.AddSheet(name) + if err != nil { + return nil, err + } + row := sheet.AddRow() + var cell *xlsx.Cell + for _, title := range titles { + cell = row.AddCell() + cell.Value = title + } + return sheet, nil +} + +func fillData(ctx context.Context, data service.GetAppClassPerRsp, status string) ([]byte, error) { + if status == "published" { + status = "是" + } else { + status = "否" + } + titles := []TitleClass{{"小程序类型", "string"}, {"是否只看上架中的小程序", "string"}, {"数量", "int"}, {"占比", "percent"}} + total := 0 + matrix := [][]string{} + for _, item := range data.List { + total += item.Count + } + for _, item := range data.List { + cells := []string{} + if item.AppClassName == "" { + cells = append(cells, item.AppClass) + } else { + cells = append(cells, item.AppClassName) + } + cells = append(cells, status) + cells = append(cells, strconv.Itoa(item.Count)) + cells = append(cells, fmt.Sprintf("%.4f", float64(item.Count)/float64(total))) + matrix = append(matrix, cells) + } + return export(titles, matrix) +} + +type DevGetappReviewTrendDataReq struct { + StartTime int64 `form:"startTime"` + EndTime int64 `form:"endTime"` +} +type DevGetappReviewTrendDataResultItem struct { + Date string `bson:"_id" json:"date"` + Num int `bson:"num" json:"num"` +} +type DevGetappReviewTrendDataRsp struct { + ErrCode string `json:"errcode"` + Error string `json:"error"` + Data map[string]interface{} `json:"data"` +} + +func DevGetappReviewTrendData(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := DevGetappReviewTrendDataReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("DevGetappReviewTrendData bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + if req.StartTime >= req.EndTime || req.EndTime <= 0 { + log.Errorf("DevGetappReviewTrendData time value err!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + //rspData := make(map[string]interface{}) + //daysArry := GetTimeRangeDays(req.StartTime, req.EndTime) + //fmt.Println("days arry", daysArry) + ////首先拉取start之前的累计数据 + //t := db.NewTable(db.TableAppVersion) + //beforeMatchGrand := bson.M{ + // "status.value": bson.M{"$nin": []string{StInDevelopment, StPublishing, StPublishWithdrawed}}, + // //"approvalStatus.lastUpdated": bson.M{"$lte": req.StartTime - (24 * 60 * 60 * 1000)}, //获取前一天的时间 + // "approvalStatus.lastUpdated": bson.M{"$lte": req.StartTime}, //获取前一天的时间 + // "sequence": bson.M{"$ne": 0}, + //} + //beforeGroup := bson.M{ + // "_id": nil, + // "total": bson.M{"$sum": 1}, + //} + //beforeResultList := make([]db.TotalInfo, 0) + //beforePipe := []bson.M{ + // {"$match": beforeMatchGrand}, + // {"$group": beforeGroup}, + //} + //err := t.AggregateOnly(traceCtx, beforePipe, &beforeResultList) + //if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_DB_ERR, err, "Failed to get appVersion before total", nil) + // return + //} + //fmt.Println("before total:", beforeResultList) + //beforeResult := db.TotalInfo{} + //if len(beforeResultList) > 0 { + // beforeResult = beforeResultList[0] + //} + ////拉取累计审核的每天的数据 + //matchGrand := bson.M{ + // "status.value": bson.M{"$nin": []string{StInDevelopment, StPublishing, StPublishWithdrawed}}, + // //如果开始时间=结束时间,实际取得是这一天0:0:0 -- 23:59:59 + // "approvalStatus.lastUpdated": bson.M{"$gte": req.StartTime, "$lte": req.EndTime}, + // "sequence": bson.M{"$ne": 0}, + //} + //projectGrand := bson.M{ + // "statusValue": "$status.value", + // "formatTime": bson.M{ + // "$dateToString": bson.M{ + // "format": "%Y-%m-%d", + // "date": bson.M{"$add": []interface{}{time.Date(1970, 1, 1, 8, 0, 0, 0, time.Local), "$approvalStatus.lastUpdated"}}, + // }, + // }, + //} + //groupGrand := bson.M{ + // "_id": "$formatTime", + // "num": bson.M{"$sum": 1}, + //} + //countFilter := []bson.M{ + // {"$match": matchGrand}, + //} + //countFilter = append(countFilter, bson.M{ + // "$group": bson.M{ + // "_id": nil, + // "total": bson.M{ + // "$sum": 1, + // }, + // }, + //}) + //pipeFilter := []bson.M{ + // {"$match": matchGrand}, + // {"$project": projectGrand}, + // {"$group": groupGrand}, + // {"$sort": bson.M{"_id": 1}}, + //} + //result := make([]DevGetappReviewTrendDataResultItem, 0) + //total, err := t.Aggregate(traceCtx, countFilter, pipeFilter, &result) + //if err != nil && !t.NotFound() { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_DB_ERR, err, "Failed to get appVersion", nil) + // return + //} + //rspData["trendTotal"] = total + //fmt.Printf("get data,count:%d,result:%+v\n", total, result) + ////所有的日期+数据需要都返回给前端 + //trendRspItemsTemp := make([]DevGetappReviewTrendDataResultItem, 0) + //for _, v := range daysArry { + // foundV := false + // var foundItem DevGetappReviewTrendDataResultItem + // for _, item := range result { + // if item.Date == v { + // foundV = true + // foundItem = item + // } + // } + // if !foundV { + // foundItem = DevGetappReviewTrendDataResultItem{ + // Date: v, + // Num: 0, + // } + // } + // trendRspItemsTemp = append(trendRspItemsTemp, foundItem) + //} + ////第一天需要加上之前的所有 + //if len(trendRspItemsTemp) > 0 { + // trendRspItemsTemp[0].Num += beforeResult.Total + //} + ////累计审核 + //var preResultTotal int + //var foundItem DevGetappReviewTrendDataResultItem + //trendRspItems := make([]DevGetappReviewTrendDataResultItem, 0) + //isFirst := true + //for _, v := range trendRspItemsTemp { + // if isFirst { + // foundItem = DevGetappReviewTrendDataResultItem{Date: v.Date, Num: v.Num} + // preResultTotal = v.Num + // isFirst = false + // } else { + // foundItem = DevGetappReviewTrendDataResultItem{Date: v.Date, Num: preResultTotal + v.Num} + // preResultTotal = foundItem.Num + // } + // trendRspItems = append(trendRspItems, foundItem) + //} + ////新增审核 + //var preItem DevGetappReviewTrendDataResultItem + //AddNewRspItems := make([]DevGetappReviewTrendDataResultItem, 0) + //isFirst = true + //for _, item := range trendRspItems { + // if isFirst { + // foundItem = DevGetappReviewTrendDataResultItem{Num: 0, Date: item.Date} + // isFirst = false + // } else { + // foundItem = DevGetappReviewTrendDataResultItem{Num: item.Num - preItem.Num, Date: item.Date} + // } + // preItem = item + // AddNewRspItems = append(AddNewRspItems, foundItem) + //} + // + //rspData["trend"] = trendRspItems + //rspData["addNew"] = AddNewRspItems + // + ////rsp := DevGetappReviewTrendDataRsp{} + ////rsp.ErrCode = "OK" + ////rsp.Error = "" + ////rsp.Data = rspData + //c.JSON(http.StatusOK, rspData) +} + +type AdminListInDevAppHandReq struct { + PullType string `form:"pullType"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchTxt string `form:"searchTxt"` + SortType string `form:"sortType"` +} +type AdminListInDevAppHandRspItem struct { + AppId string `json:"appId"` + Name string `json:"name"` +} + +/** + * @api {GET} /api/v1/mop/finstore/admin//apps-v2/in-development?pageNo=1&pageSize=10&searchTxt=&sortType=created&pullType=dev-list [C/S]获取小程序开发列表【运营端】 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} pageNo //页码 + * @apiParam (RequestParam) {string} pageSize //页大小 + * @apiParam (RequestParam) {string} sortType //排序类型 + * @apiParam (RequestParam) {string} pullType //指定类别条件 + * @apiParam (RequestParam) {string} searchTxt //搜索内容 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "total": 1, + "list": [ + { + "appId": "62986e87277a0d00017b782e", + "name":"开户" + } + ] + }, + "errcode": "OK", + "error": "" +} + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 +*/ +func AdminListInDevAppHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminListInDevAppHandReq{} + if err := c.Bind(&req); err != nil { + log.Errorf("AdminListInDevAppHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.PageSize == 0 { + req.PageSize = 50 + } + if req.SortType == "" { + req.SortType = "-created" + } + req.PageNo += 1 + svrReq := service.ListAppsReq{ + PullType: req.PullType, + SortType: req.SortType, + PageNo: req.PageNo, + PageSize: req.PageSize, + SearchText: req.SearchTxt, + UserId: "", + IsDev: false, + } + log.Infof("AdminListInDevAppHand req:%+v", svrReq) + svr := service.NewAppService() + total, apps, err := svr.AdminListApps(traceCtx, &svrReq) + if err != nil { + log.Errorf("AdminListInDevAppHand err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rspData := make(map[string]interface{}) + rspData["total"] = total + list := make([]AdminListInDevAppHandRspItem, 0) + for _, v := range apps { + list = append(list, AdminListInDevAppHandRspItem{ + Name: v.Name, + AppId: v.AppID, + }) + } + rspData["list"] = list + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +type GetAppGroupIdRsp struct { + GroupID string `json:"groupId"` + Name string `json:"name"` + Logo string `json:"logo"` + CoreDescription string `json:"coreDescription"` + Version string `json:"version" bson:"version"` + Sequence int `json:"sequence" bson:"sequence"` +} + +func GetAppGroupIdByAppId(c *gin.Context) { + + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetAppInFoByAppId appId id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + appInfo, err := service.NewAppService().GetAppInfo(traceCtx, appId) + if err != nil { + log.Errorf("getApp db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_BAD_JSON, gin.H{}) + return + } + rsp := GetAppGroupIdRsp{} + rsp.GroupID = appInfo.GroupID + rsp.Name = appInfo.Name + rsp.Logo = appInfo.Logo + rsp.CoreDescription = appInfo.CoreDescription + rsp.Sequence = appInfo.Sequence + rsp.Version = appInfo.Version + //log.Debugln("GetAppInFoByAppIdRsp", rsp) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) + return +} +func UpdateHistoryAppMsg(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + //err := client.NotifySpider{}.UpdateHistoryAppMsg(traceCtx) + //if err != nil { + // log.Errorf("UpdateHistoryAppMsg err:%s", err.Error()) + //} + //MakeRsp(c, http.StatusOK, common.OK, nil) + return +} + +func UpdateAppInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.UpdateAppInfoReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("UpdateAppInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("UpdateAppInfo get req:%+v", req) + if req.AppId == "" { + log.Errorf("UpdateAppInfo appId empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("UpdateAppInfo user id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + if len(req.UpInfo.CustomData.SourceFile) == 0 { + log.Errorf("UpdateAppInfo SourceFile empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + err := service.NewAppService().UpdateBuildInfo(traceCtx, c, userId, req) + if err != nil { + log.Errorf("UpdateBuildInfo 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{}) + return +} + +type listAppVersionsReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchText"` + DeveloperId string `form:"developerId"` +} + +/* +?appId=&status=Deleted,InDevelopment&isIncludeStatus=false&pageNo=0&pageSize=10&sort=-publishingStatusLastUpdated&searchFields=&searchText= +*/ + +func DevListAppVersions(c *gin.Context) { + //listAppVersions(c, true, false) + return +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps/sequences-v2?appId=62986e87277a0d00017b782e&pageNo=0&pageSize=100&sort=-sequence&searchFields=&searchText= [C/S]获取小程序审核历史 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId //小程序id + * @apiParam (RequestParam) {string} pageNo //页码 + * @apiParam (RequestParam) {string} pageSize //页大小 + * @apiParam (RequestParam) {string} sort //排序类型 + * @apiParam (RequestParam) {string} searchFields //搜索域 + * @apiParam (RequestParam) {string} searchText //搜索内容 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "list": [ + * { + * "appId": "62986e87277a0d00017b782e", + * "name": "1", + * "appClass": "jinrong", + * "appTag": [ + * "zhengquankaihu" + * ], + * "appType": "Applet", + * "status": { + * "value": "Published", + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "publishingStatus": { + * "reason": "", + * "lastUpdated": 1654156994088, + * "modifiedBy": "15377373355" + * }, + * "unpublishingStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "unpublishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishedStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "unpublishedStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "", + * "type": "" + * }, + * "requestStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "approvalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "actionStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "developerId": "628b2215062d300001e36285", + * "groupId": "628b2215062d300001e36286", + * "created": 1654156994088, + * "createdBy": "15377373355", + * "customData": { + * "detailDescription": "", + * "sourceFile": [ + * { + * "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + * "name": "app.zip", + * "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + * "uploadDate": 1654156973289, + * "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + * "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + * "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + * "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + * "basicPackVer": "", + * "Packages": [], + * "EncryptPackages": [] + * } + * ], + * "versionDescription": "1.0.0", + * "developer": "15377373355" + * }, + * "version": "1.0.0", + * "sequence": 1, + * "corporationId": "", + * "coreDescription": "123", + * "logo": "https://www-cdn.finclip.com/images/ic-default.png", + * "isRollback": false, + * "testInfo": { + * "account": "", + * "password": "", + * "description": "", + * "images": [] + * }, + * "needAutoPub": true, + * "inGrayRelease": false, + * "expire": 0, + * "appBuildID": "62986ead277a0d00017b782f" + * }, + * {...} + * ] + * "total": 100 + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +func NewDevListAppSeqList(c *gin.Context) { + newGetAppVerList(c, "dev") +} + +type AdminListAppSeqListReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchText"` + Type string `form:"type"` + OrganTraceId string `form:"organTraceId"` +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps/audit/list?pageNo=0&pageSize=100&type=pendingReview&organTraceId=24234&searchText= [C/S]获取某个企业小程序列表 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} pageNo //页码 + * @apiParam (RequestParam) {string} pageSize //页大小 + * @apiParam (RequestParam) {string} type //类型,pendingReview:待审核,reviewed:已审核,revoked:已撤销 + * @apiParam (RequestParam) {string} organTraceId //企业id + * @apiParam (RequestParam) {string} searchText //搜索内容 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "list": [ + * { + * "appId": "62986e87277a0d00017b782e", + * "name": "1", + * "appClass": "jinrong", + * "appTag": [ + * "zhengquankaihu" + * ], + * "appType": "Applet", + * "status": { + * "value": "Published", + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "publishingStatus": { + * "reason": "", + * "lastUpdated": 1654156994088, + * "modifiedBy": "15377373355" + * }, + * "unpublishingStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "unpublishingApprovalStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "publishedStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "unpublishedStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "", + * "type": "" + * }, + * "requestStatus": { + * "reason": "", + * "lastUpdated": 0, + * "modifiedBy": "" + * }, + * "approvalStatus": { + * "reason": "", + * "lastUpdated": 1654157465436, + * "modifiedBy": "15377373355" + * }, + * "actionStatus": { + * "reason": "", + * "lastUpdated": 1654157465456, + * "modifiedBy": "自动上架" + * }, + * "developerId": "628b2215062d300001e36285", + * "groupId": "628b2215062d300001e36286", + * "created": 1654156994088, + * "createdBy": "15377373355", + * "customData": { + * "detailDescription": "", + * "sourceFile": [ + * { + * "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + * "name": "app.zip", + * "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + * "uploadDate": 1654156973289, + * "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + * "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + * "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + * "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + * "basicPackVer": "", + * "Packages": [], + * "EncryptPackages": [] + * } + * ], + * "versionDescription": "1.0.0", + * "developer": "15377373355" + * }, + * "version": "1.0.0", + * "sequence": 1, + * "corporationId": "", + * "coreDescription": "123", + * "logo": "https://www-cdn.finclip.com/images/ic-default.png", + * "isRollback": false, + * "testInfo": { + * "account": "", + * "password": "", + * "description": "", + * "images": [] + * }, + * "needAutoPub": true, + * "inGrayRelease": false, + * "expire": 0, + * "appBuildID": "62986ead277a0d00017b782f" + * }, + * {...} + * ] + * "total": 100 + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func AdminListAppSeqList(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminListAppSeqListReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("listAppVersions bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("AdminListAppSeqList req:%+v", req) + req.PageNo += 1 + + total, list, err := service.NewAppService().AdminListAppVer(traceCtx, req.PageNo, req.PageSize, req.SearchText, req.Type, req.OrganTraceId) + if err != nil { + log.Errorf("AdminListAppSeqList err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + c.JSON(http.StatusOK, gin.H{"list": list, "total": total}) +} + +func AdminListAppVersions(c *gin.Context) { + listAppVersions(c, false, true) +} + +func listAppVersions(c *gin.Context, isDev, isAdmin bool) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.ListAppsToBindReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("listAppVersions bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + //queryFilter, sortFilter, searchFilter, pageSize, pageNo, err := GetCommonParam(c) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, err, "Failed to get params", nil) + // return + //} + //if len(sortFilter) == 0 { + // sortFilter = []string{"-created"} + //} + //baseFilter := bson.M{} + //calledByDev := isDev + //operatorID := "" + //if isDev || isAdmin || isClient { + // operatorID = c.Request.Header.Get("x-consumer-custom-id") + //} else if developerID != "" { + // operatorID = developerID + // calledByDev = true + //} + //if calledByDev { + // groupID, err := provider.GetGroupID(traceCtx, c, operatorID) + // if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_GET_GROUP_FAILED, err, operatorID, nil) + // return + // } + // baseFilter = bson.M{ + // "groupId": groupID, + // "sequence": bson.M{"$ne": 0}, + // "status.value": bson.M{"$ne": StDeleted}, + // } + //} else { + // baseFilter = bson.M{ + // "sequence": bson.M{"$ne": 0}, + // "status.value": bson.M{"$ne": StDeleted}, + // } + //} + // + //filter := baseFilter + //if len(searchFilter) > 0 { + // filter = bson.M{"$and": []bson.M{filter, searchFilter}} + //} + //if len(queryFilter) > 0 { + // filter = bson.M{"$and": []bson.M{filter, queryFilter}} + //} + //appVers := make([]model.AppVersion, 0) + //t := db.NewTable(db.TableAppVersion) + //total, err := t.GetSome(traceCtx, filter, sortFilter, pageSize, pageNo, &appVers) + //if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_DB_ERR, err, "Failed to get appVersion", nil) + // return + //} + //c.JSON(http.StatusOK, gin.H{ + // "total": total, + // "list": appVers, + //}) +} + +func newGetAppVerList(c *gin.Context, t string) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + req = apiproto.ListAppVerReq{} + ) + if err := c.BindQuery(&req); err != nil { + log.Errorf("list app ver bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("get app seq req:%+v", req) + if req.PageSize == 0 { + req.PageSize = 100 + } + req.PageNo += 1 + svr := service.NewAppService() + total, appVers, err := svr.ListAppVer(traceCtx, req.AppId, req.PageNo, req.PageSize) + if err != nil { + log.Errorf("ListAppVer err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rsp := make(map[string]interface{}) + rsp["total"] = total + rsp["list"] = appVers + c.JSON(http.StatusOK, rsp) + //utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +type ListAppsInDevelopmentReq struct { + GroupId string `form:"groupId"` +} + +func DevListAppsInDevelopment(c *gin.Context) { + listAppsInDevelopment(c, true, false, false) +} + +func AdminListAppsInDevelopment(c *gin.Context) { + listAppsInDevelopment(c, false, true, false) +} + +func ClientListAppsInDevelopment(c *gin.Context) { + listAppsInDevelopment(c, false, false, true) +} + +func ListAppsInDevelopment(c *gin.Context) { + listAppsInDevelopment(c, false, false, false) +} + +func listAppsInDevelopment(c *gin.Context, isDev, isAdmin, isClient bool) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + + //developerID := c.Query("developerId") + //queryFilter, sortFilter, searchFilter, pageSize, pageNo, err := GetCommonParam(c) + //if err != nil { + // LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, err, "Failed to get param", nil) + // return + //} + //if len(sortFilter) == 0 { + // sortFilter = []string{"-created"} + //} + //baseFilter := bson.M{} + //calledByDev := isDev + //operatorID := "" + //if isDev || isAdmin || isClient { + // operatorID = c.GetHeader("X-Consumer-Custom-Id") + //} else if developerID != "" { + // operatorID = developerID + // calledByDev = true + //} + //if calledByDev { + // groupID, err := provider.GetGroupID(traceCtx, c, operatorID) + // if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_GET_GROUP_FAILED, err, developerID, nil) + // return + // } + // baseFilter = bson.M{ + // "sequence": 0, + // "groupId": groupID, + // "status.value": bson.M{"$ne": StDeleted}, + // } + //} else { + // baseFilter = bson.M{ + // "sequence": 0, + // "status.value": bson.M{"$ne": StDeleted}, + // } + //} + //filter := baseFilter + //if len(searchFilter) > 0 { + // filter = bson.M{"$and": []bson.M{filter, searchFilter}} + //} + //if len(queryFilter) > 0 { + // filter = bson.M{"$and": []bson.M{filter, queryFilter}} + //} + //appVers := make([]model.AppVersion, 0) + //t := db.NewTable(db.TableAppVersion) + //total, err := t.GetSome(traceCtx, filter, sortFilter, pageSize, pageNo, &appVers) + //if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_DB_ERR, err, "Failed to get appVersion", nil) + // return + //} + //c.JSON(http.StatusOK, gin.H{ + // "total": total, + // "list": appVers, + //}) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) +} + +type AdminListIndevlopmentAppsReq struct { + GroupId string `form:"groupId"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` +} + +func AdminListIndevlopmentApps(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := AdminListIndevlopmentAppsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("AdminListApps err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + req.PageNo += 1 + svr := service.NewAppService() + svrReq := service.ListAppsReq{ + GroupId: req.GroupId, + PageNo: req.PageNo, + PageSize: req.PageSize, + } + total, list, err := svr.AdminListApps(traceCtx, &svrReq) + if err != nil { + log.Errorf("AdminListApps err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rspList := []entity.App{} + + for _, v := range list { + if v.Expire == MAX_EXPIRE_DATA { + v.Expire = 0 + } + rspList = append(rspList, v) + } + rspData := make(map[string]interface{}) + rspData["total"] = total + rspData["list"] = rspList + c.JSON(http.StatusOK, rspData) + return +} + +type DevListAppHandReq struct { + PullType string `form:"pullType"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchTxt"` + SortType string `form:"sortType"` +} + +type DevListAppsRspItem struct { + AppId string `json:"appId"` + GroupId string `json:"groupId"` + GroupName string `json:"groupName"` + AppClass string `json:"appClass"` + AppTag []string `json:"appTag"` + Name string `json:"name"` + Created int64 `json:"created"` + Updated int64 `json:"updated"` + Logo string `json:"logo"` + Desc string `json:"desc"` + Status string `json:"status"` + IsForbidden int `json:"isForbidden"` //是否禁用 0:未禁用 1:禁用 +} +type DevListAppsRsp struct { + Total int `json:"total"` + List []DevListAppsRspItem `json:"list"` +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/apps/inDevelopment-v2?pageNo=1&pageSize=10&searchTxt=&sortType=created&pullType=dev-list [C/S]获取小程序开发列表 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} pageNo //页码 + * @apiParam (RequestParam) {string} pageSize //页大小 + * @apiParam (RequestParam) {string} sortType //排序类型 + * @apiParam (RequestParam) {string} pullType //指定类别条件 + * @apiParam (RequestParam) {string} searchTxt //搜索内容 + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "total": 1, + "list": [ + { + "appId": "62986e87277a0d00017b782e", + "groupId": "628b2215062d300001e36286", + "groupName": "个人-15377373355", + "appClass": "jinrong", + "appTag": [ + "zhengquankaihu" + ], + "name": "1", + "created": 1654156935640, + "expire": 0, + "logo": "https://www-cdn.finclip.com/images/ic-default.png", + "desc": "123", + "status": "Published", + "isForbidden": 1 + } + ] + }, + "errcode": "OK", + "error": "" +} + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 +*/ +func DevListAppHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := DevListAppHandReq{} + if err := c.Bind(&req); err != nil { + log.Errorf("DevListAppHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("DevListAppHand req:%+v", req) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("DevListAppHand bind err:%s", "user id empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + accountInfo, err := hCaller.GetGroupInfoByUserId(traceCtx, userId) + if err != nil { + log.Errorf("DevListAppHand GetGroupInfoByUserId err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.PageNo == 0 { + req.PageNo = 1 + } + if req.PageSize == 0 { + req.PageSize = 10 + } + svrReq := service.ListAppsReq{ + PullType: req.PullType, + SortType: req.SortType, + PageNo: req.PageNo, + PageSize: req.PageSize, + SearchText: req.SearchText, + UserId: userId, + IsDev: true, + } + log.Infof("DevListAppHand req:%+v", svrReq) + svr := service.NewAppService() + total, appList, err := svr.DevListApps(traceCtx, &svrReq) + if err != nil { + log.Errorf("DevListAppHand err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + /*licenseInfo, err := hCaller.GetLicense(traceCtx) + if err != nil { + log.Errorf("DevListAppHand GetLicense err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + }*/ + succRspData := DevListAppsRsp{Total: total, List: make([]DevListAppsRspItem, 0)} + for _, v := range appList { + item := DevListAppsRspItem{ + AppId: v.AppID, + GroupId: v.GroupID, + GroupName: accountInfo.GroupName, + AppClass: v.AppClass, + AppTag: v.AppTag, + Name: v.Name, + Created: v.Created, + Updated: v.Status.LastUpdated, + Logo: v.Logo, + Desc: v.CoreDescription, + Status: v.Status.Value, + IsForbidden: v.IsForbidden, + } + //item.Expire = getExpire(item.Expire, licenseInfo.ExpireTime) + succRspData.List = append(succRspData.List, item) + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, succRspData) + return +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/apps/privacy/setting [C/S]保存,更新小程序的隐私配置接口 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} commitType //提交类型 1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况 + * @apiParam (RequestBody) {userMessageType} userMessageType //用户使用类型 + * @apiParam (RequestBody) {[]SdkMessageInfoObj} sdkMessage //sdk信息 + * @apiParam (RequestBody) {contactInfo} contactInfo //联系方式 + * @apiParam (RequestBody) {int} fixedStorageTime //固定存储时间 + * @apiParam (RequestBody) {bool} isShortestTime //是否是最短时间 + * @apiParam (RequestBody) {string} additionalDocName //补充文档名称 + * @apiParam (RequestBody) {string} additionalDocNetDiskId //补充文档网盘id + * @apiParam (RequestBody) {string} additionalDocContent //补充文档内容 + * @apiParamExample {json} Request-Example: + * { + * "appId": "61f4f3ce5d3ef200013d9240", + * "commitType":1, + * "userMessageType": { + * "userMes":"", //用户信息 + * "locationMes":"", //位置信息 + * "microphone":"", //麦克风 + * "camera":"", //摄像头 + * "equipmentMes":"", //设备信息 + * "addressBook":"", //通讯录 + * "photoAlbum":"", //相册 + * "calendar":"", //日历 + * "operationLog":"", //操作日志 + * "bluetooth":"", //蓝牙 + * "others":"", //其他 + * "othersExt":"", //其他 + * }, + * "sdkMessage":[{ + * "name":"SDK名称", //SDK名称 + * "provider":"提供方" //提供方 + * }, + * { + * "name":"名称2", //SDK名称 + * "provider":"提供方2" //提供方 + * }, + * {...} + * ], + * "contactInfo":{ + * "phone":"13033333333", //电话 + * "email":"133@qq.com", //邮箱 + * "other":"其他" //其他 + * }, + * "fixedStorageTime":1, + * "isShortestTime":false, + * "additionalDocName":"文件.txt", + * "additionalDocNetDiskId":"61f4f3ce5d3ef200013d9240" //网盘Id + * "additionalDocContent":"补充内容" //网盘Id + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +func DevPrivacySetting(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.PrivacySettingReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("UpdateAppInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("DevPrivacySetting get req:%+v", req) + if req.AppId == "" { + log.Errorf("DevPrivacySetting appId empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + + err := service.NewAppService().SavePrivacySetting(traceCtx, req) + if err != nil { + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil) + return +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/app/privacy/get/61f4f3ce5d3ef200013d9240 [C/S]获取小程序的隐私配置接口 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId 小程序id + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "errcode": "OK", + * "error": "", + * "data":{ + * "appId": "61f4f3ce5d3ef200013d9240", + * "commitType":1, + * "userMessageType": { + * "userMes":"", //用户信息 + * "locationMes":"", //位置信息 + * "microphone":"", //麦克风 + * "camera":"", //摄像头 + * "equipmentMes":"", //设备信息 + * "addressBook":"", //通讯录 + * "photoAlbum":"", //相册 + * "calendar":"", //日历 + * "operationLog":"", //操作日志 + * "bluetooth":"", //蓝牙 + * "others":"", //其他 + * "othersExt":"", + * }, + * "sdkMessage":[{ + * "name":"SDK名称", //SDK名称 + * "provider":"提供方" //提供方 + * }, + * { + * "name":"名称2", //SDK名称 + * "provider":"提供方2" //提供方 + * }, + * {...} + * ], + * "contactInfo":{ + * "phone":"13033333333", //电话 + * "email":"133@qq.com", //邮箱 + * "other":"其他" //其他 + * }, + * "fixedStorageTime":1, + * "isShortestTime":false, + * "additionalDocName":"文件.txt", + * "additionalDocContent":"111111", + * "additionalDocNetDiskId":"61f4f3ce5d3ef200013d9240" //网盘Id + * "isFirstSave":false, + * "effectiveTime":1657003167000 //生效时间 + * "updateTime":1657003167000 //更新时间 + * } + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func GetPrivacySettingInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetAppInFoByAppId appId id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + result, err := service.NewAppService().GetPrivacySettingInfo(traceCtx, appId) + if err != nil { + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, result) + return +} + +/** + * @api {DELETE} /api/v1/mop/finstore/dev/app/privacy/del/61f4f3ce5d3ef200013d9240 [C/S]删除小程序的隐私配置 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId 小程序id + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "errcode": "OK", + * "error": "", + * "data":{} + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +func DelPrivacySettingInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetAppInFoByAppId appId id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + err := service.NewAppService().DelPrivacySettingInfo(traceCtx, appId) + if err != nil { + log.Errorf("DelPrivacySettingInfo db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil) + return +} + +func InternalGetPrivacySettingInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetAppInFoByAppId appId id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + result, err := service.NewAppService().InternalGetPrivacySettingInfo(traceCtx, appId) + if err != nil { + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{}) + return + } + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, result) + return +} + +func InternalGetAppSearchDataInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetAppInFoByAppId appId id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + result, err := service.NewAppService().InternalGetAppSearchDataInfo(traceCtx, appId) + if err != nil { + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{}) + return + } + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, result) + return +} + +func InternalGetAppInfoBySearchText(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + searchText := c.Query("searchText") + if searchText == "" { + log.Errorf("InternalGetAppInfoBySearchText empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + result, err := service.NewAppService().InternalGetAppInfoBySearchText(traceCtx, searchText) + if err != nil { + log.Errorf("DevGetAppVersion db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, result) + return +} + +func getExpire(ms int64, licenseExp int64) int64 { + if ms == MAX_EXPIRE_DATA { + return 0 + } + //非uat环境取license过期时间 + if !config.Cfg.IsUatEnv() { + return licenseExp + } + return ms +} diff --git a/application/app_build_info.go b/application/app_build_info.go new file mode 100644 index 0000000..72c4932 --- /dev/null +++ b/application/app_build_info.go @@ -0,0 +1,1009 @@ +package application + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +/** +* @api {POST} {{URL_PREFIX}}/apps/builds [C/S][MOP]获取当前app的可审核版本 +* @apiGroup Finclip App Manager +* @apiVersion __API_VERSION__ +* @apiPrivate +* +* @apiParam (RequestBody) {string} [developerId] 开发者id,URL_PREFIX为/api/v1/finstore时填写 +* @apiParam (RequestBody) {string} appId 应用id +* @apiParam (RequestBody) {bool=true,false} needAutoPub=false 审核通过是否自动上架 +* @apiSuccessExample {json} Success-Response: + {} +*/ + +type GetAppBuildsReq struct { + AppId string `form:"appId"` + PageSize int `form:"pageSize"` + PageNo int `form:"pageNo"` +} + +type GetAppBuildsRspItem struct { + Id string `json:"id" bson:"id"` + BuildInfoId string `json:"buildInfoId" bson:"buildInfoId"` + Source string `json:"source" bson:"source"` // 该上传版本的状态: build:正常版本, trail:被设置为体验版 + AppID string `json:"appId" bson:"appId"` + GroupID string `json:"groupId" bson:"groupId"` + Created int64 `json:"created" bson:"created"` //创建该编译版本的时间 + UserId string `json:"userId" bson:"userId"` + CreatedBy string `json:"createdBy" bson:"createdBy"` //创建人 + + CustomData entity.CustomDataInfo `json:"customData" bson:"customData"` + Version string `json:"version" bson:"version"` + StartParams entity.AppStartParams `json:"startParams" bson:"startParams"` + Status bool `json:"status" bson:"status"` + IsSecurityAuditPass int `json:"isSecurityAuditPass" bson:"isSecurityAuditPass"` //安全审核是否通过(0,未通过 1:通过) +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/appInfo/builds?appId=62986ead277a0d00017b782f [C/S]获取编译开发列表 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId //小程序id + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": { + * "appBuilds": [ + * { + * "id": "62986ead277a0d00017b782f", + * "buildInfoId": "ac8f47cf-65a9-43d8-b2ac-34fba808707a", + * "source": "build", + * "appId": "62986e87277a0d00017b782e", + * "groupId": "628b2215062d300001e36286", + * "created": 1654156973289, + * "userId": "628b2215062d300001e36285", + * "createdBy": "15377373355", + * "customData": { + * "detailDescription": "", + * "sourceFile": [ + * { + * "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + * "name": "app.zip", + * "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + * "uploadDate": 1654156973289, + * "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + * "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + * "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + * "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + * "basicPackVer": "", + * "Packages": [], + * "EncryptPackages": [] + * } + * ], + * "versionDescription": "1.0.0", + * "developer": "15377373355" + * }, + * "version": "1.0.0", + * "startParams": { + * "pathAndQuery": "" + * }, + * "status": true + * } + * ], + * "total": 1 + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func GetAppBuilds(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetAppBuildsReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("GetAppBuilds bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + pageNo := c.DefaultQuery("pageNo", "0") + pageSize := c.DefaultQuery("pageSize", "20") //config.GetConfig().CodePackageNumLimit + + pageNoInt, _ := strconv.Atoi(pageNo) + pageNoInt += 1 + pageSizeInt, _ := strconv.Atoi(pageSize) + appId := c.Query("appId") + userId := utility.GetUserId(c) + + log.Infof("GetAppBuilds req:%+v,pageNo:%d,pageSize:%d,userId:%s", req, pageNoInt, pageSizeInt, userId) + + svr := service.NewAppAppletInfoService() + appBuilds, total, err := svr.GetAppBuilds(traceCtx, userId, appId, pageSizeInt, pageNoInt) + if err != nil { + log.Errorf("GetAppBuilds err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + log.Debugf("appBuilds:%+v", appBuilds) + res := make([]GetAppBuildsRspItem, 0) + for _, v := range appBuilds { + item := GetAppBuildsRspItem{ + Id: v.Id, + BuildInfoId: v.BuildInfoId, + Source: v.Source, + AppID: v.AppID, + GroupID: v.GroupID, + Created: v.Created, + UserId: v.UserId, + CreatedBy: v.CreatedBy, + CustomData: entity.CustomDataInfo{ + VersionDescription: v.CustomData.VersionDescription, + SourceFile: v.CustomData.SourceFile, + Developer: v.CustomData.Developer, + }, + Version: v.Version, + + StartParams: entity.AppStartParams{}, + Status: v.Status, + } + if config.GetConfig().IsOpenAuditSecurity { + auditInfo, err := hCaller.GetAuditDataInfoByBuildInfoId(traceCtx, v.BuildInfoId) + log.Debugln("GetAuditDataInfoByBuildInfoId:%v", utility.InterfaceToJsonString(auditInfo)) + if err != nil { + log.Errorf("GetAuditDataInfoByBuildInfoId err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + item.IsSecurityAuditPass = 0 + //0无,1审核中,2通过,3不通过 + if auditInfo.Data.Status == 2 { + item.IsSecurityAuditPass = 1 + } + //0:无 1:审批通过 + if auditInfo.Data.OperOpinion == 1 { + item.IsSecurityAuditPass = 1 + } + } else { + item.IsSecurityAuditPass = 1 + } + + res = append(res, item) + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"appBuilds": res, "total": total}) +} + +type WechatInfoRsp struct { + WechatAppSecret string `json:"wechatAppSecret" bson:"wechatAppSecret"` + WechatAppId string `json:"wechatAppId" bson:"wechatAppId"` + WechatPath string `json:"wechatPath" bson:"wechatPath"` + WechatSize string `json:"wechatSize" bson:"wechatSize"` + QrcodeUrl string `json:"qrcodeUrl" bson:"qrcodeUrl"` + QrcodeDownloadUrl string `json:"qrcodeDownloadUrl" bson:"qrcodeDownloadUrl"` + Updated int64 `json:"updated" bson:"updated"` + ShowHint bool `json:"showHint" bson:"-"` // 是否展示提示 +} + +type GetLatestAppInfoRsp struct { + OnlineAppInfo interface{} `json:"onlineAppInfo"` //线上小程序详情 + ReviewVersion interface{} `json:"reviewVersion"` //最新审核版本信息 + TrialVersion interface{} `json:"trialVersion"` //最新体验版本信息 + ExtInfo map[string]interface{} `json:"extInfo"` //额外数据 extInfo: {trialQrcodeHasRead: true} + WechatInfo interface{} `json:"wechatInfo"` + WechatLoginInfo interface{} `json:"wechatLoginInfo"` +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/appInfo/latest?appId=62986ead277a0d00017b782f [C/S]获取最新线上版、最新审核版本、最新体验版 + * @apiGroup Finclip App Manager + * @apiParam (RequestParam) {string} appId //小程序id + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "onlineAppInfo": { + "appId": "62986e87277a0d00017b782e", + "name": "1", + "appClass": "jinrong", + "appTag": [ + "zhengquankaihu" + ], + "appType": "Applet", + "status": { + "value": "Published", + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "publishingStatus": { + "reason": "", + "lastUpdated": 1654156994088, + "modifiedBy": "15377373355" + }, + "unpublishingStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishingApprovalStatus": { + "reason": "", + "lastUpdated": 1654157465436, + "modifiedBy": "15377373355" + }, + "unpublishingApprovalStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishedStatus": { + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "unpublishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "", + "type": "" + }, + "requestStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "approvalStatus": { + "reason": "", + "lastUpdated": 1654157465436, + "modifiedBy": "15377373355" + }, + "actionStatus": { + "reason": "", + "lastUpdated": 1654157465456, + "modifiedBy": "自动上架" + }, + "developerId": "628b2215062d300001e36285", + "groupId": "628b2215062d300001e36286", + "created": 1654156994088, + "createdBy": "15377373355", + "customData": { + "detailDescription": "", + "sourceFile": [ + { + "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + "name": "app.zip", + "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + "uploadDate": 1654156973289, + "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + "basicPackVer": "", + "Packages": [], + "EncryptPackages": [] + } + ], + "versionDescription": "1.0.0", + "developer": "15377373355" + }, + "version": "1.0.0", + "sequence": 1, + "corporationId": "", + "coreDescription": "123", + "logo": "https://www-cdn.finclip.com/images/ic-default.png", + "isRollback": false, + "testInfo": { + "account": "", + "password": "", + "description": "", + "images": [] + }, + "needAutoPub": true, + "inGrayRelease": false, + "expire": 0, + "appBuildID": "62986ead277a0d00017b782f" + }, + "reviewVersion": { + "appId": "62986e87277a0d00017b782e", + "name": "1", + "appClass": "jinrong", + "appTag": [ + "zhengquankaihu" + ], + "appType": "Applet", + "status": { + "value": "PublishApproved", + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "publishingStatus": { + "reason": "", + "lastUpdated": 1654165260773, + "modifiedBy": "15377373355" + }, + "unpublishingStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishingApprovalStatus": { + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "unpublishingApprovalStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "publishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "unpublishedStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "", + "type": "" + }, + "requestStatus": { + "reason": "", + "lastUpdated": 0, + "modifiedBy": "" + }, + "approvalStatus": { + "reason": "", + "lastUpdated": 1654165268630, + "modifiedBy": "15377373355" + }, + "actionStatus": { + "reason": "", + "lastUpdated": 1654165260773, + "modifiedBy": "15377373355" + }, + "developerId": "628b2215062d300001e36285", + "groupId": "628b2215062d300001e36286", + "created": 1654165260773, + "createdBy": "15377373355", + "customData": { + "detailDescription": "", + "sourceFile": [ + { + "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + "name": "app.zip", + "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + "uploadDate": 1654156973289, + "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + "basicPackVer": "", + "Packages": [], + "EncryptPackages": [] + } + ], + "versionDescription": "1.0.0", + "developer": "15377373355" + }, + "version": "1.0.0", + "sequence": 9, + "corporationId": "", + "coreDescription": "123", + "logo": "https://www-cdn.finclip.com/images/ic-default.png", + "isRollback": false, + "testInfo": { + "account": "", + "password": "", + "description": "", + "images": [] + }, + "needAutoPub": false, + "inGrayRelease": false, + "expire": 0, + "appBuildID": "62986ead277a0d00017b782f" + }, + "trialVersion": {}, + "extInfo": { + "trialQrcodeHasRead": true + }, + "wechatInfo": { + "wechatAppSecret": "", + "wechatAppId": "", + "wechatPath": "", + "wechatSize": "", + "qrcodeUrl": "", + "qrcodeDownloadUrl": "", + "updated": 1654157465456, + "showHint": false + }, + "wechatLoginInfo": { + "wechatOriginId": "", + "profileUrl": "", + "phoneUrl": "" + } + }, + "errcode": "OK", + "error": "" +} + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 +*/ +//GetLatestAppInfo 获取最新线上版、最新审核版本、最新体验版 +func GetLatestAppInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Query("appId") + if appID == "" { + log.Errorf("GetLatestAppInfo appid empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + svr := service.NewAppService() + buildInfoSvr := service.NewAppAppletInfoService() + + developerID := c.Request.Header.Get("X-Consumer-Custom-ID") + groupInfo, _ := hCaller.GetGroupInfoByUserId(traceCtx, developerID) + + app, err := svr.GetAppInfo(traceCtx, appID) + if repository.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND, gin.H{}) + return + } else if groupInfo.GroupID != app.GroupID { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_APPID_ORGANID_ERR, gin.H{}) + return + } + var developer string + if app.CustomData.Developer != "" { + developer = app.CustomData.Developer + } else { + developer = app.CreatedBy + app.CustomData.Developer = developer + } + + rspData := GetLatestAppInfoRsp{ + OnlineAppInfo: gin.H{}, + ReviewVersion: gin.H{}, + TrialVersion: gin.H{}, + ExtInfo: gin.H{}, + } + latestPubVer, err := svr.GetLatestPubAppVer(traceCtx, appID) + if err != nil { + if !repository.NotFound(err) { + log.Errorf("GetLatestAppInfo GetLatestPubAppVer err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + } else { + rspData.OnlineAppInfo = latestPubVer + } + + reviewVersion, err := svr.GetLatestReviewAppVer(traceCtx, appID) + if err != nil { + if !repository.NotFound(err) { + log.Errorf("GetLatestAppInfo GetLatestReviewAppVer err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + } else { + //且没有上、下架的版本 + if reviewVersion.Status.Value != entity.StPublished && reviewVersion.Status.Value != entity.StUnpublished { + rspData.ReviewVersion = reviewVersion + } + } + trialInfo, err := buildInfoSvr.DevGetTrialInfo(traceCtx, appID) + if err != nil { + log.Debugln("GetTrailInfoByAppId err:%s", err.Error()) + if repository.NotFound(err) { + log.Debugln("GetLatestAppInfo DevGetTrialInfo err:%s", err.Error()) + //utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + rspData.TrialVersion = gin.H{} + } else { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + } else { + if trialInfo.CustomData.Developer == "" { + trialInfo.CustomData.Developer = developer + } + rspData.TrialVersion = trialInfo + trialAppQrRedDotHasRead, err := hCaller.IsTrialHasRead(traceCtx, trialInfo.Id, developerID) + if err != nil { + log.Errorf("GetLatestAppInfo IsTrialHasRead err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + log.Debugln("trialQrcodeHasRead :%s", trialAppQrRedDotHasRead) + rspData.ExtInfo["trialQrcodeHasRead"] = trialAppQrRedDotHasRead + } + if trialInfo != nil { + rspData.TrialVersion = trialInfo + } + //extInfo := make(map[string]interface{}) + rspData.ExtInfo["trialQrcodeHasRead"] = true + if trialInfo != nil { + hasRead, _ := hCaller.IsTrialHasRead(traceCtx, trialInfo.Id, utility.GetUserId(c)) + log.Debugln("trialQrcodeHasRead :%s", hasRead) + rspData.ExtInfo["trialQrcodeHasRead"] = hasRead + } + //rspData.ExtInfo = extInfo + wechatInfoRsp := WechatInfoRsp{} + wechatInfo, err := hCaller.GetWeChatInfo(traceCtx, appID) + if err == nil { + wechatInfoRsp.Updated = wechatInfo.Updated + wechatInfoRsp.QrcodeDownloadUrl = wechatInfo.QrcodeDownloadUrl + wechatInfoRsp.QrcodeUrl = wechatInfo.QrcodeUrl + wechatInfoRsp.WechatPath = wechatInfo.WechatPath + wechatInfoRsp.WechatAppId = wechatInfo.WechatAppId + wechatInfoRsp.WechatAppSecret = wechatInfo.WechatAppSecret + wechatInfoRsp.WechatSize = wechatInfo.WechatSize + if wechatInfo.Updated == 0 { + wechatInfoRsp.Updated = app.PublishedStatus.LastUpdated + } + isShowHint, _ := hCaller.IsShowHint(traceCtx, appID, developerID) + wechatInfoRsp.ShowHint = isShowHint + rspData.WechatInfo = wechatInfoRsp + } else { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + } + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(traceCtx, appID) + if err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + } else { + rspData.WechatLoginInfo = wechatLoginInfo + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) +} + +func GetAppAdminAccount(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("appId") + svr := service.NewAppService() + app, err := svr.GetAppInfo(traceCtx, appID) + if err != nil { + if repository.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND, gin.H{}) + } else { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + } + return + } + groupInfo, err := hCaller.GetGroupInfoByGroupId(traceCtx, app.GroupID) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + } else { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"adminAccountId": groupInfo.AdminAccountId, "groupId": groupInfo.GroupID}) + } +} + +type UpdateTrailAppReq struct { + Id string `json:"id"` + AppId string `json:"appId"` + Type string `json:"type"` +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/trial/operate [C/S]添加体验版小程序 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} id //编译id + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} type //add:添加,cancel:取消 + * @apiParamExample {json} Request-Example: + * { + * "id":"61b32654659d2b00016264a9", + * "appId":"61b32654659d2b00016264a8", + * "type": "add" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func UpdateTrialApp(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := UpdateTrailAppReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("UpdateTrialApp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + log.Infof("UpdateTrialApp req:%+v", req) + userId := utility.GetUserId(c) + if req.Id == "" || req.Type == "" || userId == "" { + log.Errorf("UpdateTrialApp req:[%+v] or user id:[%s] err", req, userId) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + + svr := service.NewAppAppletInfoService() + err := svr.UpdateTrialApp(traceCtx, userId, req.Id, req.Type, req.AppId) + if err != nil { + log.Errorf("UpdateTrialApp get info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return + +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/trial/path-query [C/S]更新体验版小程序path + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} traceId //编译id + * @apiParam (RequestBody) {string} pathAndQuery //path + * @apiParamExample {json} Request-Example: + * { + * "traceId":"61b32654659d2b00016264a9", + * "pathAndQuery":"abc" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func UpdateTrialAppPathAndQueryHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.UpdateTrialAppPathReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("UpdateTrialAppPathHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + log.Infof("UpdateTrialAppPathHand req:%+v", req) + if req.TraceId == "" { + log.Errorf("UpdateTrialAppPathHand trace id empty,req:%+v", req) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("UpdateTrialAppPathHand user id empty,req:%+v", req) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + + svr := service.NewAppAppletInfoService() + err := svr.UpdateTrialAppPathAndQueryHand(traceCtx, userId, req.TraceId, req.PathAndQuery) + if err != nil { + log.Errorf("GetTrialInfoById err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} + +/** + * @api {GET} /api/v1/mop/finstore/dev/trial/info?appId=61b32654659d2b00016264a8 [C/S]获取小程序体验版信息 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} traceId //编译id + * @apiParam (RequestBody) {string} pathAndQuery //path + * @apiParamExample {json} Request-Example: + * { + * "traceId":"61b32654659d2b00016264a9", + * "pathAndQuery":"abc" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + { + "data": { + "qrcodeHasRead":true, //二维码是否已读 + "info":{ + "id":"id", + "buildInfoId":"编译id", + "source":"build", //build:正常版本, trail:被设置为体验版 + "appId":"61b32654659d2b00016264a8", + "groupId":"企业id", + "created":1660291974, //创建时间 + "userId":"用户id", + "createdBy":"创建人", + "customData": { + "detailDescription": "", + "sourceFile": [ + { + "fileMd5": "159eed6c06432b1a4f68ced6c19a1bfe", + "name": "app.zip", + "sourceFileUrl": "/api/v1/mop/netdisk/download/62986eaa1f1afd0001c3698c", + "uploadDate": 1654156973289, + "url": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698d", + "encryptedUrl": "/api/v1/mop/netdisk/download/62986ead1f1afd0001c3698e", + "encryptedFileMd5": "fad7bd98dbcabb560ca30f4c99121a42", + "encryptedFileSha256": "c9e9db06725f95a4418c83d54dda3499946b8e1c894583b6477a36cc1d796668", + "basicPackVer": "", + "Packages": [], + "EncryptPackages": [] + } + ], + "versionDescription": "1.0.0", + "developer": "15377373355" + }, + "version":"1.0.0", + "startParams": { + "pathAndQuery": "" + }, + "status":true + } + } + "errcode": "OK", + "error": "" + } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 +*/ +func GetTrialAppInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + + log.Infof("GetTrialAppInfo app id:%+v", appId) + userId := utility.GetUserId(c) + if appId == "" || userId == "" { + log.Errorf("GetTrialAppInfo appId:[%s] or userId:[%s] empty, err", appId, userId) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + + svr := service.NewAppAppletInfoService() + rspData, err := svr.GetTrialAppInfo(traceCtx, userId, appId) + if err != nil { + log.Errorf("GetTrialInfoById err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +// GetBuildAppInfo 获取由编译列表衍生的小程序详情 +//目前包括临时小程序、体验版小程序 +func GetBuildAppInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.GetBuildAppInfoReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("GetBuildAppInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + + sdkKey := utility.GetSdkKey(c) + log.Infof("GetBuildAppInfo req:%+v,sdk key:%s", req, sdkKey) + svr := service.NewAppService() + appInfo, rsp := svr.GetBuildInfo(traceCtx, req, sdkKey) + if appInfo == nil { + rsp.MakeRsp(c, gin.H{}) + } else { + rsp.MakeRsp(c, appInfo) + } + return +} +func GetBuildInfoById(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + t := c.Query("type") + codeId := c.Query("codeId") + if codeId == "" { + log.Errorf("GetBuildInfoById type or code id is empty,t:[%s],code id:[%s]", t, codeId) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + svr := service.NewAppAppletInfoService() + appInfo, err := svr.GetInfoById(traceCtx, codeId) + if err != nil { + log.Errorf("GetInfoById err:%s", err.Error()) + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appInfo) + return +} + +func GetInfoByBuildInfoId(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + buildInfoId := c.Query("buildInfoId") + if buildInfoId == "" { + log.Errorf("GetBuildInfoById type or code id is empty:[%s]", buildInfoId) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + svr := service.NewAppAppletInfoService() + appInfo, err := svr.GetInfoByBuildInfoId(traceCtx, buildInfoId) + if err != nil { + log.Errorf("GetInfoById err:%s", err.Error()) + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appInfo) + return +} + +func GetManageAppList(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + sdkKey := c.GetHeader(entity.SDKKEY_HEADER_KEY) + userId := c.Query("userId") + apiServer := c.Query("apiServer") + + log.Infof("GetManageAppList req sdkKey:[%s],userId:[%s]", sdkKey, userId) + if sdkKey == "" || userId == "" || apiServer == "" { + log.Errorf("GetManageAppList type or appid is nil !") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + svr := service.NewAppAppletInfoService() + rspData, rsp := svr.GetManageAppList(traceCtx, userId, sdkKey, apiServer) + if rspData == nil { + rsp.MakeRsp(c, gin.H{}) + } else { + rsp.MakeRsp(c, rspData) + } + return +} + +func GetManageAppVerList(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + listType := c.Query("listType") + appId := c.Query("appId") + apiServer := c.Query("apiServer") + log.Infof("GetManageAppVerList req appId:[%s],listType:[%s],apiServer:[%s]", appId, listType, apiServer) + if listType == "" || appId == "" { + log.Errorf("GetManageAppVerList type or appid is nil !") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + svr := service.NewAppAppletInfoService() + rspData, rsp := svr.GetManageAppVerList(traceCtx, listType, appId, apiServer) + if rspData == nil { + rsp.MakeRsp(c, gin.H{}) + } else { + rsp.MakeRsp(c, rspData) + } + return +} + +func FixDevListStatus(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + svr := service.NewAppAppletInfoService() + rsp := svr.FixDevListStatus(traceCtx) + + rsp.MakeRsp(c, gin.H{}) + + return +} + +type GenOfflinePackageInfoHandReq struct { + AppId string `json:"appId"` + Sequence int `json:"seq"` +} + +/** + * @api {POST} /api/v1/mop/finstore/dev/package/offline [C/S]生成离线包下载信息 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {int} seq //小程序序列号 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "seq": 1, + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": { + * "netdiskId":"61b32654659d2b00016264a9" //网盘id + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +//GenOfflinePackageInfoHand 离线包下载信息获取 +func GenOfflinePackageInfoHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("user id empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + req := GenOfflinePackageInfoHandReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("GenOfflinePackageInfoHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + log.Infof("GenOfflinePackageInfoHand req:%v", req) + svr := service.NewAppService() + fileId, err := svr.GenOfflinePackageInfo(traceCtx, req.AppId, req.Sequence, userId) + if err != nil { + log.Errorf("app ver service gen offline package err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + //todo test + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"netdiskId": fileId}) +} + +type GetBindingIdBySdkKeyHandReq struct { + SdkKey string `form:"sdkKey"` + AppId string `form:"appId"` + OrganId string `form:"organId"` +} + +func GetBindingIdBySdkKeyHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetBindingIdBySdkKeyHandReq{} + if err := c.Bind(&req); err != nil { + log.Errorf("GetBindingIdBySdkKeyHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.SdkKey == "" { + log.Errorf("GetBindingIdBySdkKeyHand sdk key empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, gin.H{}) + return + } + + log.Debugf("GetBindingIdBySdkKeyHand sdkkey=%s, appId=%s", req.SdkKey, req.AppId) + + svr := service.NewBindingService() + info, err := svr.GetBindInfoByParam(traceCtx, req.SdkKey, req.OrganId, req.AppId) + if err != nil { + log.Errorf("GetBindingIdBySdkKeyHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVICE_UNAVAILABLE, gin.H{}) + return + } + rspData := gin.H{ + "bindingId": info.BindingID, + "owner": info.Owner, + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +func GetBindingInfoBySdkKeyHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetBindingIdBySdkKeyHandReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("GetBindingInfoBySdkKeyHand ShouldBindJSON err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, make(map[string]interface{})) + return + } + if req.SdkKey == "" { + log.Errorf("GetBindingIdBySdkKeyHand sdk key empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, gin.H{}) + return + } + + log.Debugf("GetBindingIdBySdkKeyHand sdkkey=%s, appId=%s", req.SdkKey) + + svr := service.NewBindingService() + info, err := svr.GetBindingBySdkKey(traceCtx, req.SdkKey) + if err != nil { + log.Errorf("GetBindingIdBySdkKeyHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVICE_UNAVAILABLE, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, info) + return +} diff --git a/application/app_config.go b/application/app_config.go new file mode 100644 index 0000000..4e36422 --- /dev/null +++ b/application/app_config.go @@ -0,0 +1,78 @@ +package application + +import ( + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/logger" + "finclip-app-manager/infrastructure/utility" + "net/http" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +/** +* @api {GET} /api/v1/mop/finstore/admin/app-oper-conifg/info [C/S]运营端获取小程序操作配置相关信息 +* @apiGroup Finclip App Manager +* @apiVersion __API_VERSION__ +* @apiSuccessExample {json} Success Status: +* HTTP/1.1 200 OK +* { +* "errcode": "OK", +* "error": "", +* "data":{ +* "autoReviewApp":1 //1代表打开,0代表关闭 +* } +* } +* @apiErrorExample Error Status: +* HTTP/1.1 !=200 服务端异常 + */ + +func QueryAppOperConfig(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + + s := service.NewAppConfigService() + rsp, errStr := s.GetOperConfig(traceCtx) + if errStr != utility.OK { + utility.MakeLocRsp(c, http.StatusOK, errStr, nil) + return + } else { + utility.MakeLocRsp(c, http.StatusOK, errStr, rsp) + return + } +} + +/** +* @api {POST} /api/v1/mop/finstore/admin/app-oper-conifg/update [C/S]运营端更新小程序操作配置相关信息 +* @apiGroup Finclip App Manager +* @apiVersion __API_VERSION__ +* @apiParam (RequestBody) {int} autoReviewApp 是否打开自动审核小程序 +* @apiParamExample {json} Request-Example: +* { +* "autoReviewApp": 1 +* } +* @apiSuccessExample {json} Success Status: +* HTTP/1.1 200 OK +* { +* "errcode": "OK", +* "error": "", +* "data":{} +* } +* @apiErrorExample Error Status: +* HTTP/1.1 !=200 服务端异常 + */ + +func UpdateAppOperConfig(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + + var req service.UpdateAppOperCofigReq + if err := c.BindJSON(&req); err != nil { + logger.GetLogger().Errorf("UpdateAppOperConfig bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + + s := service.NewAppConfigService() + errStr, errCode := s.UpdateAppOperCofig(traceCtx, req) + utility.MakeLocRsp(c, errCode, errStr, nil) + return +} diff --git a/application/app_internal.go b/application/app_internal.go new file mode 100644 index 0000000..665e03c --- /dev/null +++ b/application/app_internal.go @@ -0,0 +1,829 @@ +package application + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" + "strconv" + "strings" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +type InternalGetAppVerInfoRsp struct { + AppID string `json:"appId"` + Name string `json:"name"` + Sequence int `json:"sequence"` + AppClass string `json:"appClass"` + AppType string `json:"appType"` + Status entity.Status `json:"status"` + PublishedStatus entity.SpecificStatus `json:"publishedStatus"` + UnpublishedStatus entity.SpecificStatus `json:"unpublishedStatus"` + ActionStatus entity.SpecificStatus `json:"actionStatus"` + DeveloperID string `json:"developerId"` + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + Created int64 `json:"created"` + CreatedBy string `json:"createdBy"` + CustomData entity.CustomDataInfo `json:"customData"` + Version string `json:"version"` + CorporationID string `json:"corporationId"` + CoreDescription string `json:"coreDescription"` + Logo string `json:"logo"` +} + +func InternalGetAppVerInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + seqStr := c.Param("sequence") + SDKKey := c.GetHeader(utility.SDK_KEY_SIGNAL) + sdkVer := c.GetHeader(utility.SDKKEY_VER_HEADER_KEY) + log.Infof("InternalGetAppVerInfo req appId:%s,seq:%s,sdk-key:%s,sdk-ver:%s", appId, seqStr, SDKKey, sdkVer) + if appId == "" { + log.Errorf("InternalGetAppVerInfo appId empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + if SDKKey == "" { + log.Errorf("InternalGetAppVerInfo sdk-key empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_SDKKEY, gin.H{}) + return + } + //sdkKey白名单的校验 + if !utility.InArry(SDKKey, config.WhiteSDKArry) { + if config.Cfg.PublishEnv == entity.ENV_PRIVATE { + svr := service.NewBindingService() + checkStatus := svr.CheckReviewBySdkKey(traceCtx, SDKKey) + if checkStatus != utility.OK { + log.Errorf("RuntimeGetAppVersionInfo sdk not in reviewlist,sdk-key:%s", SDKKey) + utility.MakeLocRsp(c, http.StatusForbidden, checkStatus, gin.H{}) + return + } + } else { + log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", SDKKey) + utility.MakeLocRsp(c, http.StatusForbidden, utility.FS_COOPERATION_TERMINATED, gin.H{}) + return + } + } + sequence, err := strconv.Atoi(seqStr) + if err != nil { + log.Errorf("InternalGetAppVerInfo sequence format err,seq:%s,err:%s", seqStr, err.Error()) + utility.MakeLocRsp(c, http.StatusForbidden, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewAppService() + data, rsp := svr.OpenApiGetAppVerInfo(traceCtx, appId, sequence, sdkVer) + log.Infof("OpenApiGetAppVerInfo rsp data:%+v,info:%+v", data, rsp) + if rsp.ErrCode != utility.OK { + rsp.MakeRsp(c, gin.H{}) + } else { + data.GroupName = ChangeGroupName(data.GroupName) + rsp.MakeRsp(c, data) + } + return +} + +func ChangeGroupName(groupName string) string { + if len(groupName) == 18 && strings.Contains(groupName, "个人-") { + phone := groupName[7:] + if isOK := utility.IsMobile(phone); isOK { + newName := "个人-" + for i := 0; i < len(phone); i++ { + if i >= 3 && i <= 6 { + newName += "*" + } else { + newName += string(phone[i]) + } + } + + groupName = newName + } + } + + return groupName +} + +type GetGroupIdByAppIdRspData struct { + GroupId string `json:"groupId"` + AppName string `json:"appName"` +} +type GetGroupIdByAppIdRsp struct { + Data GetGroupIdByAppIdRspData `json:"data"` + Errcode string `json:"errcode"` + Errmsg string `json:"error"` +} + +func GetGroupIdByAppId(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("appId") + if appID == "" { + log.Errorf("GetGroupIdByAppId app id empty!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + log.Infof("GetGroupIdByAppId req appId:%s", appID) + app, err := service.NewAppService().GetAppInfoByAppId(traceCtx, appID) + if err != nil { + log.Errorf("GetGroupIdByAppId db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rspData := GetGroupIdByAppIdRsp{} + rspData.Data.GroupId = app.GroupID + rspData.Data.AppName = app.Name + rspData.Errmsg = "" + rspData.Errmsg = "OK" + c.JSON(http.StatusOK, rspData) +} + +type GetRuleEngineVerPubListRspItem struct { + Version int `json:"version"` + VersionStr string `json:"versionStr"` +} + +type VerToDescItem struct { + Version int `json:"version"` + Desc string `json:"desc"` +} +type GetRuleEngineVerPubListRsp struct { + VerList []GetRuleEngineVerPubListRspItem `json:"verList"` //大于等于MaxPubVer的序列号列表 + NowPubVer GetRuleEngineVerPubListRspItem `json:"nowPubVer"` //当前上架版本 + MaxPubVer GetRuleEngineVerPubListRspItem `json:"maxPubVer"` //已发布、已下架、审核通过三种状态里面的最大版本号 + VerToDesc []VerToDescItem `json:"verToDesc"` //序列号到版本描述的映射 +} + +func GetRuleEngineVerPubList(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + if appId == "" { + log.Errorf("GetRuleEngineVerPubList app id empty !") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_APP_ID_NOT_FOUND, gin.H{}) + return + } + log.Infof("GetRuleEngineVerPubList appId:%s", appId) + svr := service.NewAppService() + data, rsp := svr.GetRuleEngineVerPubList(traceCtx, appId) + rsp.MakeRsp(c, data) + return + +} + +func RuleEngineGetAppInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("appId") + if appID == "" { + log.Infof("RuleEngineGetAppInfo appId empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + sdkKey := c.GetHeader(utility.SDK_KEY_SIGNAL) + sdkVer := c.GetHeader(utility.SDKKEY_VER_HEADER_KEY) + log.Infof("RuleEngineGetAppInfo req appId:%s sdkKey:%s sdkver:%s", appID, sdkKey, sdkVer) + svr := service.NewAppService() + data, rsp := svr.RuntimeGetPubAppInfo(traceCtx, sdkKey, appID, sdkVer) + if rsp.ErrCode != utility.OK { + rsp.MakeRsp(c, gin.H{}) + } else { + rsp.MakeRsp(c, data) + } +} + +func RuleEngineGetAppVerInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Param("appId") + seqStr := c.Param("version") + log.Infof("RuleEngineGetAppVerInfo req appId:%s,seq:%s", appId, seqStr) + if appId == "" { + log.Errorf("RuleEngineGetAppVerInfo appId empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + sequence, err := strconv.Atoi(seqStr) + if err != nil { + log.Errorf("RuleEngineGetAppVerInfo sequence format err,seq:%s,err:%s", seqStr, err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + sdkKey := c.GetHeader(utility.SDK_KEY_SIGNAL) + if sdkKey == "" { + log.Errorf("RuleEngineGetAppVerInfo sdk key empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, gin.H{}) + return + } + sdkVer := c.GetHeader(utility.SDKKEY_VER_HEADER_KEY) + svr := service.NewAppService() + data, rsp := svr.RuleEngineGetAppVerInfo(traceCtx, appId, sequence, sdkKey, sdkVer) + if rsp.ErrCode != utility.OK { + rsp.MakeRsp(c, gin.H{}) + } else { + rsp.MakeRsp(c, data) + } +} + +type GrayNotifyAppReq struct { + AppId string `json:"appId"` + Version int `json:"version"` + Status bool `json:"status"` +} + +func GrayNotifyApp(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GrayNotifyAppReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("GrayNotifyApp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + err := service.NewAppService().UpdateGrayPubStatus(traceCtx, req.AppId, req.Version, req.Status) + if err != nil { + log.Errorf("GrayNotifyApp db 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{}) + return +} + +type GetPubVerListRspItem struct { + AppID string `json:"appId" bson:"appId"` + Name string `json:"name" bson:"name"` + Version string `json:"version" bson:"version"` + Sequence int `json:"sequence" bson:"sequence"` + AppBuildID string `json:"appBuildID" bson:"appBuildID"` + AppBuildInfoId string `json:"buildInfoId" bson:"buildInfoId"` + StartParams entity.AppStartParams `json:"startParams"` + WechatInfo WechatInfoRsp `json:"wechatInfo" bson:"wechatInfo"` +} + +func GetAppVerBuildInfos(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + + if appId == "" { + log.Errorf("appId is empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + log.Infof("get app ver build info req appid:[%s]", appId) + svr := service.NewAppService() + appInfo, err := svr.GetAppInfoByAppId(traceCtx, appId) + if err != nil { + log.Errorf("GetAppVerBuildInfos db err:%s", err.Error()) + if service.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + buildSvr := service.NewAppAppletInfoService() + trialResult, err := buildSvr.GetTrialInfoByAppId(traceCtx, appId) + if err != nil && !service.NotFound(err) { + log.Errorf("GetTrialInfoByAppId db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + log.Debugf("trialResult data:", trialResult) + + appSvr := service.NewAppService() + publishedList, _, err := appSvr.GetAllPublishedVerList(traceCtx, appId) + if err != nil { + log.Errorf("GetAllPublishedVerList err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + var pubResult []GetPubVerListRspItem + for _, v := range publishedList { + pubItem := GetPubVerListRspItem{} + if len(v.AppBuildID) > 0 { + buildInfo := &entity.AppBuildInfo{} + buildInfo, err = buildSvr.GetInfoById(traceCtx, v.AppBuildID) + if err != nil { + log.Infof("GetInfoById err:%s", err.Error()) + buildInfo, err = buildSvr.GetInfoByBuildInfoId(traceCtx, v.AppBuildID) + if err != nil { + log.Infof("GetInfoByBuildInfoId err:%s", err.Error()) + } + } else { + pubItem.AppID = v.AppID + pubItem.AppBuildID = v.AppBuildID + pubItem.AppBuildInfoId = buildInfo.BuildInfoId + pubItem.Sequence = v.Sequence + pubItem.Version = v.Version + pubItem.Name = v.Name + pubItem.StartParams = buildInfo.StartParams + } + wechatInfo, err := hCaller.GetWeChatInfo(traceCtx, appId) + if err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + if wechatInfo.Updated == 0 { + wechatInfo.Updated = appInfo.PublishedStatus.LastUpdated + } + pubItem.WechatInfo = WechatInfoRsp{ + WechatAppSecret: wechatInfo.WechatAppSecret, + WechatAppId: wechatInfo.WechatAppId, + WechatPath: wechatInfo.WechatPath, + WechatSize: wechatInfo.WechatSize, + QrcodeUrl: wechatInfo.QrcodeUrl, + QrcodeDownloadUrl: wechatInfo.QrcodeDownloadUrl, + Updated: wechatInfo.Updated, + //ShowHint:wechatInfo.ShowHint, + } + pubResult = append(pubResult, pubItem) + } + } + log.Debugf("pubResult data:", pubResult) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"trialVer": trialResult, "pubVer": pubResult}) + return +} + +type GetGrayStatisticsVerListReq struct { + AppId string `form:"appId"` + Version int `form:"version"` + BeginTime int64 `form:"begin_time"` + EndTime int64 `form:"end_time"` +} + +func GetGrayStatisticsVerList(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetGrayStatisticsVerListReq{} + if err := c.Bind(&req); err != nil { + log.Errorf("GetGrayStatisticsVerList req bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("GetGrayStatisticsVerList req:%+v", req) + svr := service.NewAppService() + data, rsp := svr.GetGrayStatisticsVerList(traceCtx, req.AppId, req.Version, req.BeginTime, req.EndTime) + if rsp.ErrCode == utility.OK { + rsp.MakeRsp(c, data) + } else { + rsp.MakeRsp(c, gin.H{}) + } + return +} + +type RuleEngineBatchGetAppReq struct { + SdkKey string `json:"sdkKey"` + SdkVer string `json:"sdkVer"` + AppList []string `json:"appList"` + AppVerList []struct { + AppId string `json:"appId"` + Sequence int `json:"sequence"` + } `json:"appVerList"` +} +type RuleEngineBatchGetAppRsp struct { + AppFailList []string `json:"appFailList"` + AppVerFailList []string `json:"appVerFailList"` + AppDataList []interface{} `json:"appDataList"` + AppVerDataList []interface{} `json:"appVerDataList"` +} + +func RuleEngineBatchGetApp(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := RuleEngineBatchGetAppReq{} + rsp := RuleEngineBatchGetAppRsp{} + rsp.AppFailList = make([]string, 0) + rsp.AppVerFailList = make([]string, 0) + rsp.AppDataList = make([]interface{}, 0) + rsp.AppVerDataList = make([]interface{}, 0) + if err := c.BindJSON(&req); err != nil { + log.Errorf("RuleEngineBatchGetApp bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("http RuleEngineBatchGetApp req:%+v", req) + //首先获取小程序详情 + rs := service.NewAppService() + for _, appId := range req.AppList { + data, tempRsp := rs.RuntimeGetPubAppInfo(traceCtx, req.SdkKey, appId, req.SdkVer) + if tempRsp.ErrCode != utility.OK { + log.Errorf("RuleEngineBatchGetApp get info data:%v,resp:%+v", data, tempRsp) + rsp.AppFailList = append(rsp.AppFailList, appId) + continue + } + log.Debugf("RuleEngineBatchGetApp info:%+v", data.CustomData.SourceFile) + log.Infof("http RuleEngineBatchGetApp info:", utility.InterfaceToJsonString(data)) + rsp.AppDataList = append(rsp.AppDataList, data) + } + //获取小程序版本详情 + for _, appVer := range req.AppVerList { + rspData, tempRsp := rs.RuleEngineGetAppVerInfo(traceCtx, appVer.AppId, appVer.Sequence, req.SdkKey, req.SdkVer) + if tempRsp.ErrCode != utility.OK { + rsp.AppVerFailList = append(rsp.AppVerFailList, appVer.AppId) + continue + } + rsp.AppVerDataList = append(rsp.AppVerDataList, rspData) + } + log.Infof("http RuleEngineBatchGetApp resp:", utility.InterfaceToJsonString(rsp)) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) + return +} + +func GetAppTagAndClassification(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + + svr := service.NewAppService() + appClassList, err := svr.GetAppClassList(traceCtx) + + if err != nil { + log.Debugf("GetAppTagAndClassification err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + + appTagList, err := svr.GetAppTagList(traceCtx) + if err != nil { + log.Debugf("GetAppTagAndClassification err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + + c.JSON(http.StatusOK, gin.H{"appTag": appTagList, "appClass": appClassList}) +} + +/** + * @api {PUT} /api/v1/mop/finstore/update-expire/:type/:businessId [S/S][MOP]更新小程序过期时间 + * @apiGroup Finclip App Manager + * @apiVersion __API_VERSION__ + * + * @apiParam {string=app,binding} type 更新类型-app:小程序,binding:应用 + * @apiParam {string=app,binding} businessId 业务Id(小程序Id或应用Id) + * @apiParam (RequestBody) {Number} expire 到期时间,单位/ms + * @apiParamExample {json} Request-Example: + * /api/v1/finstore/update-expire/app/5edf44b56ef940000153c3f7 + * { + * "expire":1596445961000, + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +//支付系统同步过期信息到应用市场 +func UpdateExpireInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.UpdateExpireInfoReq{} + rsp := make(map[string]interface{}) + if err := c.BindJSON(&req); err != nil { + log.Errorf("UpdateExpireInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp) + return + } + upType := c.Param("type") + bussId := c.Param("businessId") + if upType == "" || bussId == "" { + log.Errorf("UpdateExpireInfo param err:%s", "type or businessId empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp) + return + } + log.Infof("NotifySyncInfoHand req,upType:%s,buss id:%s,expire:%d", upType, bussId, req.Expire) + if req.Expire == 0 { + req.Expire = service.MAX_EXPIRE_DATA + } + svrRsp := &utility.SvrRsp{} + switch upType { + case "app": + appSvr := service.NewAppService() + svrRsp = appSvr.UpExpire(traceCtx, bussId, req.Expire) + case "binding": + bindSvr := service.NewBindingService() + svrRsp = bindSvr.UpExpire(traceCtx, bussId, req.Expire) + default: + log.Errorf("UpdateExpireInfo up type err:%s,up type:%s", "up type err", upType) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rsp) + return + } + svrRsp.MakeRsp(c, rsp) + return +} + +//根据小程序包标识符(md5、sha256)进行小程序信息的获取 +func BatchAppsByIdentity(c *gin.Context) { + var ( + req = apiproto.BatchAppsByIdentityReq{} + traceCtx = apm.ApmClient().TraceContextFromGin(c) + ) + if err := c.BindJSON(&req); err != nil { + log.Errorf("bind para err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if len(req.Apps) == 0 { + log.Errorf("BatchAppsByIdentity apps empty ...") + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return + } + req.IdentityType = strings.ToLower(req.IdentityType) + + sdkKey := c.GetHeader(utility.SDK_KEY_SIGNAL) + + log.Infof("BatchAppsByIdentity req:%+v", req) + + svr := service.NewAppService() + rsp := svr.BatchAppsByIdentity(traceCtx, sdkKey, &req) + + utility.MakeLocRsp(c, int(rsp.GetResult().Httpcode), rsp.GetResult().Errcode, rsp.GetData()) + return +} + +//根据小程序包标识符(md5、sha256)获取小程序包是否合法 +func IdentityAppsCheck(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + req = apiproto.IdentityAppsCheckReq{} + ) + if err := c.BindJSON(&req); err != nil { + log.Errorf("bind para err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + if len(req.Apps) == 0 { + log.Errorf("IdentityAppsCheck apps empty ...") + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return + } + sdk := c.GetHeader(utility.SDK_KEY_SIGNAL) + log.Debugf("IdentityAppsCheck req:%+v", req) + svr := service.NewAppService() + rsp := svr.IdentityAppsCheck(traceCtx, sdk, &req) + //todo 处理nil + utility.MakeLocRsp(c, int(rsp.GetResult().Httpcode), rsp.GetResult().Errcode, rsp.GetData()) + return +} + +//根据sdkKey获取关联的应用 +//再根据关联的应用获取所有的小程序 +type GetAppListBySdkKeyHandReq struct { + BindingId string `form:"bindingId"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` +} + +type GetAppListBySdkKeyHandRspItem struct { + AppId string `bson:"appId" json:"appId"` + Name string `bson:"name" json:"name"` + Logo string `bson:"logo" json:"logo"` + Sequence int `bson:"sequence" json:"sequence"` +} + +type GetAppListBySdkKeyHandRsp struct { + Total int `json:"total"` + List []GetAppListBySdkKeyHandRspItem `json:"list"` +} + +func GetAppListByBindIdHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetAppListBySdkKeyHandReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("GetAppListBySdkKeyHand bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("GetAppListByBindIdHand req:%+v", req) + if req.BindingId == "" { + log.Errorf("GetAppListBySdkKeyHand binding id empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BINDINGID_NOT, gin.H{}) + return + } + + if req.PageNo <= 0 { + req.PageNo = 1 + } + if req.PageSize >= 100 || req.PageSize <= 0 { + req.PageSize = 100 + } + svr := service.NewAppService() + total, apps, err := svr.GetLinkAppsByBindingID(traceCtx, req.BindingId, req.PageNo, req.PageSize, "") + if err != nil { + log.Errorf("GetLinkAppsByBindingID err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rsp := GetAppListBySdkKeyHandRsp{ + Total: total, + List: make([]GetAppListBySdkKeyHandRspItem, 0), + } + for _, v := range apps { + item := GetAppListBySdkKeyHandRspItem{ + AppId: v.AppID, + Name: v.Name, + Logo: v.Logo, + Sequence: v.Sequence, + } + rsp.List = append(rsp.List, item) + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +type GetAppListBySdkKeyReq struct { + SDKKey string `form:"sdkKey"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` +} + +type GetAppBySDKKeyRspItem struct { + AppId string `bson:"appId" json:"appId"` + Name string `bson:"name" json:"name"` + Logo string `bson:"logo" json:"logo"` + AppTag []string `bson:"appTag" json:"appTag"` + AppClass string `bson:"appClass" json:"appClass"` + CoreDescription string `bson:"coreDescription" json:"coreDescription"` + SourceFileUrl string `bson:"sourceFileUrl" json:"sourceFileUrl"` +} + +type GetAppBySDKKeyRsp struct { + Total int `json:"total"` + List []GetAppBySDKKeyRspItem `json:"list"` +} + +func GetAppBySDKKey(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetAppListBySdkKeyReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("GetAppBySDKKey bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + log.Infof("GetAppBySDKKey req:%+v", req) + if req.SDKKey == "" { + log.Errorf("GetAppListBySdkKeyHand sdkKey empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SDKKEY_NOT, gin.H{}) + return + } + + if req.PageSize >= 100 || req.PageSize <= 0 { + req.PageSize = 100 + } + svr := service.NewAppService() + total, apps, err := svr.GetLinkAppsBySDKKey(traceCtx, req.SDKKey, req.PageNo, req.PageSize) + if err != nil { + log.Errorf("GetAppBySDKKey err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + rsp := GetAppBySDKKeyRsp{ + Total: total, + List: make([]GetAppBySDKKeyRspItem, 0), + } + for _, v := range apps { + latestVersion, _ := svr.GetLatestPubAppVer(traceCtx, v.AppID) + + item := GetAppBySDKKeyRspItem{ + AppId: v.AppID, + Name: v.Name, + Logo: v.Logo, + AppTag: v.AppTag, + AppClass: v.AppClass, + CoreDescription: v.CoreDescription, + SourceFileUrl: latestVersion.CustomData.SourceFile[0].SourceFileUrl, + } + rsp.List = append(rsp.List, item) + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +type GetAppsInfoByListHandReq struct { + AppIdList string `form:"list"` //用逗号分隔 +} +type GetAppsInfoByListHandRspItem struct { + AppId string `json:"appId"` + Name string `json:"name"` + Logo string `json:"logo"` + Desc string `json:"desc"` + GroupId string `json:"groupId"` +} +type GetAppsInfoByListHandRsp struct { + List []GetAppsInfoByListHandRspItem `json:"list"` +} + +func GetAppsInfoByListHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := GetAppsInfoByListHandReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("GetAppsInfoByListHand bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + appIdList := strings.Split(req.AppIdList, ",") + if len(appIdList) == 0 { + log.Errorf("GetAppsInfoByListHand appId list zero") + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return + } + log.Infof("GetAppsInfoByListHand req:%+v", req) + svr := service.NewAppService() + apps, err := svr.GetAppsByAppIds(traceCtx, appIdList) + if err != nil { + log.Errorf("GetAppsByAppIds err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + log.Infof("get result:%+v", apps) + rsp := GetAppsInfoByListHandRsp{ + List: make([]GetAppsInfoByListHandRspItem, 0), + } + for _, v := range apps { + item := GetAppsInfoByListHandRspItem{} + item.AppId = v.AppID + item.Name = v.Name + item.Logo = v.Logo + item.Desc = v.CoreDescription + item.GroupId = v.GroupID + rsp.List = append(rsp.List, item) + } + log.Infof("get rsp:%+v", rsp) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +type SearchAppHandReq struct { + SearchTxt string `form:"searchTxt"` + BindingId string `form:"bindingId"` + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` +} +type SearchAppHandRspItem struct { + AppId string `bson:"appId" json:"appId"` + Name string `bson:"name" json:"name"` + Logo string `bson:"logo" json:"logo"` + Desc string `bson:"desc" json:"desc"` + Sequence int `bson:"sequence" json:"sequence"` +} +type SearchAppHandRsp struct { + Total int `json:"total"` + List []SearchAppHandRspItem `json:"list"` +} + +//搜索应用已经上架的小程序信息 +func SearchAppHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := SearchAppHandReq{} + if err := c.BindQuery(&req); err != nil { + log.Errorf("SearchAppHand bind error:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.BindingId == "" { + log.Errorf("SearchAppHand binding id empty") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BINDINGID_NOT, gin.H{}) + return + } + if req.PageNo <= 0 { + req.PageNo = 1 + } + if req.PageSize >= 100 || req.PageSize <= 0 { + req.PageSize = 100 + } + rsp := SearchAppHandRsp{ + Total: 0, + List: make([]SearchAppHandRspItem, 0), + } + svr := service.NewAppService() + total, apps, err := svr.GetLinkAppsByBindingID(traceCtx, req.BindingId, req.PageNo, req.PageSize, req.SearchTxt) + if err != nil { + log.Errorf("GetLinkAppsByBindingID err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusIMUsed, utility.FS_DB_ERR, gin.H{}) + return + } + rsp.Total = total + for _, v := range apps { + item := SearchAppHandRspItem{ + AppId: v.AppID, + Name: v.Name, + Logo: v.Logo, + Desc: v.CoreDescription, + Sequence: v.Sequence, + } + rsp.List = append(rsp.List, item) + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rsp) +} + +//账号系统同步信息到应用市场 +type NotifySyncInfoHandReq struct { + TraceId string `json:"traceId"` + SubId string `json:"subId"` + Type string `json:"type"` + Data map[string]interface{} `json:"data"` +} + +func NotifySyncInfoHand(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := NotifySyncInfoHandReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("NotifySyncInfoHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + //log.Infof("NotifySyncInfoHand req:%+v", req) + //svr := service.NewNotifySyncInfoService() + //httpCode, errcode := svr.NotifySyncInfo(traceCtx, req.TraceId, req.SubId, req.Type, req.Data) + //common.MakeRsp(c, httpCode, errcode, rsp) + return +} diff --git a/application/app_runtime.go b/application/app_runtime.go new file mode 100644 index 0000000..7c8bbb1 --- /dev/null +++ b/application/app_runtime.go @@ -0,0 +1,207 @@ +package application + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/utility" + "github.com/gin-gonic/gin" + "net/http" +) + +func RuntimeGetAppInfo(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("path1") //appId + if appID == "" { + log.Infof("RuntimeGetAppInfo appId empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + //key := c.Request.Header.Get("SDK-Key") + ////安全校验 + //err := CheckSignatureAuth(traceCtx, key, c) + //if err != nil { + // log.Infof("RuntimeGetAppInfo CheckSignatureAuth err:%s", err.Error()) + // MakeRsp(c, http.StatusBadRequest, err.Error(), rsp) + // return + //} + //rs := service.NewRuntimeService() + //resp, err := rs.GetAppInfo(traceCtx, key, appID, "") + //if err != nil { + // log.Errorf("GetGrayAppInfo get info from cache err:%s", err.Error()) + // MakeRsp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, rsp) + // return + //} + //if resp == nil { + // log.Warnf("GetGrayAppInfo app info is nil !!!") + // if rs.AppNotFound() { + // log.Errorf("GetGrayAppInfo get info app id Not Found,appId:%s", appID) + // MakeRsp(c, http.StatusNotFound, FS_APP_ID_NOT_FOUND, rsp) + // return + // } + // if !rs.AppStatusValid() { + // log.Errorf("GetGrayAppInfo get info app status invalid,appId:%s", appID) + // MakeRsp(c, http.StatusForbidden, FS_SERVICE_UNAVAILABLE, rsp) + // return + // } + // if !rs.PayAppIdStatusOk() { + // log.Errorf("GetGrayAppInfo get info app pay status invaild,appId:%s", appID) + // MakeRsp(c, http.StatusForbidden, FS_APP_PAY_EXPIRE, rsp) + // return + // } + // if !rs.OrganIsValid() { + // log.Errorf("GetGrayAppInfo get info organ info invalid,appId:%s", appID) + // MakeRsp(c, http.StatusForbidden, FS_COOPERATION_TERMINATED, rsp) + // return + // } + // if rs.BindNotFound() { + // log.Errorf("GetGrayAppInfo get info bind not found,sdkKey:%s,appId:%s", key, appID) + // MakeRsp(c, http.StatusForbidden, FS_COOPERATION_TERMINATED, rsp) + // return + // } + // if !rs.BindCoopValid() { + // log.Errorf("GetGrayAppInfo get info bind coop status invalid,sdkKey:%s", key) + // MakeRsp(c, http.StatusForbidden, FS_COOPERATION_TERMINATED, rsp) + // return + // } + // if !rs.BindAssociateValid() { + // log.Errorf("GetGrayAppInfo get info bind ass app invalid,sdkKey:%s,appId:%s", key, appID) + // MakeRsp(c, http.StatusForbidden, FS_APP_NOT_ASS_BIND, rsp) + // return + // } + // if !rs.PayBindIdStatusOk() { + // log.Errorf("GetGrayAppInfo get info bind pay status invaild,appId:%s", appID) + // MakeRsp(c, http.StatusForbidden, FS_BIND_PAY_EXPIRE, rsp) + // return + // } + // if !rs.LicenseValid() { + // log.Errorf("GetGrayAppInfo get info license invalid,sdkKey:%s,appId:%s", key, appID) + // MakeRsp(c, http.StatusForbidden, FS_LICENSE_INVALID_ERR, rsp) + // return + // } + // MakeRsp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, rsp) + // return + //} + //c.JSON(http.StatusOK, resp) + return +} + +type RuntimeGetAppVersionInfoRsp struct { + AppID string `json:"appId"` + Name string `json:"name"` + Sequence int `json:"sequence"` + AppClass string `json:"appClass"` + AppType string `json:"appType"` + Status entity.Status `json:"status"` + PublishedStatus entity.SpecificStatus `json:"publishedStatus"` + ActionStatus entity.SpecificStatus `json:"actionStatus"` + DeveloperID string `json:"developerId"` + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + Created int64 `json:"created"` + CreatedBy string `json:"createdBy"` + //CustomData proto.AppRspCustomData `json:"customData"` + Version string `json:"version"` + CorporationID string `json:"corporationId"` + CoreDescription string `json:"coreDescription"` + Logo string `json:"logo"` + Platform []string `json:"platform"` + MarketID string `json:"marketId"` + FcID string `json:"fcId"` +} + +func RuntimeGetAppVersionInfo(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + appID := c.Param("path1") + seqStr := c.Param("path3") + log.Infof("RuntimeGetAppVersionInfo appId:%s,sequence:%s", appID, seqStr) + if appID == "" { + log.Errorf("RuntimeGetAppVersionInfo appID empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, gin.H{}) + return + } + //sequence, err := strconv.Atoi(seqStr) + //if err != nil { + // log.Errorf("RuntimeGetAppVersionInfo seueence format err:%s,seqstr:%s", err.Error(), seqStr) + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + // return + //} + //t := db.NewTable(db.TableAppVersion) + //appVerInfo := model.AppVersion{} + //if err := t.GetOne(traceCtx, bson.M{"appId": appID, "sequence": sequence}, &appVerInfo); err != nil { + // log.Errorf("RuntimeGetAppVersionInfo get appVer err:%s", err.Error()) + // MakeRsp(c, http.StatusInternalServerError, FS_DB_ERR, rsp) + // return + //} + //if t.NotFound() { + // log.Error("RuntimeGetAppVersionInfo get appVer not found!") + // MakeRsp(c, http.StatusNotFound, FS_APP_SEQUENCE_NOT_FOUND, rsp) + // return + //} + // + //key := c.Request.Header.Get("SDK-Key") + ////白名单 + //if !InArry(key, config.WhiteSDKArry) { + // log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", key) + // MakeRsp(c, http.StatusForbidden, FS_COOPERATION_TERMINATED, rsp) + // return + //} + ////安全校验 + //err = CheckSignatureAuth(traceCtx, key, c) + //if err != nil { + // log.Error("RuntimeGetAppVersionInfo CheckSignatureAuth err:%s", err.Error()) + // MakeRsp(c, http.StatusBadRequest, err.Error(), rsp) + // return + //} + ////校验企业的状态 + //log.Infof("get group info id:%s", appVerInfo.GroupID) + //groupInfo, err := provider.GetGroupInfoByGroupId(traceCtx, appVerInfo.GroupID) + //if err != nil { + // log.Errorf("RuntimeGetAppVersionInfo GetGroupInfoByGroupId err:%s", err.Error()) + // MakeRsp(c, http.StatusBadRequest, FS_GET_GROUP_FAILED, rsp) + // return + //} + //log.Infof("RuntimeGetAppVersionInfo get group info:%+v", groupInfo) + ////如果是私有化版本,白名单不需要校验 + //if config.Cfg.PublishEnv != ENV_PRIVATE { + // if groupInfo.ReviewStatus != client.StOrganApproved && + // groupInfo.ReviewStatus != client.StOrganPersonalReviewing && + // groupInfo.ReviewStatus != client.StOrganPersonalUnPass { + // log.Errorf("RuntimeGetAppVersionInfo organ status:%v", groupInfo.ReviewStatus) + // MakeRsp(c, http.StatusForbidden, FS_COOPERATION_TERMINATED, rsp) + // return + // } + //} + ////appVerInfo.CustomData["appRuntimeDomain"] = data + //rspInfo := RuntimeGetAppVersionInfoRsp{ + // AppID: appVerInfo.AppID, + // Name: appVerInfo.Name, + // Sequence: appVerInfo.Sequence, + // AppClass: appVerInfo.AppClass, + // AppType: appVerInfo.AppType, + // Status: appVerInfo.Status, + // PublishedStatus: appVerInfo.PublishedStatus, + // //UnpublishedStatus: appVerInfo.UnpublishedStatus, + // ActionStatus: appVerInfo.ActionStatus, + // DeveloperID: appVerInfo.DeveloperID, + // GroupID: appVerInfo.GroupID, + // GroupName: groupInfo.GroupName, //实时获取 todo 加个缓存 + // Created: appVerInfo.Created, + // CreatedBy: appVerInfo.CreatedBy, + // //CustomData: appVerInfo.CustomData, + // Version: appVerInfo.Version, + // CorporationID: appVerInfo.CorporationID, + // CoreDescription: appVerInfo.CoreDescription, + // Logo: appVerInfo.Logo, + // Platform: appVerInfo.Platform, + // MarketID: appVerInfo.MarketID, + // FcID: appVerInfo.FcID, + //} + //err, errCode, customData := service.ConvertModelCustomDataToRpc(traceCtx, service.NewRuntimeService(), appVerInfo.GroupID, appVerInfo.CustomData, nil, "") + //rspInfo.CustomData = *customData + //if err != nil { + // log.Errorf("RuntimeGetAppVersionInfo ConvertModelCustomDataToPb err:%s", err.Error()) + // MakeRsp(c, http.StatusInternalServerError, errCode, rsp) + // return + //} + //c.JSON(http.StatusOK, rspInfo) + //return +} diff --git a/application/app_temp_info.go b/application/app_temp_info.go new file mode 100644 index 0000000..4a186c1 --- /dev/null +++ b/application/app_temp_info.go @@ -0,0 +1,70 @@ +package application + +import ( + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/utility" + "net/http" + + "github.com/gin-gonic/gin" +) + +/** + * @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 UpdateTempApp(c *gin.Context) { + var ( + errRspData = make(map[string]interface{}) + ) + req := proto.UpdateTempAppInfoReq{} + err := c.BindJSON(&req) + if err != nil { + log.Errorf("UpdateTempApp bind json err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, errRspData) + return + } + appId := c.Param("appId") + log.Infof("UpdateTempApp appId:[%s],req:%+v", appId, req) + svr := service.NewAppTempInfoService() + svr.UpdateTempApp(c, appId, &req) + 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 GenTempApp(c *gin.Context) { + req := proto.CreateTempAppInfoReq{} + err := c.ShouldBindJSON(&req) + if err != nil { + log.Errorf("GenTempApp bind json err:%s", err.Error()) + } + + svr := service.NewAppTempInfoService() + svr.GenTempApp(c, req) + return +} diff --git a/application/application.go b/application/application.go new file mode 100644 index 0000000..d8c2ff7 --- /dev/null +++ b/application/application.go @@ -0,0 +1,38 @@ +package application + +/** + * DDD: application 应用层 + * 相对于领域层,应用层是很薄的一层,应用层定义了软件要完成的任务,要尽量简单。 + * 它不包含任务业务规则或知识, 为下一层的领域对象协助任务、委托工作。 + * 它没有反映业务情况的状态,但它可以具有反映用户或程序的某个任务的进展状态。 + * 对外:为展现层提供各种应用功能(service)。 + * 对内:调用领域层(领域对象或领域服务)完成各种业务逻辑任务(task)。 + * 这一层也很适合写一些任务处理,日志监控。 + **/ + +import ( + "github.com/gin-gonic/gin" +) + +/** + * @api {GET} /api/v1/finclip-app-manager/user [C/S]user api + * @apiGroup [这个地方需要改成对应的项目名称],例如:@apiGroup ddd Gin Framework + * @apiVersion __API_VERSION__ + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "errcode": "OK", + * "error": "成功", + * "data":{ + * "say":"hello" + * } + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func UserApi(c *gin.Context) { + //rsp := gin.H{"say": "hello"} + + //utility.MakeRsp(c, http.StatusOK, utility.OK, rsp) + return +} diff --git a/application/binding.go b/application/binding.go new file mode 100644 index 0000000..e9eae86 --- /dev/null +++ b/application/binding.go @@ -0,0 +1,1870 @@ +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 +} diff --git a/application/file.go b/application/file.go new file mode 100644 index 0000000..d98013b --- /dev/null +++ b/application/file.go @@ -0,0 +1,37 @@ +package application + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +func UploadFile(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + inFile, fileHeader, err := c.Request.FormFile("file") + if err != nil { + log.Errorf("get form file err:", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + url, err := hCaller.Upload(traceCtx, fileHeader.Filename, inFile, config.Cfg.OpenCdn) + if err != nil { + log.Errorf("Upload err:", err.Error()) + utility.MakeErrRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, err.Error(), gin.H{}) + return + } + file := entity.File{ + FileID: bson.NewObjectId().Hex(), + Name: fileHeader.Filename, + UploadDate: time.Now().UnixNano() / 1000000, + Size: fileHeader.Size, + Url: url, + } + c.JSON(http.StatusOK, file) +} diff --git a/application/grpc/app.go b/application/grpc/app.go new file mode 100644 index 0000000..af75f69 --- /dev/null +++ b/application/grpc/app.go @@ -0,0 +1,303 @@ +package grpcHandler + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/logger" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "finclip-app-manager/infrastructure/utility" + "strings" + + "gitlab.finogeeks.club/finclip-backend/apm" + + "net/http" +) + +var ( + log = logger.GetLogger() +) + +type GrpcServer struct { +} + +func (g GrpcServer) RuleEngineGetAppInfo(ctx context.Context, req *pb.RuleEngineGetAppInfoReq) (*pb.RuleEngineGetAppInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.RuleEngineGetAppInfo") + defer span.End() + svr := service.NewAppService() + rspData, rsp := svr.RuntimeGetPubAppInfo(ctx, req.GetSdkKey(), req.GetAppId(), req.GetSdkVer()) + log.Infof("RuleEngineGetAppInfo service rsp data:%+v,rsp:%v", rspData, rsp) + result := pb.RuleEngineGetAppInfoRsp{} + if rsp.ErrCode != utility.OK { + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + return &result, nil + } + result.Data = service.CovertAppToPbAppInfoRsp(&rspData) + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + return &result, nil +} + +func (g GrpcServer) RuleEngineGetAppVerInfo(ctx context.Context, req *pb.RuleEngineGetAppVerInfoReq) (*pb.RuleEngineGetAppVerInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.RuleEngineGetAppVerInfo") + defer span.End() + svr := service.NewAppService() + rspData, rsp := svr.RuleEngineGetAppVerInfo(ctx, req.AppId, int(req.GetVersion()), req.GetSdkKey(), req.GetSdkVer()) + log.Infof("RuleEngineGetAppVerInfo service rsp data:%+v,rsp:%v", rspData, rsp) + + result := pb.RuleEngineGetAppVerInfoRsp{} + if rsp.ErrCode != utility.OK { + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + return &result, nil + } + result.Data = service.CovertAppToPbAppInfoRsp(&rspData) + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + + return &result, nil +} + +func (g GrpcServer) OpenApiGetAppVerInfo(ctx context.Context, req *pb.OpenApiGetAppVerInfoReq) (*pb.OpenApiGetAppVerInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.OpenApiGetAppVerInfo") + defer span.End() + + result := pb.OpenApiGetAppVerInfoRsp{} + if req.GetAppId() == "" || req.GetSdkKey() == "" { + log.Errorf("InternalGetAppVerInfo sdk key or appid empty,appId:%s,sdkKey:%s", req.GetAppId(), req.GetSdkKey()) + switch { + case req.GetAppId() == "": + utility.MakeGrpcCommonResult(http.StatusBadRequest, utility.FS_LACK_OF_APPID, &result.Result) + case req.GetSdkKey() == "": + utility.MakeGrpcCommonResult(http.StatusBadRequest, utility.FS_LACK_OF_SDKKEY, &result.Result) + default: + utility.MakeGrpcCommonResult(http.StatusBadRequest, utility.FS_LACK_OF_APPID, &result.Result) + } + return &result, nil + } + //sdkKey白名单的校验 + if !utility.InArry(req.SdkKey, config.WhiteSDKArry) { + if config.Cfg.PublishEnv == entity.ENV_PRIVATE { + svr := service.NewBindingService() + //if !svr.CheckReviewBySdkKey(ctx, req.SdkKey) { + checkStatus := svr.CheckReviewBySdkKey(ctx, req.SdkKey) + if checkStatus != utility.OK { + log.Errorf("RuntimeGetAppVersionInfo sdk not in review list,sdk-key:%s", req.SdkKey) + utility.MakeGrpcCommonResult(http.StatusForbidden, checkStatus, &result.Result) + return &result, nil + } + } else { + log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", req.SdkKey) + utility.MakeGrpcCommonResult(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED, &result.Result) + return &result, nil + } + } + svr := service.NewAppService() + rspData, rsp := svr.OpenApiGetAppVerInfo(ctx, req.GetAppId(), int(req.GetVersion()), req.GetSdkVer()) + log.Infof("OpenApiGetAppVerInfo rsp data:%+v,rsp:%+v", rspData, rsp) + if rsp.ErrCode != utility.OK { + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + return &result, nil + } + result.Data = service.CovertInternalAppToPbAppInfoRsp(&rspData) + result.Data.GroupName = g.ChangeGroupName(result.Data.GroupName) + utility.MakeGrpcCommonResult(rsp.HttpStatus, rsp.ErrCode, &result.Result) + return &result, nil +} + +func (g GrpcServer) ChangeGroupName(groupName string) string { + if len(groupName) == 18 && strings.Contains(groupName, "个人-") { + phone := groupName[7:] + if isOK := utility.IsMobile(phone); isOK { + newName := "个人-" + for i := 0; i < len(phone); i++ { + if i >= 3 && i <= 6 { + newName += "*" + } else { + newName += string(phone[i]) + } + } + + groupName = newName + } + } + + return groupName +} + +func (g GrpcServer) GetOrganIdBySdkKey(ctx context.Context, req *pb.GetOrganIdBySdkKeyReq) (*pb.GetOrganIdBySdkKeyRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.GetOrganIdBySdkKey") + defer span.End() + + rsp := pb.GetOrganIdBySdkKeyRsp{} + rsp.Data = new(pb.GetOrganIdBySdkKeyRsp_DATA) + rsp.Data.OrganId = "" + rsp.Data.IsWhite = false + if req.SdkKey == "" { + log.Errorf("GetOrganIdBySdkKey sdk-key empty!!!") + utility.MakeGrpcCommonResult(http.StatusBadRequest, utility.FS_LACK_OF_SDKKEY, &rsp.Result) + return &rsp, nil + } + //sdkKey白名单的校验 + if utility.InArry(req.SdkKey, config.WhiteSDKArry) { + log.Errorf("GetOrganIdBySdkKey is white list,sdk key:%s", req.SdkKey) + rsp.Data.IsWhite = true + utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result) + return &rsp, nil + } + //非白名单 + //svr := service.NewBindingService() + //t := db.NewTable(db.TableBinding) + //result := model.Binding{} + //err := t.GetOne(ctx, bson.M{"bundleInfos.SDKKey": bson.M{"$in": []string{req.SdkKey}}}, &result) + //if err != nil { + // log.Errorf("GetOrganIdBySdkKey get binding info error:%s", err.Error()) + // common.MakeGrpcCommonResult(http.StatusInternalServerError, common.FS_SERVICE_UNAVAILABLE, &rsp.Result) + // return &rsp, nil + //} + //rsp.Data.OrganId = result.GroupID + //rsp.Data.IsWhite = false + //log.Infof("GetOrganIdBySdkKey sdkKey:%s,result:%+v", req.SdkKey, result) + //common.MakeGrpcCommonResult(http.StatusOK, common.OK, &rsp.Result) + return &rsp, nil +} + +func (g GrpcServer) BatchGetAppAndVerInfo(ctx context.Context, req *pb.BatchGetAppAndVerInfoReq) (*pb.BatchGetAppAndVerInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.BatchGetAppAndVerInfo") + defer span.End() + + rsp := new(pb.BatchGetAppAndVerInfoRsp) + rsp.Data = new(pb.BatchGetAppAndVerInfoRsp_DATA) + rsp.Data.AppFailList = make([]string, 0) + rsp.Data.AppVerFailList = make([]string, 0) + rsp.Data.AppDataList = make([]*pb.AppInfoRspData, 0) + rsp.Data.AppVerDataList = make([]*pb.AppInfoRspData, 0) + log.Infof("BatchGetAppAndVerInfo req:%+v", req) + //首先获取小程序详情 + rs := service.NewAppService() + for _, appId := range req.AppList { + data, tempRsp := rs.RuntimeGetPubAppInfo(ctx, req.SdkKey, appId, req.SdkVer) + if tempRsp.ErrCode != utility.OK { + log.Errorf("RuleEngineBatchGetApp get info data:%v,resp:%+v", data, tempRsp) + rsp.Data.AppFailList = append(rsp.Data.AppFailList, appId) + continue + } + log.Debugf("RuleEngineBatchGetApp info:%+v", data.CustomData.SourceFile) + log.Debugf("RuleEngineBatchGetApp info:%+v", utility.InterfaceToJsonString(data)) + rsp.Data.AppDataList = append(rsp.Data.AppDataList, service.CovertAppToPbAppInfoRsp(&data)) + } + //获取小程序版本详情 + for _, appVer := range req.AppVerList { + rspData, tempRsp := rs.RuleEngineGetAppVerInfo(ctx, appVer.AppId, int(appVer.Sequence), req.SdkKey, req.SdkVer) + if tempRsp.ErrCode != utility.OK { + rsp.Data.AppVerFailList = append(rsp.Data.AppVerFailList, appVer.AppId) + continue + } + rsp.Data.AppVerDataList = append(rsp.Data.AppVerDataList, service.CovertAppToPbAppInfoRsp(&rspData)) + } + utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result) + log.Infof("grpc BatchGetAppAndVerInfo resp:", utility.InterfaceToJsonString(rsp)) + return rsp, nil +} + +func (g GrpcServer) OpenApiGetQRcodeAppVerInfo(ctx context.Context, req *pb.OpenApiGetQRcodeAppVerInfoReq) (*pb.OpenApiGetAppVerInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.OpenApiGetAppVerInfo") + defer span.End() + + rsp := pb.OpenApiGetAppVerInfoRsp{} + rsp.Data = new(pb.AppInfoRspData) + if req.RedisKey == "" { + log.Errorf("InternalGetAppVerInfo redisKey empty!!!") + return &rsp, nil + } + if req.SdkKey == "" { + log.Errorf("InternalGetAppVerInfo sdk-key empty!!!") + return &rsp, nil + } + //sdkKey白名单的校验 + if !utility.InArry(req.SdkKey, config.WhiteSDKArry) { + if config.Cfg.PublishEnv == entity.ENV_PRIVATE { + svr := service.NewBindingService() + checkStatus := svr.CheckReviewBySdkKey(ctx, req.SdkKey) + if checkStatus != utility.OK { + log.Errorf("RuntimeGetAppVersionInfo sdk not in review list,sdk-key:%s", req.SdkKey) + return &rsp, nil + } + } else { + log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", req.SdkKey) + return &rsp, nil + } + } + rspInfo := service.InternalGetAppVerInfoRsp{} + //dataBytes, err := cache.NewQRcodeAppCache().GetQRcodeAppInfo(ctx, req.RedisKey) + //fmt.Println("dataBytes------------", dataBytes) + //if err != nil { + // if len(dataBytes) == 0 { + // log.Debugln("qrcode is refresh:") + // common.MakeGrpcCommonResult(http.StatusOK, common.FS_QRCODE_HAS_EXPIRE, &rsp.Result) + // return &rsp, nil + // + // } else { + // log.Errorf("redis error:", err.Error()) + // return &rsp, nil + // } + //} + //err = json.Unmarshal(dataBytes, &rspInfo) + //if err != nil { + // log.Errorf("json unmarshal error:", err.Error()) + // return &rsp, nil + //} + + rsp.Data.AppClass = rspInfo.AppClass + rsp.Data.AppId = rspInfo.AppID + rsp.Data.AppType = rspInfo.AppType + rsp.Data.CoreDescription = rspInfo.CoreDescription + rsp.Data.CorporationId = rspInfo.CorporationID + rsp.Data.Created = rspInfo.Created + rsp.Data.CreatedBy = rspInfo.CreatedBy + rsp.Data.CustomData = service.ConvertRpcCustomDataToPb(rspInfo.CustomData) + + rsp.Data.DeveloperId = rspInfo.DeveloperID + rsp.Data.GroupId = rspInfo.GroupID + rsp.Data.GroupName = rspInfo.GroupName + rsp.Data.InGrayRelease = rspInfo.InGrayRelease + rsp.Data.Logo = rspInfo.Logo + rsp.Data.Name = rspInfo.Name + rsp.Data.Sequence = int32(rspInfo.Sequence) + rsp.Data.Version = rspInfo.Version + if &rspInfo.Status != nil { + rsp.Data.Status = new(pb.Status) + rsp.Data.Status.Value = rspInfo.Status.Value + rsp.Data.Status.LastUpdated = rspInfo.Status.LastUpdated + rsp.Data.Status.ModifiedBy = rspInfo.Status.ModifiedBy + rsp.Data.Status.Reason = rspInfo.Status.Reason + } + + rsp.Data.IsTemp = rspInfo.IsTemp + rsp.Data.IsUserLimit = false + rsp.Data.NeedCrt = rspInfo.NeedCrt + rsp.Data.WechatLoginInfo = service.ConvertWechatLoginInfoToPb(&rspInfo.WechatLoginInfo) + rsp.Data.PrivacySettingType = int32(rspInfo.PrivacySettingType) + rsp.Data.ProjectType = int32(rspInfo.ProjectType) + rsp.Data.AppTag = rspInfo.AppTag + log.Debugln("appver info:", rspInfo, ",data:", rsp.Data) + utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result) + return &rsp, nil +} + +func (g GrpcServer) GetBuildAppInfo(ctx context.Context, req *pb.GetBuildAppInfoReq) (*pb.GetBuildAppInfoRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.GetBuildAppInfo") + defer span.End() + log.Infof("grpc GetBuildAppInfo req:%+v", req) + svr := service.NewAppService() + svrReq := apiproto.GetBuildAppInfoReq{ + Type: req.GetType(), + CodeId: req.GetCodeId(), + } + rspData, rsp := svr.GetBuildInfo(ctx, svrReq, req.GetSdkKey()) + //buildInfo, svrRsp := svr.GetBuildInfo(ctx, svrReq, req.GetSdkKey()) + log.Infof("grp GetBuildAppInfo rsp data:%+v,rsp:%+v", rspData, rsp) + result := new(pb.GetBuildAppInfoRsp) + result.Data = rspData + utility.MakeGrpcCommonResultNoLoc(rsp.HttpStatus, rsp.ErrCode, rsp.ErrMsg, &result.Result) + return result, nil +} diff --git a/application/grpc/externalApp.go b/application/grpc/externalApp.go new file mode 100755 index 0000000..c7f749a --- /dev/null +++ b/application/grpc/externalApp.go @@ -0,0 +1,47 @@ +package grpcHandler + +import ( + "context" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +func (GrpcServer) BatchAppsByIdentity(ctx context.Context, req *pb.BatchAppsByIdentityReq) (*pb.BatchAppsByIdentityRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.BatchAppsByIdentity") + defer span.End() + svr := service.NewAppService() + svrReq := &apiproto.BatchAppsByIdentityReq{ + Source: req.Source, + IdentityType: req.IdentityType, + Apps: make([]apiproto.BatchAppsByIdentityAppsItem, 0), + } + for _, v := range req.Apps { + item := apiproto.BatchAppsByIdentityAppsItem{ + AppId: v.GetAppId(), + Identity: v.GetIdentity(), + } + svrReq.Apps = append(svrReq.Apps, item) + } + return svr.BatchAppsByIdentity(ctx, req.GetSdkKey(), svrReq), nil +} + +func (GrpcServer) IdentityAppsCheck(ctx context.Context, req *pb.IdentityAppsCheckReq) (*pb.IdentityAppsCheckRsp, error) { + span, ctx := apm.ApmClient().CreateGRpcEntrySpan(ctx, "GrpcServer.IdentityAppsCheck") + defer span.End() + svr := service.NewAppService() + svrReq := &apiproto.IdentityAppsCheckReq{ + Source: req.Source, + IdentityType: req.IdentityType, + Apps: make([]apiproto.IdentityAppsCheckAppsItem, 0), + } + for _, v := range req.Apps { + item := apiproto.IdentityAppsCheckAppsItem{ + AppId: v.GetAppId(), + Identity: v.GetIdentity(), + } + svrReq.Apps = append(svrReq.Apps, item) + } + return svr.IdentityAppsCheck(ctx, req.GetSdkKey(), svrReq), nil +} diff --git a/application/menu_info.go b/application/menu_info.go new file mode 100644 index 0000000..7079614 --- /dev/null +++ b/application/menu_info.go @@ -0,0 +1,216 @@ +package application + +import ( + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/utility" + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" + "net/http" +) + +/** + * @api {POST} + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} name + * @apiParam (RequestBody) {string} id + * @apiParam (RequestBody) {string} image + * @apiParamExample {json} Request-Example: + * { + * "name":"111", + * "id":"1112", + * "image":"11" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "errcode": "OK", + * "error": "成功", + * "data":{ + * + * } + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func AddMenuHand(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + req = apiproto.AddMenuReq{} + ) + + if err := c.BindJSON(&req); err != nil { + log.Errorf("AddMenuHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if req.Name == "" || req.ID == "" || req.Image == "" { + log.Errorf("AddMenuHand param err:[empty],req:%+v", req) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewMenuInfoService() + svr.AddMenu(traceCtx, c, &req) + return +} + +/** + * @api {GET} + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DelMenuHand(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + ) + + traceId := c.Param("traceId") + if traceId == "" { + log.Errorf("trace id empty ...") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + svr := service.NewMenuInfoService() + svr.DelMenu(traceCtx, c, traceId) + return +} + +/** + * @api {PUT} + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} traceId + * @apiParam (RequestBody) {string} name + * @apiParam (RequestBody) {string} id + * @apiParam (RequestBody) {string} image + * @apiParamExample {json} Request-Example: + * { + * "name":"111", + * "id":"1112", + * "image":"11" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func UpdateMenuHand(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + ) + + traceId := c.Param("traceId") + if traceId == "" { + log.Errorf("trace id empty ...") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + + req := apiproto.UpdateMenuReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("UpdateMenuHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + + svr := service.NewMenuInfoService() + svr.UpdateMenu(traceCtx, c, traceId, &req) + + return +} + +/** + * @api {GET} + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * { + * "data": { + * "total": 1, + * "list": [ + * { + * "traceId": "6049d56024c81800015698cc", + * "name": "12", + * "id": "12", + * "image": "/api/v1/mop/netdisk/download/6049d55f264ec50001706a4c", + * "sortNum": 0, + * "createTime": 1615451488106, + * "updateTime": 1615451488106, + * "updateOperator": "叼叼叼kk" + * } + * ] + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func GetAllMenuHand(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + ) + svr := service.NewMenuInfoService() + svr.GetAllMenu(traceCtx, c) + + return +} + +/** + * @api {POST} + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} traceId + * @apiParam (RequestBody) {string} sortNum + * @apiParamExample {json} Request-Example: + * { + * "list": [ + * { + * "traceId": "61f2658437236900015ad666", + * "sortNum": 5 + * }, + * { + * "traceId": "61f266ea37236900015ad667", + * "sortNum": 4 + * } + * ] + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func SortMenuHand(c *gin.Context) { + var ( + traceCtx = apm.ApmClient().TraceContextFromGin(c) + ) + + req := apiproto.MenuSortReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("AddMenuHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + + svr := service.NewMenuInfoService() + svr.SortMenu(traceCtx, c, &req) + + return +} \ No newline at end of file diff --git a/application/public.go b/application/public.go new file mode 100644 index 0000000..405afa8 --- /dev/null +++ b/application/public.go @@ -0,0 +1,11 @@ +package application + +import ( + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/logger" +) + +var ( + hCaller = httpcall.NewClient() + log = logger.GetLogger() +) diff --git a/application/qr_code_info.go b/application/qr_code_info.go new file mode 100644 index 0000000..b120937 --- /dev/null +++ b/application/qr_code_info.go @@ -0,0 +1,485 @@ +package application + +import ( + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/logger" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "fmt" + "net/http" + "net/url" + "path" + "strconv" + "strings" + "time" + + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +/** + * @api {POST} + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId 小程序Id + * @apiParam (RequestBody) {string} sequence 小程序序列号 + * @apiParam (RequestBody) {string} apiServer 小程序apiServer + * @apiParam (RequestBody) {string} type + * @apiParam (RequestBody) {string} codeId 标识某个编译版本的id + * @apiParam (RequestBody) {string} startParams 小程序启动参数 + * @apiParamExample {json} Request-Example: + * { + * "appId": "5fd17becec413300012b1911", + * "sequence": 0, + * "apiServer": "https://finchat-mop-b.finogeeks.club", + * "type": "trial", + * "codeId": "c1218720c7a34e5f43b3b6d3", + * "startParams": { + * "path": "", + * "query": "" + * } + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": { + * "url": "https://finchat-mop-b.finogeeks.club/api/v1/mop/runtime/applet/-f-NDhiNThiOGIwYjJlNDdmZg--" + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func GenQrcodeHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := proto.GenQrcodeReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("GenQrcodeHand bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_PARAM_ERR, gin.H{}) + return + } + log.Infof("GenQrcodeHand req:%+v", req) + svr := service.NewQrCodeInfoService() + info, err := svr.GenQrcodeInfo(traceCtx, req) + if err != nil { + log.Errorf("GenQrcodeHand GenQrcodeInfo err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + log.Debugf("get qrcode type:%s info:%+v", info.Type, info) + rspInfo := gin.H{} + if info.Type == entity.QrCodeTypeTemporary || info.Type == entity.QrCodeTypeRomoteDebug || info.Type == entity.QrCodeTypeReview { + rspInfo["expireTime"] = info.ExpireTime + } + server, err := parseServer(req.ApiServer) + if err != nil { + log.Errorf("gen url err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, gin.H{}) + return + } + var serverUrl string + if req.Limit != "" { + serverUrl = config.GetConfig().QRcodeUriV2 + } else { + serverUrl = config.GetConfig().QRcodeUri + } + + resultUrl := server + path.Join(serverUrl, req.Limit, "/", info.Uuid) + rspInfo["url"] = resultUrl + log.Debugf("qrcode type:%s result info:%+v", info.Type, rspInfo) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspInfo) + return +} + +//对原有的二维码逻辑进行重新处理 +//文档见:https://wiki.finogeeks.club/pages/viewpage.action?pageId=161317118 +func joinUrl(server string, uri, uuid string) (string, error) { + u, err := url.Parse(server) + if err != nil { + return "", err + } + u.Path = path.Join(u.Path, uri, uuid) + return u.String(), nil +} + +func parseServer(server string) (string, error) { + u, err := url.Parse(server) + if err != nil { + return "", err + } + return u.String(), nil +} + +type appQRcodeInfoReq struct { + AppID string `json:"appId"` + Sequence int `json:"sequence"` + ApiServer string `json:"apiServer"` + CodeId string `json:"codeId"` + Type string `json:"type"` + StartParams appQRcodeInfoStartParams `json:"startParams"` +} + +type appQRcodeInfoStartParams struct { + Path string `json:"path"` + Query string `json:"query"` +} + +type EncryptInfo struct { + AppID string `json:"appId"` + Sequence int `json:"sequence"` + ApiServer string `json:"apiServer"` + CodeId string `json:"codeId"` + Type string `json:"type"` + StartParams appQRcodeInfoStartParams `json:"startParams"` + ExpireTime int64 `json:"expireTime"` + Uuid string `json:"uuid"` +} + +type appQRcodeInfoRsp struct { + QRData string `json:"qrData"` + ExpireTime int `json:"expireTime"` +} + +/** + * @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 QRCodeRefresh(c *gin.Context) { + req := appQRcodeInfoReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("appInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + log.Infof("QRCodeRefresh req:%+v", req) + + addSecond, _ := time.ParseDuration(strconv.Itoa(config.GetConfig().QRcodeExpireTime) + "s") + + encryptData := EncryptInfo{} + encryptData.AppID = req.AppID + encryptData.Sequence = req.Sequence + encryptData.ApiServer = req.ApiServer + encryptData.CodeId = req.CodeId + encryptData.Type = req.Type + if config.GetConfig().ApiServer != "" { + encryptData.ApiServer = config.GetConfig().ApiServer + } + encryptData.StartParams.Path = req.StartParams.Path + encryptData.StartParams.Query = req.StartParams.Query + //过期时间 + encryptData.ExpireTime = -1 + encryptData.Uuid = uuid.NewV4().String() + if req.Type == "temporary" { + encryptData.ExpireTime = time.Now().Add(addSecond).UnixNano() / 1e6 + } + jsonByte, _ := json.Marshal(encryptData) + logger.GetLogger().Debugf("jsonByte:%s", string(jsonByte)) + + encodeStr := utils.EncodeAESContent(string(jsonByte)) + //if req.Type == "temporary" { + // /*err := cache.NewAppCache(req.AppID).SetAppInfoQRcode(traceCtx, encodeStr, jsonByte, config.Cfg.QRcodeExpireTime) + // if err != nil { + // logger.GetLogger().Errorf("redis set data error:", err.Error()) + // MakeRsp(c, http.StatusBadRequest, utility.FS_REDIS_ERR, nil) + // return + // }*/ + // encryptData.ExpireTime = time.Now().Add(addSecond).UnixNano() / 1e6 + //} + rsp := appQRcodeInfoRsp{} + rsp.QRData = encodeStr + rsp.ExpireTime = config.GetConfig().QRcodeExpireTime + 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 InternalGetQRcodeAppVerInfo(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + SDKKey := c.GetHeader(entity.SDKKEY_HEADER_KEY) + redisKey := c.GetHeader("redisKey") + log.Infof("InternalGetAppVerInfo req appId:%s,seq:%s,sdk-key:%s,sdk-ver:%s", SDKKey, redisKey) + rspErr := make(map[string]interface{}) + if redisKey == "" { + log.Errorf("InternalGetAppVerInfo redisKey empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, rspErr) + return + } + if SDKKey == "" { + log.Errorf("InternalGetAppVerInfo sdk-key empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_SDKKEY, rspErr) + return + } + //sdkKey白名单的校验 + if !utils.InArry(SDKKey, config.WhiteSDKArry) { + log.Errorf("RuntimeGetAppVersionInfo sdk not in white sdk arry,sdk-key:%s", SDKKey) + utility.MakeLocRsp(c, http.StatusForbidden, utility.FS_COOPERATION_TERMINATED, rspErr) + return + } + /* appVerSvr := service.NewAppVerService() + data, httpCode, errcode := appVerSvr.OpenApiGetAppVerInfo(traceCtx, appId, sequence, sdkVer) + if data == nil { + MakeRsp(c, httpCode, errcode, rspErr) + return + } + MakeRsp(c, httpCode, errcode, data)*/ + rspInfo := InternalGetAppVerInfoRsp{} + + // 临时注释 + //dataBytes, err := cache.NewQRcodeAppCache().GetQRcodeAppInfo(c, redisKey) + //fmt.Println("dataBytes------------", dataBytes) + //if err != nil { + // if len(dataBytes) == 0 { + // log.Debugln("qrcode is refresh:") + // utility.MakeLocRsp(c, http.StatusOK, utility.FS_QRCODE_HAS_EXPIRE, rspInfo) + // return + // } else { + // log.Errorf("redis error:", err.Error()) + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_DB_ERR, rspInfo) + // return + // } + //} + //err = json.Unmarshal(dataBytes, &rspInfo) + //if err != nil { + // log.Errorf("json unmarshal error:", err.Error()) + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, rspInfo) + // return + //} + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspInfo) + 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 DeleteWechatQrcode(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := apiproto.DeleteWechatInfoReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("UpdateWechatInfo err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + svr := service.NewQrCodeInfoService() + if err := svr.DeleteWechatQrcode(traceCtx, req); err != nil { + log.Errorf("DeleteWechatQrcode err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_DB_ERR, nil) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil) + 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 GetQrcodeInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + uuid := c.Param("uuid") + log.Infof("GetQrcodeInfo req uuid:%v", uuid) + svr := service.NewQrCodeInfoService() + info, err := svr.GetQrcodeInfo(traceCtx, uuid) + + log.Errorf(utility.InterfaceToJsonString(info)) + if err != nil { + log.Errorf("GetQrcodeInfo err:%s", err.Error()) + if err == entity.NotFoundErr { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_NOT_FOUND, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, gin.H{}) + return + } + now := time.Now().UnixNano() / 1e6 + if info.Type == entity.QrCodeTypeReview && now >= info.ExpireTime { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_QR_CODE_EXPIRED, gin.H{}) + return + } + //uat多域名兼容 + if utils.InArry(info.ApiServer, config.GetConfig().UatDomainList) { + info.ApiServer = "https://api.finclip.com" + } + //if info.ApiServer == "https://www.finclip.com" || info.ApiServer == "https://www.finclip.com/" { + // info.ApiServer = "https://api.finclip.com" + //} + + resultInfo := make(map[string]interface{}) + resultInfo["apiServer"] = info.ApiServer + resultInfo["type"] = info.Type + switch info.Type { + case entity.QrCodeTypeReview: + resultInfo["appId"] = info.AppId + resultInfo["sequence"] = info.Sequence + resultInfo["expireTime"] = info.ExpireTime + case entity.QrCodeTypeRelease: + resultInfo["appId"] = info.AppId + case entity.APP_BUILD_SOURCE_TRIAL: + resultInfo["codeId"] = info.CodeId + //这里的返回做一个转换 + StartParamsMap := map[string]string{ + "path": "", + "query": "", + } + paramList := strings.Split(info.StartParams.PathAndQuery, "?") + if len(paramList) > 0 { + StartParamsMap["path"] = paramList[0] + } + if len(paramList) > 1 { + StartParamsMap["query"] = paramList[1] + } + resultInfo["startParams"] = StartParamsMap + case entity.QrCodeTypeTemporary: + resultInfo["appId"] = info.AppId + resultInfo["codeId"] = info.AppId + resultInfo["sequence"] = info.Sequence + resultInfo["expireTime"] = info.ExpireTime + StartParamsMap := map[string]string{ + "path": "", + "query": "", + } + paramList := strings.Split(info.StartParams.PathAndQuery, "?") + if len(paramList) > 0 { + StartParamsMap["path"] = paramList[0] + } + if len(paramList) > 1 { + StartParamsMap["query"] = paramList[1] + } + resultInfo["startParams"] = StartParamsMap + case entity.QrCodeTypeRomoteDebug: + resultInfo["appId"] = info.AppId + resultInfo["codeId"] = info.AppId + resultInfo["sequence"] = info.Sequence + resultInfo["expireTime"] = info.ExpireTime + resultInfo["debugInfo"] = info.DebugInfo + } + log.Infof("GetQrcodeInfo rsp:%+v", resultInfo) + infoByte, _ := json.Marshal(resultInfo) + infoStr := utils.EncodeAESContent(string(infoByte)) + log.Infof("info.ApiServer:%v", info.ApiServer) + link := info.ApiServer + "/mop/scattered-page/#/sdktip" + resultUrl := fmt.Sprintf("%s?info=%s&type=scanOpen&codeType=%s", link, infoStr, info.Type) + //resultUrl := fmt.Sprintf("%s/mop/scattered-page/#/sdktip?info=%s&type=scanOpen&codeType=%s", info.ApiServer, infoStr, info.Type) + //c.Redirect(http.StatusMovedPermanently, resultUrl) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"url": resultUrl}) + return +} + +const ( + QRCodeMinWidth = 280 + QRCodeMaxWidth = 1280 + QRCodeDefaultWidth = 430 +) + +func GetQRCode(c *gin.Context) { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + //appID := c.Param("path1") + //widthStr := c.Query("width") + //width := QRCodeDefaultWidth + //if widthStr != "" { + // var err error + // width, err = strconv.Atoi(c.Query("width")) + // if err != nil { + // //msg := "Invalid width format: should be integer" + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + // return + // } + //} + //if width < QRCodeMinWidth || width > QRCodeMaxWidth { + // //msg := "Invalid width" + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + // return + //} + //if appID == "" { + // //msg := "Lack of appId" + // utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + // return + //} + //qr := model.QRCode{} + //if err := qr.GetOne(traceCtx, bson.M{"appId": appID}); err != nil { + // if err.Error() == model.ErrorNotFound { + // msg := fmt.Sprintf("QR Code info with appId %s not found", appID) + // LogAndSetErrResp(c, http.StatusNotFound, FS_NOT_FOUND, nil, msg, nil) + // return + // } + //} + //app := model.App{} + //if err := app.GetOne(traceCtx, bson.M{"appId": appID}); err != nil { + // if err.Error() == model.ErrorNotFound { + // msg := fmt.Sprintf("App with appId %s not found", appID) + // LogAndSetErrResp(c, http.StatusBadRequest, FS_BAD_JSON, nil, msg, nil) + // } else { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, err, "Failed to get app", nil) + // } + // return + //} + ////qrCodeStr := fmt.Sprintf("%s://applet/appid/%s?path=%s", qr.Scheme, appID, qr.Path) + //qrCodeStr := fmt.Sprintf("%s://applet/appid/%s", qr.Scheme, appID) + //if qr.Path != "" { + // qrCodeStr = qrCodeStr + "?path=" + qr.Path + //} + //bytes, err := createQRCode(traceCtx, qrCodeStr, app.Logo, width) + //if err != nil { + // LogAndSetErrResp(c, http.StatusInternalServerError, FS_SYSTEM_CALL, err, "Failed create QR Code", nil) + // return + //} + //c.Data(http.StatusOK, "image/png", bytes) +} + +func GetQRCodeInfo(c *gin.Context) { + +} diff --git a/application/red_dot.go b/application/red_dot.go new file mode 100644 index 0000000..4ce7363 --- /dev/null +++ b/application/red_dot.go @@ -0,0 +1,61 @@ +package application + +import ( + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/utility" + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" + "net/http" +) + +type ReadRedDotReq struct { + Type string `json:"type"` + Id string `json:"id"` +} + +/** + * @api {POST} + * @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 ReadRedDotHand(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := ReadRedDotReq{} + if err := c.BindJSON(&req); err != nil { + log.Errorf("ReadRedDotHand read err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + userId := utility.GetUserId(c) + if userId == "" { + log.Errorf("ReadRedDotHand user id empty,req:%+v", req) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + var err error + svr := service.NewRedDotService() + switch req.Type { + case "trialAppQr": + err = svr.ReadTrialQr(traceCtx, req.Id, userId) + default: + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, gin.H{}) + return + } + if err != nil { + log.Errorf("ReadRedDotHand ReadTrialQr 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{}) + return +} diff --git a/application/type_config.go b/application/type_config.go new file mode 100644 index 0000000..a64a6d3 --- /dev/null +++ b/application/type_config.go @@ -0,0 +1,199 @@ +package application + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/service" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "gitlab.finogeeks.club/finclip-backend/apm" + "net/http" + "sort" +) + +type listTypeConfigResponse struct { + Total int `json:"total"` + List []entity.TypeConfig `json:"list"` +} + +/** + * @api {GET} + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": { + * "total": 1, + * "list": [ + * { + * "typeConfigId": "619659a31bcd700001146eb1", + * "namespace": "appClass", + * "value": "jinrong", + * "marketId": "", + * "customData": { + * "chinese": "金融" + * }, + * "sortNum": 1 + * } + * ] + * }, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +func ListTypeConfig(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + queryFilter, sortFilter, searchFilter, _, _, err := utils.GetCommonParam(c) + if err != nil { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + if len(sortFilter) == 0 { + sortFilter = []string{"namespace"} + } + filter := bson.M{"namespace": "appClass"} + if len(searchFilter) > 0 { + filter = searchFilter + } + if len(queryFilter) > 0 { + filter = bson.M{"$and": []bson.M{filter, queryFilter}} + } + + svr := service.NewTypeConfigService() + //total, cfgs, err := svr.GetTypeConfigList(traceCtx, pageSize, pageNo) + total, cfgs, err := svr.GetAllTypeConfigList(traceCtx) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, nil) + return + } + sort.Sort(entity.TypeConfigList(cfgs)) + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, listTypeConfigResponse{ + Total: total, + List: cfgs, + }) +} + +type typeConfigRequest struct { + AdministratorID string `json:"administratorId"` + entity.TypeConfig +} + +/** + * @api {POST} + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} administratorId + * @apiParam (RequestBody) {string} namespace + * @apiParam (RequestBody) {string} value + * @apiParam (RequestBody) {string} customData + * @apiParam (RequestBody) {string} marketId + * @apiParamExample {json} Request-Example: + * { + * "administratorId":"1", + * "namespace": "appClass", + * "value": "1", + * "customData": { + * "chinese": "哈哈" + * }, + * "marketId": "1" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "errcode": "OK", + * "error": "成功", + * "data":{ + * + * } + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func AddTypeConfig(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + reqJSON := typeConfigRequest{} + if err := c.ShouldBindJSON(&reqJSON); err != nil { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + if reqJSON.AdministratorID == "" { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + t := entity.TypeConfig{ + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: reqJSON.Namespace, + Value: reqJSON.Value, + MarketID: reqJSON.MarketID, + CustomData: reqJSON.CustomData, + } + + log.Errorln(111) + svr := service.NewTypeConfigService() + exist, err := svr.Exist(traceCtx, reqJSON.Namespace, reqJSON.Value) + log.Errorln(222) + log.Errorln(exist) + log.Errorln(err) + if err != nil && !svr.NotFound(err) { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, nil) + return + } + if exist { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } else { + //获取当前最高sortNum + nowSortNumInfo, err := svr.GetNowSortNumInfo(traceCtx) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, nil) + return + } + t.SortNum = nowSortNumInfo.SortNum + 1 + err = svr.Insert(traceCtx, &t) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, nil) + return + } + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) +} + +/** + * @api {GET} + * @apiGroup Finclip App Manager + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ +func DeleteTypeConfig(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + typeConfigID := c.Param("typeConfigId") + administratorID := c.Query("administratorId") + if typeConfigID == "" { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + if administratorID == "" { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + svr := service.NewTypeConfigService() + err := svr.Delete(traceCtx, typeConfigID) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, nil) + return + } + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} diff --git a/application/wechat_info.go b/application/wechat_info.go new file mode 100644 index 0000000..3bd184e --- /dev/null +++ b/application/wechat_info.go @@ -0,0 +1,95 @@ +package application + +import ( + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/utility" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +/** + * @api {POST} /api/v1/mop/finstore/dev/wechat/info [C/S]生成离线包下载信息 + * @apiGroup Finclip App Manager + * @apiParam (RequestBody) {string} appId //小程序id + * @apiParam (RequestBody) {string} wechatAppSecret //微信密钥 + * @apiParam (RequestBody) {string} wechatAppId //微信appid + * @apiParam (RequestBody) {string} wechatPath //微信访问path + * @apiParam (RequestBody) {string} wechatSize //尺寸 + * @apiParamExample {json} Request-Example: + * { + * "appId":"61b32654659d2b00016264a8", + * "seq": 1, + * "wechatAppSecret":"3534534" + * "wechatAppId":"23345", + * "wechatPath":"sfsgfd", + * "wechatSize":"345" + * } + * @apiSuccessExample {json} Success Status: + * HTTP/1.1 200 OK + * { + * "data": {}, + * "errcode": "OK", + * "error": "" + * } + * @apiErrorExample Error Status: + * HTTP/1.1 !=200 服务端异常 + */ + +func UpdateWechatInfo(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := httpcall.UpdateWechatInfoReq{} + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("UpdateWechatInfo bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + errCode, err := hCaller.UpsertWeChatInfo(traceCtx, req) + if err != nil { + utility.MakeLocRsp(c, http.StatusBadRequest, errCode, nil) + return + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil) + return +} + +func ReadWechatHint(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + req := httpcall.ReadWechatHintoReq{} + developerID := c.Request.Header.Get("X-Consumer-Custom-ID") + if err := c.ShouldBindJSON(&req); err != nil { + log.Errorf("ReadWechatHint bind err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_BAD_JSON, nil) + return + } + req.DeveloperId = developerID + err := hCaller.ReadWechatHint(traceCtx, req) + if err != nil { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SERVER_ERR, nil) + return + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, nil) + return + +} + +func GetAppByWechat(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + qrcode := c.Query("qrcode") + if strings.TrimSpace(qrcode) == "" { + utility.MakeLocRsp(c, http.StatusOK, utility.OK, "") + return + } + appId, err := hCaller.GetAppByWechat(traceCtx, qrcode) + if err != nil { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_SERVER_ERR, "") + return + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, appId) + return +} diff --git a/domain/domain.go b/domain/domain.go new file mode 100644 index 0000000..5e88a5f --- /dev/null +++ b/domain/domain.go @@ -0,0 +1,26 @@ +package domain + +import ( + "context" + "finclip-app-manager/domain/script" + "fmt" +) + +/** +* DDD: domain 领域层 +* 领域层主要负责表达业务概念,业务状态信息和业务规则。 +* domain层是整个系统的核心层,几乎全部的业务逻辑会在该层实现。 +* 领域模型层主要包含以下的内容: +* 实体(Entities):具有唯一标识的对象。 +* 值对象(Value Objects): 无需唯一标识的对象。 +* 领域服务(Domain Services): 一些行为无法归类到实体对象或值对象上,本质是一些操作,而非事物。 +* 聚合/聚合根(Aggregates,Aggregate Roots): 聚合是指一组具有内聚关系的相关对象的集合,每个聚合都有一个root和boundary。 +* 工厂(Factories): 创建复杂对象,隐藏创建细节。 +* 仓储(Repository): 提供查找和持久化对象的方法。 +**/ + +func Start() { + fmt.Printf("script start...\n") + ctx := context.Background() + go script.NewAutoReviewApp().ReviewApps(ctx) +} diff --git a/domain/entity/app.go b/domain/entity/app.go new file mode 100644 index 0000000..1ad0996 --- /dev/null +++ b/domain/entity/app.go @@ -0,0 +1,123 @@ +package entity + +// Unpublish current sequence due to new sequence published. +const ( + TypeUnpublishedByAdmin = "UnpublishedByAdmin" + TypeUnpublishedByDev = "UnpublishedByDev" + TypeUnpublishedDueToNewSeq = "UnpublishedDueToNewSeq" +) + +const ( + APP_FORBIDDEN_NOT_STATUS = 0 + APP_FORBIDDEN_IS_STATUS = 1 + APP_FORBIDDEN_ALL_STATUS = 2 +) + +type TestInfo struct { + Account string `json:"account" bson:"account"` + Password string `json:"password" bson:"password"` + Description string `json:"description" bson:"description"` + Images []string `json:"images" bson:"images"` +} + +//App 小程序元信息 +type App struct { + AppID string `json:"appId" bson:"appId"` //id + Name string `json:"name" bson:"name"` //名字 + Sequence int `json:"sequence" bson:"sequence"` //版本号 + AppClass string `json:"appClass" bson:"appClass"` //用途 现在改为分类 + AppTag []string `json:"appTag" bson:"appTag"` //标签 + AppType string `json:"appType" bson:"appType"` //应用类型--mop使用为了和应用市场区分开 + Status Status `json:"status" bson:"status"` //状态 + PublishedStatus SpecificStatus `json:"publishedStatus" bson:"publishedStatus"` //上架 + UnpublishedStatus SpecificStatus `json:"unpublishedStatus" bson:"unpublishedStatus"` //下架 + ActionStatus SpecificStatus `json:"actionStatus" bson:"actionStatus"` //上下架 + DeveloperID string `json:"developerId" bson:"developerId"` //开发者id + GroupID string `json:"groupId" bson:"groupId"` //组id + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + CustomData CustomDataInfo `json:"customData" bson:"customData"` //预留 + Version string `json:"version" bson:"version"` //应用版本 + CoreDescription string `json:"coreDescription" bson:"coreDescription"` //小程序简介 + Logo string `json:"logo" bson:"logo"` //图标 + TestInfo TestInfo `json:"testInfo" bson:"testInfo"` //测试信息 + Expire int64 `json:"expire" bson:"expire"` + IsRollback bool `json:"isRollback" bson:"isRollback"` // 是否回滚发布 + ApplyStatus string `json:"applyStatus" bson:"-"` // 关联审核状态 + IsForbidden int `json:"isForbidden" bson:"isForbidden"` //是否禁用 0:未禁用 1:禁用 + PrivacySettingType int `json:"privacySettingType" bson:"privacySettingType"` //是否设置隐私 0:未设置 1:自定义内容 2:默认 + ProjectType int `json:"projectType" bson:"projectType"` //项目类型,默认 0,代表小程序,1 小游戏,2 H5 +} + +//AppVersion 小程序版本信息 +type AppVersion struct { + AppID string `json:"appId" bson:"appId"` + Name string `json:"name" bson:"name"` + AppClass string `json:"appClass" bson:"appClass"` //用途 现在改为分类 + AppTag []string `json:"appTag" bson:"appTag"` //标签 + AppType string `json:"appType" bson:"appType"` + Status Status `json:"status" bson:"status"` + PublishingStatus SpecificStatus `json:"publishingStatus" bson:"publishingStatus"` //提交上架审核 + UnpublishingStatus SpecificStatus `json:"unpublishingStatus" bson:"unpublishingStatus"` //下架审核 + PublishingApprovalStatus SpecificStatus `json:"publishingApprovalStatus" bson:"publishingApprovalStatus"` //管理员审核上架记录 + UnpublishingApprovalStatus SpecificStatus `json:"unpublishingApprovalStatus" bson:"unpublishingApprovalStatus"` //管理员审核下架记录 + PublishedStatus SpecificStatus `json:"publishedStatus" bson:"publishedStatus"` //执行上架记录 + UnpublishedStatus UnpublishedStatus `json:"unpublishedStatus" bson:"unpublishedStatus"` //执行下架记录 + RequestStatus SpecificStatus `json:"requestStatus" bson:"requestStatus"` //合并开发者申请上下架状态 + ApprovalStatus SpecificStatus `json:"approvalStatus" bson:"approvalStatus"` //合并管理员申请上下架状态 + ActionStatus SpecificStatus `json:"actionStatus" bson:"actionStatus"` //执行上下架合并 + DeveloperID string `json:"developerId" bson:"developerId"` + GroupID string `json:"groupId" bson:"groupId"` + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` // 提交审核的用户 + CustomData CustomDataInfo `json:"customData" bson:"customData"` + Version string `json:"version" bson:"version"` + Sequence int `json:"sequence" bson:"sequence"` + CorporationID string `json:"corporationId" bson:"corporationId"` //与groupid类似 + CoreDescription string `json:"coreDescription" bson:"coreDescription"` + Logo string `json:"logo" bson:"logo"` + IsRollback bool `json:"isRollback" bson:"isRollback"` + TestInfo TestInfo `json:"testInfo" bson:"testInfo"` + NeedAutoPub bool `json:"needAutoPub" bson:"needAutoPub"` + InGrayRelease bool `json:"inGrayRelease" bson:"inGrayRelease"` //是否在灰度发布中 + Expire int64 `json:"expire" bson:"expire"` + AppBuildID string `json:"appBuildID" bson:"appBuildID"` +} + +type SubmitAppReq struct { + AppId string + BuildId string + Account string + NeedAutoPub bool + TestInfo TestInfo + UserId string +} + +type AppClassPerRsp struct { + Class string `bson:"class"` + Count int `bson:"count"` + Name []string `bson:"name"` +} + +type AdminGetLinkAppsRspItem struct { + Id string `json:"_id"` + AppIdDetail struct { + AppId string `json:"appId"` + Name string `json:"name"` + Sequence int `json:"sequence"` + } `json:"appIdDetail"` + AppInfos struct { + AssociatedAt int64 `json:"associatedAt"` + } `json:"appInfos"` + BindingId string `json:"bindingId"` + GroupName string `json:"groupName"` + Name string `json:"name"` +} + +type CItem struct { + Id string `json:"_id" bson:"_id"` +} + +type TagItem struct { + Id []string `json:"_id" bson:"_id"` +} diff --git a/domain/entity/app_build_info.go b/domain/entity/app_build_info.go new file mode 100644 index 0000000..78618d9 --- /dev/null +++ b/domain/entity/app_build_info.go @@ -0,0 +1,24 @@ +package entity + +const ( + APP_BUILD_SOURCE_BUILD = "build" + APP_BUILD_SOURCE_TRIAL = "trial" +) + +//AppStartParams 小程序启动参数 +type AppBuildInfo struct { + Id string `json:"id"` + BuildInfoId string `json:"buildInfoId"` + Source string `json:"source"` // 该上传版本的状态: build:正常版本, trail:被设置为体验版 + AppID string `json:"appId"` + GroupID string `json:"groupId"` + Created int64 `json:"created"` //创建该编译版本的时间 + UserId string `json:"userId"` + CreatedBy string `json:"createdBy"` //创建人 + + CustomData CustomDataInfo `json:"customData"` + Version string `json:"version"` + //VersionDescription string `json:"versionDescription"` + StartParams AppStartParams `json:"startParams"` + Status bool `json:"status" bson:"status"` +} diff --git a/domain/entity/app_temp_info.go b/domain/entity/app_temp_info.go new file mode 100644 index 0000000..10fceed --- /dev/null +++ b/domain/entity/app_temp_info.go @@ -0,0 +1,67 @@ +package entity + +import ( + "errors" +) + +const APPTEMPINFO_DB_NAME = "appTempInfo" + +var ( + AppTempDefSequence = 1 + appTempNotFoundErr = errors.New("NOT FOUND") +) + +type AppTempInfo struct { + AppID string `json:"appId" bson:"appId"` //id + Name string `json:"name" bson:"name"` //名字 + Sequence int `json:"sequence" bson:"sequence"` //版本号 + AppClass string `json:"appClass" bson:"appClass"` //用途 + AppType string `json:"appType" bson:"appType"` //应用类型--mop使用为了和应用市场区分开 + Status Status `json:"status" bson:"status"` //状态 + DeveloperID string `json:"developerId" bson:"developerId"` //开发者id + GroupID string `json:"groupId" bson:"groupId"` //组id + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + CustomData CustomDataInfo `json:"customData" bson:"customData"` //预留 + Version string `json:"version" bson:"version"` //应用版本 + CoreDescription string `json:"coreDescription" bson:"coreDescription"` //核心描述 + Logo string `json:"logo" bson:"logo"` //图标 + ProjectType int `json:"rojectType" bson:"projectType"` //项目类型 +} + +//type IAppTempInfoRepo interface { +// Insert(ctx context.Context, info *AppTempInfo) error +// UpdateInfo(ctx context.Context, info *AppTempInfo) error +// GetInfoByAppId(ctx context.Context, appId string) (*AppTempInfo, error) +// GetInfoByAppIdAndSeq(ctx context.Context, appId string, seq int) (*AppTempInfo, error) +// NotFound(err error) bool +//} +// +//func NewDefaultInfo(appId string) *AppTempInfo { +// now := time.Now().UnixNano() / 1e6 +// return &AppTempInfo{ +// AppID: appId, +// Name: "", +// Sequence: AppTempDefSequence, +// AppClass: "Others", +// AppType: "Applet", +// Status: Status{ +// Value: "Published", +// Reason: "ide测试", +// LastUpdated: now, +// ModifiedBy: "ide测试", +// }, +// DeveloperID: "", +// GroupID: "", +// Created: now, +// CreatedBy: "", +// CustomData: CustomDataInfo{ +// DetailDescription: "ide测试小程序", +// VersionDescription: "ide测试小程序", +// SourceFile: make([]CustomDataSourceFile, 0), +// }, +// Version: "1.0.0", +// CoreDescription: "ide测试小程序", +// Logo: "", +// } +//} diff --git a/domain/entity/binding.go b/domain/entity/binding.go new file mode 100644 index 0000000..24da24b --- /dev/null +++ b/domain/entity/binding.go @@ -0,0 +1,119 @@ +package entity + +import ( + "time" + + "github.com/patrickmn/go-cache" +) + +const BINDING_DB_NAME = "binding" +const BUNDLEINFO_DB_NAME = "bundleInfo" + +const ( + BUNDLE_ID_LIMITI = 2 + BINGING_PLATFORM_ORGAN = 0 + BINGING_PLATFORM_OPER = 1 + BINGING_PLATFORM_ALL = 2 + BINGING_NOT_AUTO_BIND = 0 + BINGING_AUTO_BIND = 1 +) + +var SdkExiCache *cache.Cache + +func init() { + SdkExiCache = cache.New(24*time.Hour, time.Hour) +} + +type BundleInfo struct { + //Id uint64 `json:"id" bson:"id"` + BundleID string `json:"bundleId" bson:"bundleId"` + Remark string `json:"remark" bson:"remark"` + SDKKey string `json:"SDKKey" bson:"SDKKey"` + SDKID string `json:"SDKID" bson:"SDKID"` + IsFirstCreate bool `json:"isFirstCreate" bson:"isFirstCreate"` //是否第一次创建 + CreatedAt int64 `json:"createdAt" bson:"createdAt"` + CreatedAccount string `json:"createdAccount" bson:"createdAccount"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + IsForbidden int `json:"isForbidden" bson:"isForbidden"` + IsReview int `json:"-" bson:"-"` +} + +type CreatedInfo struct { + CreatedBy string `json:"createdBy" bson:"created_by"` + CreatedAt int64 `json:"createdAt" bson:"created_at"` + CreatedAccount string `json:"createdAccount" bson:"created_account"` +} + +type AppInfo struct { + //Id uint64 `json:"id" bson:"id"` + AppID string `json:"appId" bson:"appId"` + AssociatedAt int64 `json:"associatedAt" bson:"associatedAt"` + AssociatedBy string `json:"associatedBy" bson:"associatedBy"` +} + +//应用维度 +type Binding struct { + BindingID string `json:"bindingId" bson:"bindingId"` //应用的id + Name string `json:"name" bson:"name"` //应用名称 + BundleInfos []BundleInfo `json:"bundleInfos" bson:"bundleInfos"` //bundle ids + CreatedInfo CreatedInfo `json:"createdInfo" bson:"createdInfo"` //创建信息 + GroupID string `json:"groupId" bson:"groupId"` //企业ID + GroupName string `json:"groupName" bson:"groupName"` //企业名称(为了查询) + CooperateStatus Status `json:"cooperateStatus" bson:"cooperateStatus"` //合作状态 + CooperateValidStatus SpecificStatus `json:"cooperateValidStatus" bson:"cooperateValidStatus"` //合作状态详情 + CooperateInvalidStatus SpecificStatus `json:"cooperateInvalidStatus" bson:"cooperateInvalidStatus"` //解除合作状态详情 + AppInfos []AppInfo `json:"appInfos" bson:"appInfos"` //appid 的信息 + Owner string `json:"owner" bson:"owner"` //所属企业 + Expire int64 `json:"expire" bson:"expire"` + ApiServer string `json:"apiServer" bson:"apiServer"` //子域名 + 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 +} + +//type IBindingRepo interface { +// GetInfo(ctx context.Context, bindingId string) (*Binding, error) +// GetByGroupIdAndName(ctx context.Context, groupId string, name string) (*Binding, error) +// GetByApiServer(ctx context.Context, apiServer string) (*Binding, error) +// GetBindingsByAppIdAndSdkKey(ctx context.Context, appId, sdkKey string) (*Binding, error) +// GetInfoBySdkKeyOrganId(ctx context.Context, organId, sdkKey string) (*Binding, error) +// GetAllSdkKey(ctx context.Context, organId string) ([]string, error) +// GetBindListBySdkKey(ctx context.Context, sdkKey string) ([]Binding, error) +// SdkKeyExi(ctx context.Context, sdkKey string) (bool, error) +// Insert(ctx context.Context, bind *Binding) error +// Count(ctx context.Context) (int, error) +// GetBundleIdNum(ctx context.Context) (int, error) +// NotFound(err error) bool +//} +// +//func IsAssAppId(info *Binding, appId string) bool { +// if info == nil { +// return false +// } +// for _, a := range info.AppInfos { +// if a.AppID == appId { +// return true +// } +// } +// return false +//} + +type BindingUsed struct { + LimitNum int `json:"limitNum"` + HasUseNum int `json:"hasUseNum"` + RemainNum int `json:"remainNum"` +} + +type ReviewBundleInfo struct { + BindingId string `json:"bindingId"` + CreatedInfoAt int64 `json:"createdInfoAt"` + Name string `json:"name"` + Status string `json:"status"` + BundleID string `json:"bundleId"` + Remark string `json:"remark"` + SDKKey string `json:"sdkKey"` + SDKID string `json:"sdkId"` + IsForbidden int `json:"isForbidden"` //是否禁用 0:未禁用 1:禁用 + IsReview int `json:"isReview"` +} diff --git a/domain/entity/bundle.go b/domain/entity/bundle.go new file mode 100644 index 0000000..7e16bde --- /dev/null +++ b/domain/entity/bundle.go @@ -0,0 +1,15 @@ +package entity + +//Bundle 私有化环境下bundle管理由运营端管理,这里新建一个表来处理 +//机构端创建应用时,只需要选择其中一个,选择之后会重新生成一个新的bundleInfo与应用关联 +type Bundle struct { + BundleID string `json:"bundleId" bson:"bundleId"` + Remark string `json:"remark" bson:"remark"` + SDKKey string `json:"SDKKey" bson:"SDKKey"` + SDKID string `json:"SDKID" bson:"SDKID"` + IsFirstCreate bool `json:"isFirstCreate" bson:"isFirstCreate"` //是否第一次创建 + CreatedAt int64 `json:"createdAt" bson:"createdAt"` + CreatedAccount string `json:"createdAccount" bson:"createdAccount"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + IsForbidden int `json:"isForbidden" bson:"isForbidden"` //0:可用 1:禁用 +} diff --git a/domain/entity/const.go b/domain/entity/const.go new file mode 100644 index 0000000..18a4d05 --- /dev/null +++ b/domain/entity/const.go @@ -0,0 +1,187 @@ +package entity + +import "errors" + +var ( + NotFoundErr = errors.New("not found") +) + +const ( + ACCOUNT_ID_HEADER_KEY = "X-Consumer-Custom-Id" + SDKKEY_HEADER_KEY = "mop-sdk-key" + SDKEY_VER_HEADER_KEY = "mop-sdk-version" +) + +const ( + APP_MARKET_TYPE_FINANCE = "金融" + APP_MARKET_TYPE_TOOL = "工具" + APP_MARKET_TYPE_INFORMATION = "资讯" + APP_MARKET_TYPE_OTHER = "其他" +) +const ( + AppTypeBot = "Bot" + AppTypeWeb = "Web" + AppTypeApplet = "Applet" +) + +const ( + ErrFake = "fake error" +) + +const ( + ENV_UAT = "mop-uat" + ENV_PRIVATE = "mop-private" + ENV_FDEP = "mop-fdep" + ENV_COMMUNITY = "mop-community" +) + +const ( + ScopeUserInfo = "user-info" + ScopeMessageSending = "message-sending" + ScopeProfile = "profile" + ScopeEmail = "email" +) + +const ( + StKeyPublishingApprovalStatus = "publishingApprovalStatus" + StKeyUnpublishingApprovalStatus = "unpublishingApprovalStatus" +) + +const ( + OpCreate = "Create" + OpUpdate = "Update" + OpDelete = "Delete" + + OpSubmitPublishReq = "Submit publish request" + OpWithdrawPublishReq = "Withdraw publish request" + OpPublish = "Publish" + OpApprovePublishReq = "Approve publish request" + OpRejectPublishReq = "Reject publish request" + + OpSubmitUnpublishReq = "Submit unpublish request" + OpWithdrawUnpublishReq = "Withdraw unpublish request" + OpUnpublish = "Unpublish" + OpApproveUnpublishReq = "Approve unpublish request" + OpRejectUnpublishReq = "Reject unpublish request" +) + +var AppOperationMap = map[string]string{ + OpCreate: "创建应用", + OpUpdate: "更新应用", + OpDelete: "删除应用", + OpSubmitPublishReq: "提交上架申请", + OpWithdrawPublishReq: "撤回上架申请", + OpPublish: "上架", + OpApprovePublishReq: "通过上架申请", + OpRejectPublishReq: "驳回上架申请", + OpSubmitUnpublishReq: "提交下架申请", + OpWithdrawUnpublishReq: "撤回下架申请", + OpUnpublish: "下架", + OpApproveUnpublishReq: "通过下架申请", + OpRejectUnpublishReq: "驳回下架申请", +} + +const ( + OpBindingAssociate = "Associate" + OpBindBundle = "BindBundle" + OpUpdateBundle = "UpdateBundle" + + OpBindingDisassociate = "Disassociate" + OpBindingRecooperate = "Recooperate" + OpBindingDiscooperate = "Discooperate" + OpBindingModifyName = "ModifyName" + + OpBindingApplyAssociate = "ApplyAssociate" + + OpBindingAutoBind = "AutoBind" + OpBindingHiddenBundle = "HiddenBundle" + + OpBindingReviewAdd = "add" + OpBindingReviewRemove = "remove" + + OpMoveBundle = "MoveBundle" +) + +var BindingOperationMap = map[string]string{ + OpBindingAssociate: "关联小程序", + OpBindingDisassociate: "取消关联小程序", + OpBindingRecooperate: "恢复合作", + OpBindingDiscooperate: "取消合作", + OpBindingModifyName: "修改应用名称", + + OpBindingApplyAssociate: "申请关联小程序", +} + +const ( + StLinkAuditApplying = "Applying" + StLinkAuditRejected = "Rejected" + StLinkAuditApplied = "Applied" +) + +const ( + StLinkAuditAssociate = "Associated" + StLinkAuditUnAssociate = "UnAssociated" +) + +const ( + StBindValid = "Valid" + StBindInvalid = "Invalid" +) + +const ( + BuildInfoTypeTrial = "trial" + BuildInfoTypeTemporary = "temporary" + BuildInfoTypeReview = "review" + BuildInfoTypeRelease = "release" + BuildInfoTypeDevelopment = "development" + BuildInfoTypeRomoteDebug = "remoteDebug" //真机调试版 +) + +var BindingStatusMap = map[string]string{ + StBindValid: "已合作", + StBindInvalid: "已取消合作", +} + +const ( + StInDevelopment = "InDevelopment" // 开发中,客户端不感知 + StPublishing = "Publishing" // 上架审核中 + StPublishWithdrawed = "PublishWithdrawed" // 上架审核已撤回 + StPublishApproved = "PublishApproved" // 上架审核已通过 + StPublishRejected = "PublishRejected" // 上架审核已拒绝 + StPublished = "Published" // 已上架 + StUnpublishing = "Unpublishing" // 下架审核中 + StUnpublishApproved = "UnpublishApproved" // 下架审核已通过 + StUnpublishRejected = "UnpublishRejected" // 下架审核已拒绝 + StUnpublished = "Unpublished" // 已下架 + StDeleted = "Deleted" // 已删除,客户端不感知 + StGrayPublished = "StGrayPublished" //灰度发布中 +) + +var AppStatusMap = map[string]string{ + StInDevelopment: "开发中", + StPublishing: "上架申请审核中", + StPublishWithdrawed: "上架申请已撤回", + StPublishApproved: "上架申请已通过", + StPublishRejected: "上架申请已驳回", + StPublished: "已上架", + StUnpublishing: "下架申请审核中", + StUnpublishApproved: "下架申请已通过", + StUnpublishRejected: "下架申请已驳回", + StUnpublished: "已下架", + StDeleted: "已删除", +} + +const ( + StOwnershipInstalled = "Installed" + StOwnershipUninstalled = "Uninstalled" +) + +const ( + PLATFORM_ANDROID = "android" + PLATFORM_IOS = "ios" + PLATFROM_IOS_ANDROID = "ios_android" +) + +func NotFound(err error) bool { + return err == ErrNotFound +} diff --git a/domain/entity/entity.go b/domain/entity/entity.go new file mode 100644 index 0000000..897d694 --- /dev/null +++ b/domain/entity/entity.go @@ -0,0 +1,7 @@ +package entity + +/** +* DDD: domain 领域层-实体 +* 实体(Entities):具有唯一标识的对象。 +* 聚合/聚合根(Aggregates,Aggregate Roots): 聚合是指一组具有内聚关系的相关对象的集合,每个聚合都有一个root和boundary。 +**/ diff --git a/domain/entity/file.go b/domain/entity/file.go new file mode 100644 index 0000000..bd2c0b6 --- /dev/null +++ b/domain/entity/file.go @@ -0,0 +1,9 @@ +package entity + +type File struct { + FileID string `json:"fileId" bson:"fileId"` + Name string `json:"name" bson:"name"` + UploadDate int64 `json:"uploadDate" bson:"uploadDate"` + Size int64 `json:"size" bson:"size"` + Url string `json:"url" bson:"url"` +} diff --git a/domain/entity/link_audit.go b/domain/entity/link_audit.go new file mode 100644 index 0000000..28c05cf --- /dev/null +++ b/domain/entity/link_audit.go @@ -0,0 +1,19 @@ +package entity + +type LinkAudit struct { + AuditId string `json:"auditId" bson:"auditId"` //id + Version int `json:"version" bson:"version"` //审核序号 + AppId string `json:"appId" bson:"appId"` //应用名称 + AppName string `json:"appName" bson:"appName"` //应用名称 + BindingId string `json:"bindingId" bson:"bindingId"` //应用名称 + BindingName string `json:"bindingName" bson:"bindingName"` //应用名称 + GroupID string `json:"groupId" bson:"groupId"` //企业ID + Owner string `json:"owner" bson:"owner"` //所属企业 + ApplyBy string `json:"applyBy" bson:"applyBy"` // 申请人 + ApplyStatus string `json:"applyStatus" bson:"applyStatus"` // 审核状态 + ApplyAt int64 `json:"applyAt" bson:"applyAt"` // timestamp + AuditBy string `json:"auditBy" bson:"auditBy"` // 审核人 + AuditAt int64 `json:"auditAt" bson:"auditAt"` // 审核人 + AssociateStatus string `json:"associateStatus" bson:"associateStatus"` //绑定状态 + Reason string `json:"reason" bson:"reason"` //原因 +} diff --git a/domain/entity/menu_info.go b/domain/entity/menu_info.go new file mode 100644 index 0000000..77ff522 --- /dev/null +++ b/domain/entity/menu_info.go @@ -0,0 +1,44 @@ +package entity + +import ( + "errors" +) + +var ( + MenuIdOrNameExiErr = errors.New("ID OR Name exists") + MenuLockKey = "mop_app_manage_svr_menu_lock_key" +) + +type MenuInfo struct { + TraceId string `bson:"traceId" json:"traceId"` + Name string `bson:"name" json:"name"` + InfoId string `bson:"infoId" json:"infoId"` + ImageUrl string `bson:"imageUrl" json:"imageUrl"` + SortNum int `bson:"sortNum" json:"sortNum"` + CreateTime int64 `bson:"createTime" json:"createTime"` + UpdateTime int64 `bson:"updateTime" json:"updateTime"` + UpdateOperator string `bson:"updateOperator" json:"updateOperator"` +} + +//type IMenuInfoRepo interface { +// GetInfoByTraceId(ctx context.Context, id string) (*MenuInfo, error) +// GetAllMenuList(ctx context.Context, sort []string) ([]MenuInfo, int, error) +// Add(ctx context.Context, info *MenuInfo) error +// GetNextSortNum(ctx context.Context) (int, error) +// DelByTraceId(ctx context.Context, id string) error +// UpdateInfo(ctx context.Context, id string, info *MenuInfo) error +// AllCount(ctx context.Context) (int, error) +// Sort(ctx context.Context, req *apiproto.MenuSortReq) error +// NotFound(err error) bool +//} +// +//func Lock(ctx context.Context, t time.Duration) error { +// notExi, _ := utils.Setnx(ctx, MenuLockKey, "ok", int(t.Seconds())) +// if notExi { +// return nil +// } +// return errors.New("try lock err") +//} +//func Unlock(ctx context.Context) error { +// return fcredis.Client().Del(ctx, MenuLockKey).Err() +//} diff --git a/domain/entity/privacy_setting.go b/domain/entity/privacy_setting.go new file mode 100644 index 0000000..73c697b --- /dev/null +++ b/domain/entity/privacy_setting.go @@ -0,0 +1,48 @@ +package entity + +type SdkMessageInfoObj struct { + Name string `json:"name"` //名称 + Provider string `json:"provider"` //提供方 +} + +type ContactInfoObj struct { + Phone string `json:"phone"` //电话 + Email string `json:"email"` //邮箱 + WeChat string `json:"weChat"` //微信号 + Other string `json:"other"` //其它 +} + +type UserMessageTypeObj struct { + UserMes string `json:"userMes"` //用户信息 + LocationMes string `json:"locationMes"` //位置信息 + Microphone string `json:"microphone"` //麦克风 + Camera string `json:"camera"` //摄像头 + EquipmentMes string `json:"equipmentMes"` //设备信息 + AddressBook string `json:"addressBook"` //通讯录 + PhotoAlbum string `json:"photoAlbum"` //相册 + Calendar string `json:"calendar"` //日历 + OperationLog string `json:"operationLog"` //操作日志 + Bluetooth string `json:"bluetooth"` //蓝牙 + Others string `json:"others"` //其他 + //OthersExt string `json:"othersExt"` +} + +type PrivacySettingInfo struct { + AppId string `json:"appId"` + CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况 + UserMessageType string `json:"userMessageType"` //用户使用类型 + SdkMessage string `json:"sdkMessage"` //sdk信息 + ContactInfoPhone string `json:"contactInfoPhone"` //联系方式 + ContactInfoEmail string `json:"contactInfoEmail"` //联系方式 + ContactInfoWeChat string `json:"contactInfoWeChat"` //联系方式 + ContactInfoOther string `json:"contactInfoOther"` //联系方式 + FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间 + IsShortestTime bool `json:"isShortestTime"` //是否是最短时间 + AdditionalDocName string `json:"additionalDocName"` //补充文档名称 + AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容 + AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id + IsFirstSave bool `json:"isFirstSave"` //是否第一次保存 + EffectiveTime int64 `json:"effectiveTime"` //生效时间 + CreateTime int64 `json:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime"` //更新时间 +} diff --git a/domain/entity/proto/apiproto/app.go b/domain/entity/proto/apiproto/app.go new file mode 100644 index 0000000..78e55c9 --- /dev/null +++ b/domain/entity/proto/apiproto/app.go @@ -0,0 +1,127 @@ +package apiproto + +import "finclip-app-manager/domain/entity" + +type ListAppVerReq struct { + AppId string `json:"appId" form:"appId"` + PageNo int `json:"pageNo" form:"pageNo"` + PageSize int `json:"pageSize" form:"pageSize"` + Sort string `json:"sort" form:"sort"` + IsIncludeStatus bool `json:"isIncludeStatus" form:"isIncludeStatus"` + Status string `json:"status" form:"status"` + SearchFields string `json:"searchFields" form:"searchFields"` + SearchText string `json:"searchText" form:"searchText"` + DeveloperId string `json:"developerId" from:"developerId"` +} + +type AdminGetAppReviewsReq struct { + PageNo int `form:"pageNo"` + PageSize int `form:"pageSize"` + SearchText string `form:"searchText"` + Status string `form:"status"` +} + +type UpdateAppUpinfo struct { + CustomData entity.CustomDataInfo `json:"customData"` + Version string `json:"version"` + Status bool `json:"status"` +} + +type UpdateAppInfoReq struct { + AppId string `json:"appId"` + BuildInfoId string `json:"buildInfoId"` + UserId string `json:"userId"` + Username string `json:"username"` + UpInfo UpdateAppUpinfo `json:"upInfo"` +} + +type SubmitPublishReqest struct { + Id string `json:"id"` // AppBuildID + AppID string `json:"appId" bson:"appId"` + DeveloperID string `json:"developerId" bson:"developerId"` + NeedAutoPub bool `json:"needAutoPub" bson:"needAutoPub"` + TestInfo entity.TestInfo `json:"testInfo"` +} + +type ApproveAppReq struct { + AppID string `json:"appId"` + Sequence int `json:"sequence"` + //AdministratorID string `json:"administratorId" bson:"administratorId"` + Status string `json:"status"` + Reason string `json:"reason"` + RequestFrom string `json:"requestFrom"` +} + +type ListAppsToBindReq struct { + BindingId string `form:"bindingId"` + SearchText string `form:"searchText"` + SearchFields string `form:"searchFields"` + PageSize int `form:"pageSize"` + PageNo int `form:"pageNo"` +} + +type BatchAppsByIdentityReq struct { + Source string `json:"source"` + IdentityType string `json:"identityType"` + Apps []BatchAppsByIdentityAppsItem `json:"apps"` +} + +type BatchAppsByIdentityAppsItem struct { + AppId string `json:"appId"` + Identity string `json:"identity"` +} + +type IdentityAppsCheckReq struct { + Source string `json:"source"` + IdentityType string `json:"identityType"` + Apps []IdentityAppsCheckAppsItem `json:"apps"` +} + +type IdentityAppsCheckAppsItem struct { + AppId string `json:"appId"` + Identity string `json:"identity"` +} + +type UpdateExpireInfoReq struct { + Expire int64 `json:"expire"` +} + +type SdkMessageInfoObj struct { + Name string `json:"name"` //名称 + Provider string `json:"provider"` //提供方 +} + +type ContactInfoObj struct { + Phone string `json:"phone"` //电话 + Email string `json:"email"` //邮箱 + WeChat string `json:"weChat"` //微信号 + Other string `json:"other"` //其它 +} + +type UserMessageTypeObj struct { + UserMes string `json:"userMes"` //用户信息 + LocationMes string `json:"locationMes"` //位置信息 + Microphone string `json:"microphone"` //麦克风 + Camera string `json:"camera"` //摄像头 + EquipmentMes string `json:"equipmentMes"` //设备信息 + AddressBook string `json:"addressBook"` //通讯录 + PhotoAlbum string `json:"photoAlbum"` //相册 + Calendar string `json:"calendar"` //日历 + OperationLog string `json:"operationLog"` //操作日志 + Bluetooth string `json:"bluetooth"` //蓝牙 + Others string `json:"others"` //其他 + //OthersExt string `json:"othersExt"` //其他 +} + +type PrivacySettingReq struct { + AppId string `json:"appId"` + CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况 + UserMessageType UserMessageTypeObj `json:"userMessageType"` //用户使用类型 + SdkMessage []SdkMessageInfoObj `json:"sdkMessage"` //sdk信息 + ContactInfo ContactInfoObj `json:"contactInfo"` //联系方式 + FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间 + IsShortestTime bool `json:"isShortestTime"` //是否是最短时间 + AdditionalDocName string `json:"additionalDocName"` //补充文档名称 + AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id + AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容 +} diff --git a/domain/entity/proto/apiproto/binding.go b/domain/entity/proto/apiproto/binding.go new file mode 100644 index 0000000..b912cc8 --- /dev/null +++ b/domain/entity/proto/apiproto/binding.go @@ -0,0 +1,88 @@ +package apiproto + +type CreateBundleReq struct { + BundleId string `json:"bundleId"` + Platform string `json:"platform"` + SDKKey string `json:"SDKKey" ` + SDKID string `json:"SDKID"` + IsFirstCreate bool `json:"isFirstCreate"` + CreatedAt int64 `json:"createdAt"` + CreatedAccount string `json:"createdAccount"` + CreatedBy string `json:"createdBy"` + IsForbidden int `json:"isForbidden"` + IsReview int `json:"-"` +} + +type BindingUpdateReq struct { + IsDev bool + Type string + BindingId string + AppIds []string + Reason string +} + +type ListBindingsReq struct { + PullType string `json:"pullType" form:"pullType"` + PageNo int `json:"pageNo" form:"pageNo"` + PageSize int `json:"pageSize" form:"pageSize"` + Sort string `json:"sort" form:"sort"` + SearchFields string `json:"searchFields" form:"searchFields"` + SearchText string `json:"searchText" form:"searchText"` + DeveloperId string `json:"developerId" from:"developerId"` + CooperateStatus string `json:"cooperateStatus" form:"cooperateStatus,default=all"` + Platform int `json:"platform" form:"platform,default=2"` +} + +type DevListBindingReq struct { + PullType string + SortType string + PageNo int + PageSize int + SearchTxt string + BindStatus string + UserId string + Platform int +} + +type GetBindingsByAppIdReq struct { + PageNo int `json:"pageNo" form:"pageNo"` + PageSize int `json:"pageSize" form:"pageSize"` + AppId string `json:"appId" form:"appId"` +} + +type BindingUpdateRequest struct { + BindingID string `json:"bindingId" bson:"bindingId"` + Operation string `json:"operation" bson:"operation"` + AppIDs []string `json:"appIds" bson:"appIds"` + AppName string `json:"appName" bson:"appName"` + Owner string `json:"owner" bson:"owner"` + BundlesInfo []CreateBundleReq `json:"bundleInfos" bson:"bundleInfos"` + AddLimitNum int `json:"addLimitNum" bson:"addLimitNum"` + AutoBind int `json:"autoBind"` + HiddenBundle int `json:"hiddenBundle"` + Reason string `json:"reason"` + ToBindingID string `json:"toBindingId"` +} + +type SyncOrganBindingReq struct { + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + Operation string `json:"operation"` +} + +type ListReviewBundleReq struct { + SearchText string `json:"searchText" form:"searchText"` + PageSize int `json:"pageSize" form:"pageSize"` + PageNo int `json:"pageNo" form:"pageNo"` + Type int `json:"type" form:"type"` +} + +type BundleReviewItem struct { + BindingId string `json:"bindingId"` + BundleId string `json:"bundleId"` +} + +type UpdateReviewBundleReq struct { + Operation string `json:"operation"` + Reviews []BundleReviewItem `json:"reviews"` +} diff --git a/domain/entity/proto/apiproto/menu.go b/domain/entity/proto/apiproto/menu.go new file mode 100644 index 0000000..be4aed7 --- /dev/null +++ b/domain/entity/proto/apiproto/menu.go @@ -0,0 +1,36 @@ +package apiproto + +type AddMenuReq struct { + Name string `json:"name"` + ID string `json:"id"` + Image string `json:"image"` +} + +type UpdateMenuReq struct { + Name string `json:"name"` + ID string `json:"id"` + Image string `json:"image"` +} + +type GetAllMenuRspItem struct { + TraceId string `json:"traceId" ` + Name string `json:"name"` + ID string `json:"id" ` + Image string `json:"image" ` + SortNum int `json:"sortNum" ` + CreateTime int64 `json:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime"` //更新时间 + UpdateOperator string `json:"updateOperator"` //更新时间 +} + +type GetAllMenuRsp struct { + Total int `json:"total"` + List []GetAllMenuRspItem `json:"list"` +} + +type MenuSortReq struct { + List []struct { + TraceId string `json:"traceId"` + SortNum int `json:"sortNum"` + } `json:"list"` +} diff --git a/domain/entity/proto/apiproto/trial.go b/domain/entity/proto/apiproto/trial.go new file mode 100644 index 0000000..6e4ec41 --- /dev/null +++ b/domain/entity/proto/apiproto/trial.go @@ -0,0 +1,52 @@ +package apiproto + +type UpdateTrialAppPathReq struct { + TraceId string `json:"traceId"` + PathAndQuery string `json:"pathAndQuery"` +} + +type GetBuildAppInfoReq struct { + Type string `json:"type"` + CodeId string `json:"codeId"` +} + +type ManageReleaseInfo struct { + AppId string `json:"appId"` + Version string `json:"version"` + VersionDescription string `json:"versionDescription"` + CreateBy string `json:"createBy"` + CreateAt int64 `json:"createAt"` +} +type ManageTrialInfo struct { + CodeId string `json:"codeId"` + Version string `json:"version"` + VersionDescription string `json:"versionDescription"` + CreateBy string `json:"createBy"` + CreateAt int64 `json:"createAt"` + QrcodeSign string `json:"qrcodeSign"` +} +type ManageDevInfo struct { + List []ManageDevInfoItem `json:"list"` + Total int `json:"total"` +} +type ManageDevInfoItem struct { + CodeId string `json:"codeId"` + Version string `json:"version"` + VersionDescription string `json:"versionDescription"` + CreateBy string `json:"createBy"` + CreateAt int64 `json:"createAt"` + QrcodeSign string `json:"qrcodeSign"` +} + +type GetManageAppVerListRspData struct { + ReleaseInfo *ManageReleaseInfo `json:"releaseInfo"` + TrialInfo *ManageTrialInfo `json:"trialInfo"` + DevInfo *ManageDevInfo `json:"devInfo"` + ApiServer string `json:"apiServer"` +} + +type GetManageAppListRspDataItem struct { + AppId string `json:"appId"` + Logo string `json:"logo"` + Name string `json:"name"` +} diff --git a/domain/entity/proto/apiproto/wechat_qrcode.go b/domain/entity/proto/apiproto/wechat_qrcode.go new file mode 100644 index 0000000..95abc49 --- /dev/null +++ b/domain/entity/proto/apiproto/wechat_qrcode.go @@ -0,0 +1,13 @@ +package apiproto + +type UpdateWechatInfoReq struct { + AppId string `json:"appId"` + WechatAppSecret string `json:"wechatAppSecret"` + WechatAppId string `json:"wechatAppId"` + WechatPath string `json:"wechatPath"` + WechatSize string `json:"wechatSize"` +} + +type DeleteWechatInfoReq struct { + AppId string `json:"appId"` +} diff --git a/domain/entity/proto/app_proto.go b/domain/entity/proto/app_proto.go new file mode 100644 index 0000000..f257c17 --- /dev/null +++ b/domain/entity/proto/app_proto.go @@ -0,0 +1,102 @@ +package proto + +type AppUpdateReq struct { + AppId string `json:"appId"` + Name string `json:"name"` + Logo string `json:"logo"` + AppClass string `json:"appClass"` + AppTag []string `json:"appTag"` + CoreDescription string `json:"coreDescription"` + CustomData struct { + DetailDescription string `json:"detailDescription"` + } `json:"customData"` +} +type AppIsForbiddenUpdateReq struct { + AppId string `json:"appId"` + IsForbidden int `json:"isForbidden"` //0:未禁用 1:禁用 +} +type CreateAppReq struct { + AppClass string `json:"appClass"` + AppTag []string `json:"appTag"` + AppType string `json:"appType"` + CoreDescription string `json:"coreDescription"` + Logo string `json:"logo"` + Name string `json:"name"` + ProjectType int `json:"projectType"` +} + +type MenuInfoRspDataItem struct { + Name string `json:"name"` + ID string `json:"id"` + Image string `json:"image"` +} + +type MenuInfoRspData struct { + Total int `json:"total"` + List []MenuInfoRspDataItem `json:"list"` +} + +type ApiInfoRspData struct { + ApiName string `json:"apiName"` + Url string `json:"url"` +} + +type RspCustomDataSourceFile struct { + FileMd5 string `json:"fileMd5"` + Name string `json:"name"` + SourceFileUrl string `json:"sourceFileUrl"` + UploadDate int64 `json:"uploadDate"` + Url string `json:"url"` + BasicPackVer string `json:"basicPackVer"` + Packages []Package `json:"packages"` +} +type AppRspDomainInfo struct { + Business map[string]interface{} `json:"business"` + Service map[string]interface{} `json:"service"` + Whitelist map[string]interface{} `json:"whitelist"` +} +type AppRuntimeDomainData struct { + Service struct { + Request []string `json:"request"` + Socket []string `json:"socket"` + Download []string `json:"download"` + Upload []string `json:"upload"` + } `json:"service"` + Business struct { + Domains []string `json:"domains"` + } `json:"business"` + Whitelist struct { + Domains []string `json:"domains"` + } `json:"whitelist"` + Blacklist struct { + Domains []string `json:"domains"` + } `json:"blacklist"` +} +type AppRspCustomData struct { + DetailDescription string `json:"detailDescription"` //小程序详细描述 + SourceFile []RspCustomDataSourceFile `json:"sourceFile"` + VersionDescription string `json:"versionDescription"` //小程序编译包版本描述 + AppRuntimeDomain AppRuntimeDomainData `json:"appRuntimeDomain"` + MenuInfo *MenuInfoRspData `json:"menuInfo"` //菜单信息 + ApiInfo *[]ApiInfoRspData `json:"apiInfo"` // 已备案接口列表 +} + +type AppRspStatus struct { + Value string `json:"value"` + Reason string `json:"reason"` + LastUpdated int64 `json:"lastUpdated"` + ModifiedBy string `json:"modifiedBy"` +} + +type WechatLoginInfo struct { + WechatOriginId string `json:"wechatOriginId"` + ProfileUrl string `json:"profileUrl"` + PhoneUrl string `json:"phoneUrl"` + PaymentUrl string `json:"paymentUrl"` + ExtUrls []ExtUrls `json:"extUrls"` +} + +type ExtUrls struct { + FieldName string `json:"fieldName"` + PageUrl string `json:"pageUrl"` +} diff --git a/domain/entity/proto/ide.go b/domain/entity/proto/ide.go new file mode 100644 index 0000000..c6f7f2e --- /dev/null +++ b/domain/entity/proto/ide.go @@ -0,0 +1,29 @@ +package proto + +type UpdateTempAppInfoReq struct { + FileMd5 string `json:"fileMd5"` + Name string `json:"name"` + SourceFileUrl string `json:"sourceFileUrl"` + UploadDate int64 `json:"uploadDate"` + Url string `json:"url"` + EncryptedUrl string `json:"encryptedUrl"` + EncryptedFileMd5 string `json:"encryptedFileMd5"` + AppName string `json:"appName"` + AppLogo string `json:"appLogo"` + Packages []Package `json:"packages"` + EncryptPackages []Package `json:"encryptPackages"` +} + +type Package struct { + Root string `json:"root" bson:"root"` + Name string `json:"name" bson:"name"` + Pages []string `json:"pages" bson:"pages"` + Independent bool `json:"independent" bson:"independent"` + Filename string `json:"filename" bson:"filename"` + FileUrl string `json:"fileUrl" bson:"fileUrl"` + FileMd5 string `json:"fileMd5" bson:"fileMd5"` +} + +type CreateTempAppInfoReq struct { + ProjectType int `json:"projectType"` +} diff --git a/domain/entity/proto/qrcode.go b/domain/entity/proto/qrcode.go new file mode 100644 index 0000000..8768b00 --- /dev/null +++ b/domain/entity/proto/qrcode.go @@ -0,0 +1,17 @@ +package proto + +type GenQrcodeReq struct { + Type string `json:"type"` + AppId string `json:"appId"` + CodeId string `json:"codeId"` + Sequence int `json:"sequence"` + ApiServer string `json:"apiServer"` + Limit string `json:"limit"` + StartParams AppStartParams `json:"startParams"` //小程序启动参数 + DebugInfo map[string]interface{} `json:"debugInfo"` //真机调试模式扩展信息 +} + +type AppStartParams struct { + Path string `json:"path"` + Query string `json:"query"` +} diff --git a/domain/entity/public.go b/domain/entity/public.go new file mode 100644 index 0000000..f1cbf4a --- /dev/null +++ b/domain/entity/public.go @@ -0,0 +1,59 @@ +package entity + +import "errors" + +var ( + ErrNotFound = errors.New("not found") +) + +//状态信息 +type Status struct { + Value string `json:"value" bson:"value"` + Reason string `json:"reason" bson:"reason"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` +} + +type SpecificStatus struct { + Reason string `json:"reason" bson:"reson"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` +} + +type UnpublishedStatus struct { + Reason string `json:"reason" bson:"reson"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` + Type string `json:"type" bson:"type"` +} + +type CustomDataSourceFile struct { + FileMd5 string `bson:"fileMd5" json:"fileMd5"` + Name string `bson:"name" json:"name"` + SourceFileUrl string `bson:"sourceFileUrl" json:"sourceFileUrl"` + UploadDate int64 `bson:"uploadDate" json:"uploadDate"` + Url string `bson:"url" json:"url"` + EncryptedUrl string `bson:"encryptedUrl" json:"encryptedUrl"` + EncryptedFileMd5 string `bson:"encryptedFileMd5" json:"encryptedFileMd5"` + EncryptedFileSha256 string `bson:"encryptedFileSha256" json:"encryptedFileSha256"` + BasicPackVer string `bson:"basicPackVer" json:"basicPackVer"` + Packages []Package `bson:"packages"` + EncryptPackages []Package `bson:"encryptPackages"` +} + +type Package struct { + Root string `json:"root" bson:"root"` + Name string `json:"name" bson:"name"` + Pages []string `json:"pages" bson:"pages"` + Independent bool `json:"independent" bson:"independent"` + Filename string `json:"filename" bson:"filename"` + FileUrl string `json:"fileUrl" bson:"fileUrl"` + FileMd5 string `json:"fileMd5" bson:"fileMd5"` +} + +type CustomDataInfo struct { + DetailDescription string `bson:"detailDescription" json:"detailDescription"` //小程序详细描述 + SourceFile []CustomDataSourceFile `bson:"sourceFile" json:"sourceFile"` + VersionDescription string `bson:"versionDescription" json:"versionDescription"` //小程序编译包版本描述 + Developer string `bson:"developer" json:"developer"` //开发者 +} diff --git a/domain/entity/qr_code_info.go b/domain/entity/qr_code_info.go new file mode 100644 index 0000000..c0b5caa --- /dev/null +++ b/domain/entity/qr_code_info.go @@ -0,0 +1,46 @@ +package entity + +const QRCODEINFO_DB_NAME = "qrCodeInfo" + +const ( + QrCodeTypeReview = "review" //审核版二维码信息 + QrCodeTypeTrial = "trial" //体验版 + QrCodeTypeTemporary = "temporary" //临时版 + QrCodeTypeRelease = "release" //线上版 + QrCodeTypeRomoteDebug = "remoteDebug" //真机调试版 +) + +//AppStartParams 小程序启动参数 +type AppStartParams struct { + PathAndQuery string `json:"pathAndQuery" bson:"path_and_query"` +} + +type QrCodeInfo struct { + Type string `json:"type" bson:"type"` //二维码的类型 + Uuid string `json:"uuid" bson:"uuid"` //标识该二维码 + AppId string `json:"appId" bson:"appId"` //小程序Id + Sequence int `json:"sequence" bson:"sequence"` //小程序序列号 + ApiServer string `json:"apiServer" bson:"apiServer"` //小程序apiServer + CodeId string `json:"codeId" bson:"codeId"` //标识某个编译版本的id + StartParams AppStartParams `json:"startParams" bson:"startParams"` //小程序启动参数 + ExpireTime int64 `json:"expireTime" bson:"expireTime"` //过期时间 + CreateTime int64 `json:"createTime" bson:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"UpdateTime"` //更新时间 + DeleteTime int64 `json:"deleteTime" bson:"DeleteTime"` //删除时间-暂不用 + DebugInfo map[string]interface{} `json:"debugInfo" bson:"debugInfo"` //拓展数据 +} + +//type IQrCodeInfoRepo interface { +// Insert(ctx context.Context, info *QrCodeInfo) error +// GenInfo(ctx context.Context, info *QrCodeInfo) error +// GetInfoByUuid(ctx context.Context, uuid string) (*QrCodeInfo, error) +// GetReviewInfo(ctx context.Context, appId string, seq int) (*QrCodeInfo, error) +// GetReleaseInfo(ctx context.Context, appId string) (*QrCodeInfo, error) +// GetTrialInfo(ctx context.Context, appId string) (*QrCodeInfo, error) +// GetTemporaryInfo(ctx context.Context, appId string, seq int) (*QrCodeInfo, error) +// UpdateTrialStartParams(ctx context.Context, codeId string, p AppStartParams) error +// UpdateApiServer(ctx context.Context, uuid string, apiServer string) error +// UpdateInfo(ctx context.Context, uuid string, upInfo map[string]interface{}) error +// GenReviewQrCodeInfo(ctx context.Context, info *QrCodeInfo) error +// NotFound(err error) bool +//} diff --git a/domain/entity/red_dot_read_record.go b/domain/entity/red_dot_read_record.go new file mode 100644 index 0000000..1fc0268 --- /dev/null +++ b/domain/entity/red_dot_read_record.go @@ -0,0 +1,9 @@ +package entity + +type RedDotReadRecord struct { + Type string `json:"type" bson:"type"` //红点类型 + TraceId string `json:"traceId" bson:"traceId"` //红点唯一标识 + AccountId string `json:"accountId" bson:"accountId"` //已经阅读的账户Id + CreateTime int64 `json:"createTime" bson:"createTime""` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"UpdateTime"` //更新时间 +} diff --git a/domain/entity/type_config.go b/domain/entity/type_config.go new file mode 100644 index 0000000..0d49ec2 --- /dev/null +++ b/domain/entity/type_config.go @@ -0,0 +1,146 @@ +package entity + +import "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + +const TYPECONFIG_DB_NAME = "typeConfig" + +type TypeConfigCustomData struct { + Chinese string `json:Chinese bson:Chinese` +} +type TypeConfig struct { + TypeConfigID string `json:"typeConfigId" bson:"typeConfigId"` + Namespace string `json:"namespace" bson:"namespace"` + Value string `json:"value" bson:"value"` + MarketID string `json:"marketId" bson:"marketId"` + CustomData TypeConfigCustomData `json:"customData" bson:"customData"` + SortNum int `json:"sortNum" bson:"sortNum"` +} + +//type ITypeConfigRepo interface { +// Insert(ctx context.Context, typeConfig *TypeConfig) error +// GetOne(ctx context.Context, filter bson.M) error +// Exist(ctx context.Context, namespace string, value string) (bool, error) +// Update(ctx context.Context, selector bson.M, update bson.M) error +// GetSome(ctx context.Context, filter bson.M, sort []string, pageSize, pageNo int) (int, []TypeConfig, error) +// Delete(ctx context.Context, typeConfigId string) error +// GetNowSortNumInfo(ctx context.Context) (*TypeConfig, error) +// NotFound(err error) bool +//} +// +type TypeConfigList []TypeConfig + +func (l TypeConfigList) Len() int { + return len(l) +} + +func (l TypeConfigList) Less(i, j int) bool { + return l[i].SortNum < l[j].SortNum +} + +func (l TypeConfigList) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} + +var MopCfg = []TypeConfig{ + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "jinrong", + CustomData: TypeConfigCustomData{ + Chinese: "金融", + }, + SortNum: 1, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "zixun", + CustomData: TypeConfigCustomData{ + Chinese: "资讯", + }, + SortNum: 2, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "gongju", + CustomData: TypeConfigCustomData{ + Chinese: "工具", + }, + SortNum: 3, + }, + /*{ + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "qita", + CustomData: TypeConfigCustomData{ + Chinese: "其他", + }, + SortNum: 4, + },*/ + /*{ + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "LifeService", + CustomData: TypeConfigCustomData{ + Chinese: "生活服务", + }, + SortNum: 5, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "GovernmentAffairs", + CustomData: TypeConfigCustomData{ + Chinese: "政务", + }, + SortNum: 6, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "Education", + CustomData: TypeConfigCustomData{ + Chinese: "教育", + }, + SortNum: 7, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "E-commerce", + CustomData: TypeConfigCustomData{ + Chinese: "电商", + }, + SortNum: 8, + },*/ + //"其它"要一直在最后 + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "qita", + CustomData: TypeConfigCustomData{ + Chinese: "其他", + }, + SortNum: 99990000, + }, + //研报、投教为老数据,保留下对之前做兼容,chinese修改为:投教研报 + /*{ + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "Report", + CustomData: TypeConfigCustomData{ + Chinese: "投教研报", + }, + SortNum: 99990001, + }, + { + TypeConfigID: bson.NewObjectId().Hex(), + Namespace: "appClass", + Value: "Teach", + CustomData: TypeConfigCustomData{ + Chinese: "投教研报", + }, + SortNum: 99990002, + },*/ +} diff --git a/domain/entity/wechat_info.go b/domain/entity/wechat_info.go new file mode 100644 index 0000000..d4f96c1 --- /dev/null +++ b/domain/entity/wechat_info.go @@ -0,0 +1,16 @@ +package entity + +type WechatInfo struct { + Id string `json:"id" bson:"id"` + AppID string `json:"appId" bson:"appId"` + GroupID string `json:"groupId" bson:"groupId"` + Created int64 `json:"created" bson:"created"` + Updated int64 `json:"updated" bson:"updated"` + + WechatAppSecret string `json:"wechatAppSecret" bson:"wechatAppSecret"` + WechatAppId string `json:"wechatAppId" bson:"wechatAppId"` + WechatPath string `json:"wechatPath" bson:"wechatPath"` + WechatSize string `json:"wechatSize" bson:"wechatSize"` + QrcodeUrl string `json:"qrcodeUrl" bson:"qrcodeUrl"` + QrcodeDownloadUrl string `json:"qrcodeDownloadUrl" bson:"qrcodeDownloadUrl"` +} diff --git a/domain/factory/entity/entity.go b/domain/factory/entity/entity.go new file mode 100644 index 0000000..2bf755e --- /dev/null +++ b/domain/factory/entity/entity.go @@ -0,0 +1,5 @@ +package entityFac + +/** +* DDD: domain 领域层-工厂-创建实体的工厂 +**/ diff --git a/domain/factory/factory.go b/domain/factory/factory.go new file mode 100644 index 0000000..e876ba9 --- /dev/null +++ b/domain/factory/factory.go @@ -0,0 +1,6 @@ +package factory + +/** +* DDD: domain 领域层-工厂 +* 工厂(Factories): 创建复杂对象,隐藏创建细节。 +**/ diff --git a/domain/factory/value-object/value_object.go b/domain/factory/value-object/value_object.go new file mode 100644 index 0000000..eec1550 --- /dev/null +++ b/domain/factory/value-object/value_object.go @@ -0,0 +1,5 @@ +package valueObjFac + +/** +* DDD: domain 领域层-工厂-创建值对象的工厂 +**/ diff --git a/domain/repository/app.go b/domain/repository/app.go new file mode 100644 index 0000000..442fa14 --- /dev/null +++ b/domain/repository/app.go @@ -0,0 +1,73 @@ +package repository + +import ( + "context" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gorm.io/gorm" +) + +type AppRepository interface { + AppCount(ctx context.Context, organId string) (int, error) + InsertApp(ctx context.Context, info entity.App) error + GetAppInfo(ctx context.Context, appId string) (entity.App, error) + UpdateApp(ctx context.Context, info entity.App) error + + GetAppVerInfo(ctx context.Context, appId string, seq int) (entity.AppVersion, error) + GetOnlineAppVer(ctx context.Context, appId string) (entity.AppVersion, error) + GetLatestPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) + GetLatestReviewAppVer(ctx context.Context, appId string) (entity.AppVersion, error) + GetAllPermitGrayPubVers(ctx context.Context, appId string, nowPubSeq int) ([]entity.AppVersion, error) + GetMaxSeqAppVer(ctx context.Context, appId string) (entity.AppVersion, error) + UpdateAppVerAppName(ctx context.Context, appId, appName string) error + + SubmitApp(ctx context.Context, req entity.SubmitAppReq, expire int64, userId string) error + WithdrawPubApp(ctx context.Context, appId string, seq int, account string) error + PubApp(ctx context.Context, appId string, seq int, account string, isDev, isRollback bool) error + UnpubApp(ctx context.Context, appId string, seq int, account, reason string, isDev bool) error + ListApps(ctx context.Context, groupId string, pageNo, pageSize int, searchText string, sortType, pullType string) (int, []entity.App, error) + ListAppVers(ctx context.Context, pageNo, pageSize int, searchText string, t string, groupId string) (int, []entity.AppVersion, error) + ListAppVersByAppId(ctx context.Context, appId string, pageNo, pageSize int) (int, []entity.AppVersion, error) + GetAppReviews(ctx context.Context, req apiproto.AdminGetAppReviewsReq) (int, []entity.AppVersion, error) + GetAllPublishedVerList(ctx context.Context, appId string) ([]entity.AppVersion, int, error) + GetPublishedAppList(ctx context.Context, pageNo, pageSize int, searchText string) ([]entity.AppVersion, int, error) + GetAllVers(ctx context.Context, appId string) ([]entity.AppVersion, int, error) + GetAppsByAppIds(ctx context.Context, appIds []string) ([]entity.App, error) + GetAppsByGroupIds(ctx context.Context, groupIds []string) (int, []entity.App, error) + GetAppsToBinding(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) + GetLinkAppsByBindingId(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) + GetLinkAppsBySDKKey(ctx context.Context, sdkKey string, pageNo, pageSize int) (int, []entity.App, error) + AdminGetLinkApps(ctx context.Context, pageNo, pageSize int, searchText string) (int, []entity.AdminGetLinkAppsRspItem, error) + + ApproveApp(ctx context.Context, appId string, seq int, account, reason string, isPass bool) error + GetRollbackAbleList(ctx context.Context, groupId, appId string, latestPubSeq int) ([]entity.AppVersion, error) + UpdateGrayStatus(ctx context.Context, appId string, seq int, status bool) error + + UpdateExpire(ctx context.Context, appId string, expire int64) error + UpdateExpireAppVersion(ctx context.Context, appId string, seq int, expire int64) error + //statistics + GetCreatedStatistics(ctx context.Context, startTime, endTime int64, groupId string, isForbidden int) (int, error) + GetPublishedStatistics(ctx context.Context, startTime, endTime int64, groupId string) (int, error) + GetSubmittedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) + GetApprovedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) + GetAppClassPer(ctx context.Context, status string) ([]entity.AppClassPerRsp, error) + + GetGrayStatisticsVerList(ctx context.Context, appId string, seq int, begin, end int64) (int, []entity.AppVersion, error) + + //对接wx + GetAppVerLimitByIdentity(ctx context.Context, t, appId, identity string, limit int) ([]entity.AppVersion, error) + GetAppClassList(ctx context.Context) ([]entity.CItem, error) + GetAppTagList(ctx context.Context) ([]entity.TagItem, error) + GetAppsBySearchText(ctx context.Context, searchText string) ([]entity.App, error) + GetAppByCreator(ctx context.Context, phone string) ([]entity.App, error) +} + +func NotFound(err error) bool { + return err == gorm.ErrRecordNotFound || + err == mgo.ErrNotFound || + err == entity.NotFoundErr || + err == entity.ErrNotFound || + errors.Is(err, gorm.ErrRecordNotFound) +} diff --git a/domain/repository/app_build_info.go b/domain/repository/app_build_info.go new file mode 100644 index 0000000..2327c72 --- /dev/null +++ b/domain/repository/app_build_info.go @@ -0,0 +1,25 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" +) + +type IAppBuildInfoRepo interface { + Insert(ctx context.Context, item entity.AppBuildInfo) error + GetLatestInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) + GetInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) + GetInfoByBuildInfoId(ctx context.Context, buildInfoId string) (*entity.AppBuildInfo, error) + GetTrialInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) + GetTrialInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) + AddTrial(ctx context.Context, id string) error + CancelTrial(ctx context.Context, id string) error + UpdateTrialStartParams(ctx context.Context, id string, params entity.AppStartParams) error + UpdateTrialPath(ctx context.Context, id, path string) error + UpdateOneStatus(ctx context.Context, id string, status bool) error + GetList(ctx context.Context, appId string, pageNo, pageSize int) (int64, []entity.AppBuildInfo, error) + GetAll(ctx context.Context) ([]entity.AppBuildInfo, error) + GetAppBuilds(ctx context.Context, groupID, appId string, pageSize, pageNo int) (int64, []entity.AppBuildInfo, error) + NotFound(err error) bool + GetInfoByBuildId(ctx context.Context, id string) (*entity.AppBuildInfo, error) +} diff --git a/domain/repository/app_config.go b/domain/repository/app_config.go new file mode 100644 index 0000000..28abe19 --- /dev/null +++ b/domain/repository/app_config.go @@ -0,0 +1,23 @@ +package repository + +import ( + "context" +) + +type AppOperConfig struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AutoReviewApp int `json:"autoReviewApp" bson:"auto_review_app" gorm:"column:auto_review_app;type:tinyint(4);comment:"是否自动审核小程序"` + CreateTime int64 `json:"createTime" bson:"create_time" gorm:"column:create_time;type:BIGINT(16);NOT NULL;comment:'创建时间'"` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"update_time" gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` //更新时间 + +} + +func (AppOperConfig) TableName() string { + return "app_oper_config" +} + +type IAppOperConfigRepo interface { + Insert(ctx context.Context, item AppOperConfig) error + Update(ctx context.Context, item AppOperConfig) error + Find(ctx context.Context) (AppOperConfig, error) +} diff --git a/domain/repository/app_temp_info.go b/domain/repository/app_temp_info.go new file mode 100644 index 0000000..93728ba --- /dev/null +++ b/domain/repository/app_temp_info.go @@ -0,0 +1,100 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" + "time" +) + +//const APPTEMPINFO_DB_NAME = "appTempInfo" +// +//var ( +// AppTempDefSequence = 1 +// appTempNotFoundErr = errors.New("NOT FOUND") +//) +// +//type CustomDataInfo struct { +// DetailDescription string `bson:"detail_description" json:"detailDescription"` //小程序详细描述 +// SourceFile []CustomDataSourceFile `bson:"source_file" json:"sourceFile"` +// VersionDescription string `bson:"version_description" json:"versionDescription"` //小程序编译包版本描述 +// Developer string `bson:"developer" json:"developer"` //开发者 +//} +// +//type CustomDataSourceFile struct { +// FileMd5 string `bson:"file_md5" json:"fileMd5"` +// Name string `bson:"name" json:"name"` +// SourceFileUrl string `bson:"source_file_url" json:"sourceFileUrl"` +// UploadDate int64 `bson:"upload_date" json:"uploadDate"` +// Url string `bson:"url" json:"url"` +// EncryptedUrl string `bson:"encrypted_url" json:"encryptedUrl"` +// EncryptedFileMd5 string `bson:"encrypted_file_md5" json:"encryptedFileMd5"` +// EncryptedFileSha256 string `bson:"encrypted_file_sha256" json:"encryptedFileSha256"` +// BasicPackVer string `bson:"basic_pack_ver" json:"basicPackVer"` +// Packages []Package `bson:"packages"` +// EncryptPackages []Package `bson:"encrypt_packages"` +//} +// +//type Package struct { +// Root string `json:"root" bson:"root"` +// Name string `json:"name" bson:"name"` +// Pages []string `json:"pages" bson:"pages"` +// Independent bool `json:"independent" bson:"independent"` +// Filename string `json:"filename" bson:"filename"` +// FileUrl string `json:"fileUrl" bson:"file_url"` +// FileMd5 string `json:"fileMd5" bson:"file_md5"` +//} +// +//type AppTempInfo struct { +// AppID string `json:"appId" bson:"app_id"` //id +// Name string `json:"name" bson:"name"` //名字 +// Sequence int `json:"sequence" bson:"sequence"` //版本号 +// AppClass string `json:"appClass" bson:"app_class"` //用途 +// AppType string `json:"appType" bson:"app_type"` //应用类型--mop使用为了和应用市场区分开 +// Status Status `json:"status" bson:"status"` //状态 +// DeveloperID string `json:"developerId" bson:"developer_id"` //开发者id +// GroupID string `json:"groupId" bson:"group_id"` //组id +// Created int64 `json:"created" bson:"created"` +// CreatedBy string `json:"createdBy" bson:"created_by"` +// CustomData CustomDataInfo `json:"customData" bson:"custom_data"` //预留 +// Version string `json:"version" bson:"version"` //应用版本 +// CoreDescription string `json:"coreDescription" bson:"core_description"` //核心描述 +// Logo string `json:"logo" bson:"logo"` //图标 +//} + +type IAppTempInfoRepo interface { + Insert(ctx context.Context, info *entity.AppTempInfo) error + UpdateInfo(ctx context.Context, info *entity.AppTempInfo) error + GetInfoByAppId(ctx context.Context, appId string) (*entity.AppTempInfo, error) + GetInfoByAppIdAndSeq(ctx context.Context, appId string, seq int) (*entity.AppTempInfo, error) + NotFound(err error) bool +} + +func NewDefaultInfo(appId string, projectType int) *entity.AppTempInfo { + now := time.Now().UnixNano() / 1e6 + return &entity.AppTempInfo{ + AppID: appId, + Name: "", + Sequence: entity.AppTempDefSequence, + AppClass: "Others", + AppType: "Applet", + Status: entity.Status{ + Value: "Published", + Reason: "ide测试", + LastUpdated: now, + ModifiedBy: "ide测试", + }, + DeveloperID: "", + GroupID: "", + Created: now, + CreatedBy: "", + CustomData: entity.CustomDataInfo{ + DetailDescription: "ide测试小程序", + VersionDescription: "ide测试小程序", + SourceFile: make([]entity.CustomDataSourceFile, 0), + }, + Version: "1.0.0", + CoreDescription: "ide测试小程序", + Logo: "", + ProjectType: projectType, + } +} diff --git a/domain/repository/binding.go b/domain/repository/binding.go new file mode 100644 index 0000000..47aeb9d --- /dev/null +++ b/domain/repository/binding.go @@ -0,0 +1,137 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" +) + +//const BINDING_DB_NAME = "binding" +//const BUNDLEINFO_DB_NAME = "bundleInfo" +// +//const ( +// BUNDLE_ID_LIMITI = 2 +//) +// +//var SdkExiCache *cache.Cache +// +//type Status struct { +// Value string `json:"value" bson:"value"` +// Reason string `json:"reason" bson:"reason"` +// LastUpdated int64 `json:"lastUpdated" bson:"last_updated"` +// ModifiedBy string `json:"modifiedBy" bson:"modified_by"` +//} +// +//type SpecificStatus struct { +// Reason string `json:"reason" bson:"reson"` +// LastUpdated int64 `json:"lastUpdated" bson:"last_updated"` +// ModifiedBy string `json:"modifiedBy" bson:"modified_by"` +//} +// +//type UnpublishedStatus struct { +// Reason string `json:"reason" bson:"reson"` +// LastUpdated int64 `json:"lastUpdated" bson:"last_ipdated"` +// ModifiedBy string `json:"modifiedBy" bson:"modified_by"` +// Type string `json:"type" bson:"type"` +//} +// +//type BundleInfo struct { +// BundleID string `json:"bundleId" bson:"bundle_id"` +// Remark string `json:"remark" bson:"remark"` +// SDKKey string `json:"SDKKey" bson:"sdk_key"` +// SDKID string `json:"SDKID" bson:"sdk_id"` +// IsFirstCreate bool `json:"isFirstCreate" bson:"is_first_create"` //是否第一次创建 +// CreatedAt int64 `json:"createdAt" bson:"created_at"` +// CreatedAccount string `json:"createdAccount" bson:"created_account"` +// CreatedBy string `json:"createdBy" bson:"created_by"` +//} +// +//type CreatedInfo struct { +// CreatedBy string `json:"createdBy" bson:"created_by"` +// CreatedAt int64 `json:"createdAt" bson:"created_at"` +//} +// +//type AppInfo struct { +// AppID string `json:"appId" bson:"app_id"` +// AssociatedAt int64 `json:"associatedAt" bson:"associated_at"` +// AssociatedBy string `json:"associatedBy" bson:"associated_by"` +//} +// +////应用维度 +//type Binding struct { +// BindingID string `json:"bindingId" bson:"binding_id"` //应用的id +// Name string `json:"name" bson:"name"` //应用名称 +// BundleInfos []BundleInfo `json:"bundleInfos" bson:"bundle_infos"` //bundle ids +// CreatedInfo CreatedInfo `json:"createdInfo" bson:"created_info"` //创建信息 +// GroupID string `json:"groupId" bson:"group_id"` //企业ID +// GroupName string `json:"groupName" bson:"group_name"` //企业名称(为了查询) +// CooperateStatus Status `json:"cooperateStatus" bson:"cooperate_status"` //合作状态 +// CooperateValidStatus SpecificStatus `json:"cooperateValidStatus" bson:"cooperate_valid_status"` //合作状态详情 +// CooperateInvalidStatus SpecificStatus `json:"cooperateInvalidStatus" bson:"cooperate_invalid_status"` //解除合作状态详情 +// AppInfos []AppInfo `json:"appInfos" bson:"app_infos"` //appid 的信息 +// Owner string `json:"owner" bson:"owner"` //所属企业 +// Expire int64 `json:"expire" bson:"expire"` +// ApiServer string `json:"apiServer" bson:"api_server"` //子域名 +//} + +type IBindingRepo interface { + GetInfo(ctx context.Context, bindingId string) (*entity.Binding, error) + GetByGroupIdAndName(ctx context.Context, groupId string, name string, isAdmin bool) (*entity.Binding, error) + GetByApiServer(ctx context.Context, apiServer string) (entity.Binding, error) + GetInfoByParams(ctx context.Context, sdkKey, organId, appId string) (*entity.Binding, error) + GetInfoBySdkKeyOrganId(ctx context.Context, organId, sdkKey string) (*entity.Binding, error) + GetAllSdkKey(ctx context.Context, organId string) ([]string, error) + GetBindListBySdkKey(ctx context.Context, sdkKey string) ([]entity.Binding, error) + SdkKeyExi(ctx context.Context, sdkKey string) (bool, error) + Insert(ctx context.Context, bind *entity.Binding) error + Count(ctx context.Context) (int, error) + GetCountByStatus(ctx context.Context, status string, platform int) (int, error) + GetBundleIdNum(ctx context.Context) (int, error) + GetBundleIdLimitHand(ctx context.Context, groupId string) (int, error) + GetBundleLimit(ctx context.Context) (int, error) + GetBindingByGroupIdAndBindingId(ctx context.Context, groupId string, bindingId string) (*entity.Binding, error) + GetBindingByGroupIdAndSdkKey(ctx context.Context, groupId string, sdkKey string) (*entity.Binding, error) + UpdateBundleInfosByGroupIdAndBindId(ctx context.Context, groupId string, bindingId string, infos []entity.BundleInfo) error + AppendBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error + UpdateBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error + GetByBindIdList(ctx context.Context, ids []string) ([]entity.Binding, error) + GetBindListByGroupId(ctx context.Context, groupId string, pageSize int, pageNo int) ([]entity.Binding, int, error) + UpdateByBindId(ctx context.Context, bindingId string, bind *entity.Binding) error + UpdateExpire(ctx context.Context, bindingId string, expire int64) error + BundleIdCount(ctx context.Context, groupId string) (int, error) + GetBundleByGroupIdAndBundleId(ctx context.Context, groupId string, bundleId string) (*entity.Binding, error) + GetbundlesByBundleId(ctx context.Context, bundleId string) (*entity.Binding, error) + GetBindingsBySearch(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, searchFields string, cooperateStatus string, platform int) ([]entity.Binding, int, error) + GetBindingsByAppId(ctx context.Context, pageSize int, pageNo int, appId string) ([]entity.Binding, int, error) + GetDevListBinding(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, pullType string, groupId string, bindStatus string, platform int) ([]entity.Binding, int, error) + GetBindingBySdkKey(ctx context.Context, sdkKey string) (*entity.Binding, error) + ListBindings(ctx context.Context, groupId string, searchText string, pageNo int, pageSize int) ([]entity.Binding, int, error) + GetAllAssBinds(ctx context.Context, appId string) ([]entity.Binding, error) + UpdateBundleIdIsForbidden(ctx context.Context, bundleId string) error + UpdateBundleIdPlatform(ctx context.Context, bundleId, platform string) error + UpdateRelatedBindingCooperate(ctx context.Context, bindingId string, status entity.Status, specificStatus entity.SpecificStatus, cooperate bool) error + UpdateBindingInfo(ctx context.Context, bindingId string, info map[string]interface{}, platform int) error + UpdateBindingGroupName(ctx context.Context, groupId, groupName string) error + ListAutoBindAppBinding(ctx context.Context, groupId string) ([]string, error) + ListCopyOperBinding(ctx context.Context, bindingId string) ([]string, []entity.Binding, error) + AppendApps(ctx context.Context, bindingId string, apps []entity.AppInfo) error + RemoveApps(ctx context.Context, bindingId string, appIds []string) error + UpdateBundleIsView(ctx context.Context, reviews []apiproto.BundleReviewItem, isReview int) error + ListReviewBundle(ctx context.Context, pageSize int, pageNo int, searchText string, isReview int) (int64, []entity.ReviewBundleInfo, error) + CheckReviewBySdkKey(ctx context.Context, sdkKey string) bool + GetReviewBindBySdkKey(ctx context.Context, sdkKey string) (*entity.ReviewBundleInfo, error) + UpdateBundleBindingId(ctx context.Context, bundleId, bindingId, toBindingId string) error + NotFound(err error) bool +} + +func IsAssAppId(info *entity.Binding, appId string) bool { + if info == nil { + return false + } + for _, a := range info.AppInfos { + if a.AppID == appId { + return true + } + } + return false +} diff --git a/domain/repository/bundle.go b/domain/repository/bundle.go new file mode 100644 index 0000000..01f8a16 --- /dev/null +++ b/domain/repository/bundle.go @@ -0,0 +1,19 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" +) + +type IBundleRepo interface { + Insert(ctx context.Context, bundles []entity.Bundle) error + GetListByBundleId(ctx context.Context, ids []string, pageNo int, pageSize int) (int, []entity.Bundle, error) + GetListByBundleIds(ctx context.Context, ids []string) ([]entity.Bundle, error) + ExistBundleId(ctx context.Context, bundleId string) (bool, error) + GetInfoByBundleId(ctx context.Context, bundleId string) (entity.Bundle, error) + ListAllBundleInfos(ctx context.Context, searchText string, selectType, pageNo int, pageSize int) (int, []entity.Bundle, error) + AllCount(ctx context.Context) (int, error) + UpdateBundleForbidden(ctx context.Context, bundleId string, IsForbidden int) error + UpdateBundlePlatform(ctx context.Context, bundleId, remark string) error + NotFound(err error) bool +} diff --git a/domain/repository/link_audit.go b/domain/repository/link_audit.go new file mode 100644 index 0000000..787f8a2 --- /dev/null +++ b/domain/repository/link_audit.go @@ -0,0 +1,8 @@ +package repository + +import "context" + +type ILinkAuditRepo interface { + Count(ctx context.Context, appID string, groupId string, bindingID string, stLinkAudit string) (int, error) + NotFound(err error) bool +} diff --git a/domain/repository/menu_info.go b/domain/repository/menu_info.go new file mode 100644 index 0000000..c7c6420 --- /dev/null +++ b/domain/repository/menu_info.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + utils "finclip-app-manager/infrastructure/cache/redis" + fcredis "gitlab.finogeeks.club/finclip-backend-v2/finclip-redis" + "time" +) + +//const MENUINFO_DB_NAME = "menuInfo" +// +//var ( +// MenuIdOrNameExiErr = errors.New("ID OR Name exists") +// MenuLockKey = "mop_app_manage_svr_menu_lock_key" +//) +// +//type MenuInfo struct { +// TraceId string `bson:"trace_id" json:"traceId"` +// Name string `bson:"name" json:"name"` +// InfoId string `bson:"info_id" json:"infoId"` +// ImageUrl string `bson:"image_url" json:"imageUrl"` +// SortNum int `bson:"sort_num" json:"sortNum"` +// CreateTime int64 `bson:"create_time" json:"createTime"` +// UpdateTime int64 `bson:"update_time" json:"updateTime"` +// UpdateOperator string `bson:"update_operator" json:"updateOperator"` +//} + +type IMenuInfoRepo interface { + GetInfoByTraceId(ctx context.Context, id string) (*entity.MenuInfo, error) + GetAllMenuList(ctx context.Context, sort []string) ([]entity.MenuInfo, int, error) + Add(ctx context.Context, info *entity.MenuInfo) error + GetNextSortNum(ctx context.Context) (int, error) + DelByTraceId(ctx context.Context, id string) error + UpdateInfo(ctx context.Context, id string, info *entity.MenuInfo) error + AllCount(ctx context.Context) (int, error) + Sort(ctx context.Context, req *apiproto.MenuSortReq) error + NotFound(err error) bool +} + +func Lock(ctx context.Context, t time.Duration) error { + notExi, _ := utils.Setnx(ctx, entity.MenuLockKey, "ok", int(t.Seconds())) + if notExi { + return nil + } + return errors.New("try lock err") +} +func Unlock(ctx context.Context) error { + return fcredis.Client().Del(ctx, entity.MenuLockKey).Err() +} diff --git a/domain/repository/privacy_setting.go b/domain/repository/privacy_setting.go new file mode 100644 index 0000000..00a0d30 --- /dev/null +++ b/domain/repository/privacy_setting.go @@ -0,0 +1,15 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" +) + +type IPrivacySettingRepo interface { + Insert(ctx context.Context, item entity.PrivacySettingInfo) error + Count(ctx context.Context, appId string) (int, error) + GetInfoByAppId(ctx context.Context, appId string) (*entity.PrivacySettingInfo, error) + UpdateInfo(ctx context.Context, info entity.PrivacySettingInfo) error + DelInfoByAppId(ctx context.Context, appId string) error + NotFound(err error) bool +} diff --git a/domain/repository/qr_code_info.go b/domain/repository/qr_code_info.go new file mode 100644 index 0000000..dcf2138 --- /dev/null +++ b/domain/repository/qr_code_info.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" +) + +//const QRCODEINFO_DB_NAME = "qrCodeInfo" +// +//const ( +// QrCodeTypeReview = "review" //审核版二维码信息 +// QrCodeTypeTrial = "trial" //体验版 +// QrCodeTypeTemporary = "temporary" //临时版 +// QrCodeTypeRelease = "release" //线上版 +//) +// +////AppStartParams 小程序启动参数 +//type AppStartParams struct { +// PathAndQuery string `json:"pathAndQuery" bson:"path_and_query"` +//} +// +//type QrCodeInfo struct { +// Type string `json:"type" bson:"type"` //二维码的类型 +// Uuid string `json:"uuid" bson:"uuid"` //标识该二维码 +// AppId string `json:"appId" bson:"app_id"` //小程序Id +// Sequence int `json:"sequence" bson:"sequence"` //小程序序列号 +// ApiServer string `json:"apiServer" bson:"api_server"` //小程序apiServer +// CodeId string `json:"codeId" bson:"code_id"` //标识某个编译版本的id +// StartParams AppStartParams `json:"startParams" bson:"start_params"` //小程序启动参数 +// ExpireTime int64 `json:"expireTime" bson:"expire_time"` //过期时间 +// CreateTime int64 `json:"createTime" bson:"create_time"` //创建时间 +// UpdateTime string `json:"updateTime" bson:"Update_time"` //更新时间 +// DeleteTime int64 `json:"deleteTime" bson:"Delete_time"` //删除时间-暂不用 +//} + +type IQrCodeInfoRepo interface { + Insert(ctx context.Context, info *entity.QrCodeInfo) error + GenInfo(ctx context.Context, info *entity.QrCodeInfo) error + GetInfoByUuid(ctx context.Context, uuid string) (*entity.QrCodeInfo, error) + GetInfoByCodeId(ctx context.Context, codeId string) (*entity.QrCodeInfo, error) + GetReviewInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) + GetReleaseInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) + GetTrialInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) + GetTemporaryInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) + GetRemoteDebugInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) + UpdateTrialStartParams(ctx context.Context, codeId string, p entity.AppStartParams) error + UpdateStartParamsByUuid(ctx context.Context, uuid string, p entity.AppStartParams) error + UpdateApiServer(ctx context.Context, uuid string, apiServer string) error + UpdateInfo(ctx context.Context, uuid string, upInfo map[string]interface{}) error + GenReviewQrCodeInfo(ctx context.Context, info *entity.QrCodeInfo) error + NotFound(err error) bool +} diff --git a/domain/repository/red_dot.go b/domain/repository/red_dot.go new file mode 100644 index 0000000..9a378a1 --- /dev/null +++ b/domain/repository/red_dot.go @@ -0,0 +1,8 @@ +package repository + +import "context" + +type IRedDotRepo interface { + ReadTrialQr(ctx context.Context, readDotType string, id string, userId string) error + NotFound(err error) bool +} diff --git a/domain/repository/type_config.go b/domain/repository/type_config.go new file mode 100644 index 0000000..0fd42ff --- /dev/null +++ b/domain/repository/type_config.go @@ -0,0 +1,44 @@ +package repository + +import ( + "context" + "finclip-app-manager/domain/entity" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +//const TYPECONFIG_DB_NAME = "typeConfig" +// +//type TypeConfig struct { +// TypeConfigID string `json:"typeConfigId" bson:"type_config_id"` +// Namespace string `json:"namespace" bson:"namespace"` +// Value string `json:"value" bson:"value"` +// MarketID string `json:"marketId" bson:"market_id"` +// CustomData map[string]interface{} `json:"customData" bson:"custom_data"` +// SortNum int `json:"sortNum" bson:"sort_num"` +//} + +type ITypeConfigRepo interface { + Insert(ctx context.Context, typeConfig *entity.TypeConfig) error + GetOne(ctx context.Context, filter bson.M) error + Exist(ctx context.Context, namespace string, value string) (bool, error) + Update(ctx context.Context, selector bson.M, update bson.M) error + GetSome(ctx context.Context, pageSize, pageNo int) (int, []entity.TypeConfig, error) + GetAll(ctx context.Context) (int, []entity.TypeConfig, error) + Delete(ctx context.Context, typeConfigId string) error + GetNowSortNumInfo(ctx context.Context) (*entity.TypeConfig, error) + NotFound(err error) bool +} + +//type TypeConfigList []TypeConfig +// +//func (l TypeConfigList) Len() int { +// return len(l) +//} +// +//func (l TypeConfigList) Less(i, j int) bool { +// return l[i].SortNum < l[j].SortNum +//} +// +//func (l TypeConfigList) Swap(i, j int) { +// l[i], l[j] = l[j], l[i] +//} diff --git a/domain/script/auto_review_app.go b/domain/script/auto_review_app.go new file mode 100644 index 0000000..8b11e35 --- /dev/null +++ b/domain/script/auto_review_app.go @@ -0,0 +1,189 @@ +package script + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + cache "finclip-app-manager/infrastructure/cache/redis" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/logger" + "finclip-app-manager/infrastructure/utility" +) + +type AutoReviewApp struct { + AppOperConfigRepo repository.IAppOperConfigRepo + appRepo repository.AppRepository +} + +func NewAutoReviewApp() *AutoReviewApp { + return &AutoReviewApp{ + AppOperConfigRepo: impl.InitAppOperConfigRepo(), + appRepo: impl.InitAppRepo(), + } +} + +func (a *AutoReviewApp) ReviewApps(ctx context.Context) { + fmt.Printf("start auto review app...\n") + if config.Cfg.PublishEnv != entity.ENV_PRIVATE { + fmt.Printf("no need auto review app\n") + return + } + redisLockKey := "mop_auto_review_app_lock" + getOperAdminInfo := false + adminInfo := &GetOperAdminInfoRsp{} + for { + time.Sleep(60 * time.Second) + isSuc, err := cache.TryLock(ctx, redisLockKey, 600) //可以多实例部署,但是任何使用只有一个实例可以工作 + if !isSuc || err != nil { + if err != nil { + logger.GetLogger().Errorf("lock err:%s\n", err.Error()) + } else { + logger.GetLogger().Errorf("lock fail") + } + continue + } + + //获取配置 + configItem, _ := a.AppOperConfigRepo.Find(ctx) + if configItem.AutoReviewApp == 0 { + fmt.Printf("auto review app configItem.AutoReviewApp = %d\n", configItem.AutoReviewApp) + cache.Unlock(ctx, redisLockKey) + continue + } + + if !getOperAdminInfo { + adminInfo, err = a.GetOperAdminInfo(ctx) + if err != nil || adminInfo == nil { + cache.Unlock(ctx, redisLockKey) + continue + } else if adminInfo.Data.Info.ID == "" { + logger.GetLogger().Errorf("adminInfo.Data.Info.ID empty") + cache.Unlock(ctx, redisLockKey) + continue + } + getOperAdminInfo = true + } + + //获取审核中列表 + pageNo := 1 + pageSize := 20 + for { + _, list, err := a.appRepo.ListAppVers(ctx, pageNo, pageSize, "", "pendingReview", "") + if err != nil { + logger.GetLogger().Errorf("a.appRepo.ListAppVers err:%s\n", err.Error()) + break + } else if len(list) == 0 { + fmt.Printf("auto review app a.appRepo.ListAppVers empty\n") + break + } + + a.DoReview(ctx, list, adminInfo.Data.Info.ID) + pageNo += 1 + } + + cache.Unlock(ctx, redisLockKey) + + fmt.Printf("auto review app success\n") + } +} + +func (a *AutoReviewApp) DoReview(ctx context.Context, list []entity.AppVersion, userId string) { + for _, v := range list { + var auditReq AuditAppInternalReq + auditReq.AccountId = userId + auditReq.AppId = v.AppID + auditReq.Sequence = v.Sequence + auditReq.Operation = "Approve" + auditReq.Reason = "系统(自动审核)" + auditReq.Platform = "oper" + + a.AuditAppInternal(ctx, &auditReq, userId) + time.Sleep(1 * time.Second) + } +} + +type AuditAppInternalRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` +} + +type AuditAppInternalReq struct { + AccountId string `json:"accountId"` + AppId string `json:"appId"` + Sequence int `json:"sequence"` + Operation string `json:"operation"` + Reason string `json:"reason"` + Platform string `json:"platform"` +} + +func (a *AutoReviewApp) AuditAppInternal(ctx context.Context, req *AuditAppInternalReq, accountId string) (*AuditAppInternalRsp, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "X-Consumer-Custom-ID": accountId, + "url-call": "internal", + } + url := "http://mop-audit-manage-svr:8080/api/v1/mop/mop-audit-manage-svr/operation/applications" + + client := httpcall.NewClient() + rsp := AuditAppInternalRsp{} + resp, err := client.Request(ctx).SetHeaders(headers).SetBody(req).SetResult(&rsp).Put(url) + if err != nil { + logger.GetLogger().Errorf("AuditAppInternal req error:%s", err.Error()) + return nil, err + } + if resp.StatusCode() != http.StatusOK { + json.Unmarshal([]byte(resp.Body()), &rsp) + logger.GetLogger().Errorf("AuditAppInternal status code err,rsp:%s", resp.String()) + return &rsp, errors.New("AuditAppInternal status code err") + } + + logger.GetLogger().Debugf("AuditAppInternal rsp=%s", utility.InterfaceToJsonString(rsp)) + + return &rsp, nil +} + +type MopOperAdminInfo struct { + Info struct { + ID string `json:"id"` + Phone string `json:"phone"` + Account string `json:"account"` + CreateTime int64 `json:"createTime"` + } `json:"info"` +} + +type GetOperAdminInfoRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data MopOperAdminInfo `json:"data"` +} + +func (a *AutoReviewApp) GetOperAdminInfo(ctx context.Context) (*GetOperAdminInfoRsp, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + + var result GetOperAdminInfoRsp + client := httpcall.NewClient() + url := "http://mop-account-system:8080/api/v1/mop/applets-ecol-account/operation/admin-info" + rsp, err := client.Request(ctx).SetHeaders(headers).SetResult(&result).Get(url) + if err != nil { + logger.GetLogger().Errorf("goResty fail, rsp:%s, err:%s", rsp.String(), err.Error()) + return nil, err + } else if rsp.StatusCode() != 200 { + logger.GetLogger().Errorf("goResty fail, httpCode:%d", rsp.StatusCode()) + return nil, errors.New("status err") + } + + return &result, nil +} diff --git a/domain/service/account.go b/domain/service/account.go new file mode 100644 index 0000000..485b2f3 --- /dev/null +++ b/domain/service/account.go @@ -0,0 +1,39 @@ +package service + +import ( + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" +) + +type AccountInfoService struct { +} + +func NewAccountInfoService() *AccountInfoService { + return &AccountInfoService{} +} + +func (a *AccountInfoService) UpInfo(organId, subId, t string, m map[string]interface{}) (int, string) { + return http.StatusOK, utility.OK +} + +func (a *AccountInfoService) getAccountStatus(groupIDData *httpcall.GroupIDData /*, developerData *client.DeveloperData*/) int { + //if developerData.Type == client.ORGAN_ACCOUNT_TYPE_PERSON { + // return developerData.Status + //} + //if developerData.Type == client.ORGAN_ACCOUNT_TYPE_BUSINESS { + log.Infof("getAccountStatus-----groupIDData.ReviewStatus: %d\n", groupIDData.ReviewStatus) + if config.Cfg.IsUatEnv() { + if groupIDData.ReviewStatus == httpcall.StOrganApproved { + return httpcall.ORGAN_STATUS_NORMAL + } + if groupIDData.ReviewStatus == httpcall.StOrganUnApproved { + return httpcall.ORGAN_STATUS_FREEZE + } + } + //} + + // 私有化环境固定返回1 + return httpcall.ORGAN_STATUS_NORMAL +} diff --git a/domain/service/app.go b/domain/service/app.go new file mode 100644 index 0000000..cf6c7f4 --- /dev/null +++ b/domain/service/app.go @@ -0,0 +1,3418 @@ +package service + +import ( + "archive/zip" + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/kafka" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "fmt" + "io" + "os" + "path" + "path/filepath" + "strings" + + ezip "github.com/alexmullins/zip" + "github.com/gin-gonic/gin" + "gopkg.in/mgo.v2/bson" + + "net/http" + "time" +) + +const ( + /** + * 开发中: InDevelopment + * 审核中: Publishing + * 撤销审核: PublishWithdraw + * 审核通过:PublishApproved + * 审核被拒:PublishRejected + * 已上架:Published + * 高本版上架致下架:UnpublishedByNewSeq + * 开发者下架: UnpublishedByDev + * 运营端下架:UnpublishedByAdmin + **/ + AppExternalStatusInDevelopment = "InDevelopment" + AppExternalStatusPublishing = "Publishing" + AppExternalStatusPublishWithdrawed = "PublishWithdrawed" + AppExternalStatusPublishApproved = "PublishApproved" + AppExternalStatusPublishRejected = "PublishRejected" + AppExternalStatusPublished = "Published" + AppExternalStatusUnpublishedByNewSeq = "UnpublishedByNewSeq" + AppExternalStatusUnpublishedByDev = "UnpublishedByDev" + AppExternalStatusUnpublishedByAdmin = "UnpublishedByAdmin" +) + +type AppService struct { + appRepo repository.AppRepository + buildRepo repository.IAppBuildInfoRepo + bindingRepo repository.IBindingRepo + tempAppRepo repository.IAppTempInfoRepo + //qrcodeRepo repository.IQrCodeInfoRepo + prviacySettingRepo repository.IPrivacySettingRepo + tool *BoxTool +} + +func NewAppService() *AppService { + return &AppService{ + appRepo: impl.InitAppRepo(), + buildRepo: impl.InitBuildInfoRepo(), + bindingRepo: impl.InitBindingRepo(), + tempAppRepo: impl.InitAppTempInfoRepo(), + //qrcodeRepo: impl.InitQrCodeInfoRepo(), + prviacySettingRepo: impl.InitPrivacySettingRepo(), + tool: NewBoxTool(), + } +} + +func (as *AppService) CreateApp(ctx context.Context, c *gin.Context, req proto.CreateAppReq, accountId string) (*entity.App, *utility.SvrRsp) { + log.Infof("createApp get req:%+v", req) + rsp := utility.DefaultSvrRsp() + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, accountId) + if err != nil { + log.Errorf("createApp GetGroupID err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + accountInfo, err := hCaller.GetAccountInfo(ctx, accountId) + if err != nil { + log.Errorf("createApp GetAccountInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR) + } + + if req.ProjectType < 0 || req.ProjectType > 2 { + log.Errorf("createApp param err") + return nil, rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } + + info := entity.App{} + info.AppClass = req.AppClass + info.AppTag = req.AppTag + info.AppType = req.AppType + info.CoreDescription = req.CoreDescription + info.Logo = req.Logo + info.Name = req.Name + info.GroupID = groupInfo.GroupID + info.CreatedBy = accountInfo.Account + info.DeveloperID = accountId + info.AppID = bson.NewObjectId().Hex() + info.ProjectType = req.ProjectType + timestamp := time.Now().UnixNano() / 1e6 + info.Status = entity.Status{ + Value: entity.StInDevelopment, + LastUpdated: timestamp, + ModifiedBy: info.DeveloperID, + } + info.Created = timestamp + info.IsForbidden = 0 + licenseInfo, err := hCaller.GetLicense(ctx) + if err != nil { + log.Errorf("createApp get license info error:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + log.Infof("createApp get license info:%+v", licenseInfo) + appCount, err := as.appRepo.AppCount(ctx, "") + if err != nil { + log.Errorf("createApp get app count error:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if appCount >= licenseInfo.AppCount { + log.Errorf("createApp app count has over license limit app count:%d", appCount) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FC_PRI_LIMIT_APPID_OVER_ERROR) + } + //调用支付权限模块增加小程序数量 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + applyReq := httpcall.PayAddLimitReq{} + applyReq.Type = httpcall.PAY_ADD_TYPE_APP + applyReq.AccountId = accountId + applyReq.BusinessId = info.AppID + applyReq.BusinessName = info.Name + + payAddRsp, httpCode, err := hCaller.PayAddLimit(ctx, &applyReq) + if err != nil { + log.Errorf("PayAddLimit err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if httpCode != http.StatusOK { + return nil, rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR) + } + if payAddRsp.Data.EndTime == 0 { + payAddRsp.Data.EndTime = MAX_EXPIRE_DATA + } + info.Expire = payAddRsp.Data.EndTime + } else { //调用运营端增加企业appid数量,会做校验 + n := httpcall.AddLimitInfoReq{ + Type: "appId", + OrganId: info.GroupID, + AddNum: 1, + } + httpCode, _, err := hCaller.AddLimitInfo(ctx, &n) + if err != nil { + log.Errorf("createApp AddLimitInfo err:%s", err.Error()) + return nil, rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR) + } + } + if err = as.appRepo.InsertApp(ctx, info); err != nil { + log.Errorf("createApp insert appVer info err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_DB_ERR) + } + //生成操作日志 + logExp := make(map[string]interface{}) + go hCaller.AddOperateLog(c, groupInfo.GroupID, kafka.GenContent(kafka.APP_ADD_LOG, info.Name, info.AppID), logExp, accountInfo.Account) + + info.Expire = getExpire(info.Expire, licenseInfo.ExpireTime) + return &info, rsp.SetLoc(http.StatusCreated, utility.OK) +} + +func (as *AppService) WithdrawPublishRequest(ctx context.Context, c *gin.Context, appId string, seq int, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, seq) + if err != nil { + log.Errorf("withdrawPublishRequest get app ver err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("withdrawPublishRequest GetGroupID err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + err = as.appRepo.WithdrawPubApp(ctx, appId, seq, accountInfo.Account) + if err != nil { + log.Errorf("withdrawPublishRequest db err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + logExp := make(map[string]interface{}) + go hCaller.AddOperateLog(c, accountInfo.OrganId, kafka.GenContent(kafka.APP_CANCEL_REVIEW_LOG, appVer.Name, appVer.AppID), logExp, accountInfo.Account) + //model.NewAsyncMessageRepo().GenAppStatusChangeInfo(traceCtx, model.AppStatusChangeInfo{Event: model.AppWithdrawPubReq, Info: map[string]interface{}{"appId": appVer.AppID}}) + return rsp +} + +func (as *AppService) UpdateApp(ctx context.Context, c *gin.Context, req proto.AppUpdateReq, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId) + if err != nil { + log.Errorf("UpdateApp app info not found,req:%+v", req) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + oldName := appInfo.Name + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("updateApp GetGroupID err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + if groupInfo.GroupID != appInfo.GroupID { + log.Errorf("updateApp group id not equal,req groupId:%+v,get groupId:%s", groupInfo, appInfo.GroupID) + return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN) + } + //err = as.appRepo.UpdateApp(ctx, appInfo) + //if err != nil { + // log.Errorf("updateApp app err:%s", err.Error()) + // return rsp.SetLoc(http.StatusForbidden, utility.FS_DB_ERR) + //} + appInfo.Name = req.Name + appInfo.Logo = req.Logo + appInfo.AppClass = req.AppClass + appInfo.AppTag = req.AppTag + appInfo.CoreDescription = req.CoreDescription + appInfo.CustomData.DetailDescription = req.CustomData.DetailDescription + err = as.appRepo.UpdateApp(ctx, appInfo) + if err != nil { + log.Errorf("UpdateApp repo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if oldName != req.Name { + if err = as.appRepo.UpdateAppVerAppName(ctx, req.AppId, req.Name); err != nil { + log.Errorf("UpdateAppVerAppName repo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + //操作日志 + logExp := make(map[string]interface{}) + logReq := httpcall.GenOperateDataV2Req{ + OrganId: appInfo.GroupID, + Content: kafka.GenContent(kafka.APP_EDIT_INFO_LOG, appInfo.Name, appInfo.AppID), + Extra: logExp, + Oper: "", + AccountId: userId, + IsDev: true, + } + hCaller.AddOperateLogV2(c, logReq) + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) UpdateAppIsForbidden(ctx context.Context, req proto.AppIsForbiddenUpdateReq, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId) + if err != nil { + log.Errorf("UpdateAppIsForbidden app info not found,req:%+v", req) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("updateAppIsForbidden GetGroupID err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + if groupInfo.GroupID != appInfo.GroupID { + log.Errorf("updateAppIsForbidden group id not equal,req groupId:%+v,get groupId:%s", groupInfo, appInfo.GroupID) + return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN) + } + + if req.IsForbidden == 0 { + licenseInfo, err := hCaller.GetLicense(ctx) + if err != nil { + log.Errorf("createApp get license info error:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + log.Infof("createApp get license info:%+v", licenseInfo) + appCount, err := as.appRepo.AppCount(ctx, "") + if err != nil { + log.Errorf("createApp get app count error:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if appCount >= licenseInfo.AppCount { + log.Errorf("createApp app count has over license limit app count:%d", appCount) + return rsp.SetLoc(http.StatusOK, utility.FC_PRI_LIMIT_APPID_OVER_ERROR) + } + } + + appInfo.IsForbidden = req.IsForbidden + + //调用支付权限模块增加小程序数量 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + applyReq := httpcall.PayAddLimitReq{} + applyReq.Type = httpcall.PAY_ADD_TYPE_APP + applyReq.AccountId = userId + applyReq.BusinessId = req.AppId + applyReq.BusinessName = appInfo.Name + + if req.IsForbidden == 0 { + payAddRsp, httpCode, err := hCaller.PayAddLimit(ctx, &applyReq) + if err != nil { + log.Errorf("PayAddLimit err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + + } + if httpCode != http.StatusOK { + return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR) + } + if payAddRsp.Data.EndTime == 0 { + payAddRsp.Data.EndTime = MAX_EXPIRE_DATA + } + appInfo.Expire = payAddRsp.Data.EndTime + } else { + _, httpCode, err := hCaller.PayUpdateLimit(ctx, &applyReq) + if err != nil { + log.Errorf("PayAddLimit err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + + } + if httpCode != http.StatusOK { + return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR) + } + } + } else { //调用运营端增加企业appid数量,会做校验 + addNum := 1 + if req.IsForbidden == 1 { + addNum = -1 + } + n := httpcall.AddLimitInfoReq{ + Type: "appId", + OrganId: appInfo.GroupID, + AddNum: addNum, + } + httpCode, _, err := hCaller.AddLimitInfo(ctx, &n) + if err != nil { + log.Errorf("createApp AddLimitInfo err:%s", err.Error()) + return rsp.SetLoc(httpCode, utility.FC_OPERA_LIMIT_APPID_OVER_ERROR) + } + } + + err = as.appRepo.UpdateApp(ctx, appInfo) + if err != nil { + log.Errorf("UpdateAppIsForbidden repo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + /*//操作日志 + logExp := make(map[string]interface{}) + logReq := kafka.GenOperateDataV2Req{ + OrganId: appInfo.GroupID, + Content: kafka.GenContent(kafka.APP_EDIT_INFO_LOG, appInfo.Name, appInfo.AppID), + Extra: logExp, + Oper: "", + AccountId: userId, + IsDev: true, + } + kafka.GenOperateDataV2(ctx, c, logReq)*/ + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) PubApp(ctx context.Context, appId string, seq int, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq) + if err != nil { + log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error()) + if repository.NotFound(err) { + log.Errorf("DevPublishApp get appVer not found!") + return rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND) + } + } + + log.Debugf("as.appRepo.GetAppVerInfo err:%s", utility.InterfaceToJsonString(appVerInfo)) + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("DevPublishApp GetGroupID err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + if groupInfo.GroupID != appVerInfo.GroupID { + log.Errorf("DevPublishApp group id no equal,app ver group Id:%s,get group info:%+v", appVerInfo.GroupID, groupInfo) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_APP_SEQUENCE_NOT_FOUND) + } + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("DevPublishApp GetAccountInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_ACCOUNTINFO_ERROR) + } + _, onlineAppErr := as.appRepo.GetOnlineAppVer(ctx, appId) + if onlineAppErr != nil { + if !repository.NotFound(onlineAppErr) { + log.Errorf("GetOnlineAppVer err:%s", onlineAppErr.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + lastPubVerInfo, err := as.appRepo.GetLatestPubAppVer(ctx, appId) + if err != nil && !repository.NotFound(err) { + log.Errorf("DevPublishApp GetLatestPubAppVer err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + var isRollback = false + if !repository.NotFound(err) && lastPubVerInfo.Sequence > seq { //代表回退版本 + if repository.NotFound(onlineAppErr) { //如果当前小程序未上架,不允许回退 + log.Errorf("no pub app,appId:[%s]", appId) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_ROLLBACK_FORBID) + } + isRollback = true + //如果当前上架的小程序版本已经是回退版本,那不可再次回退 + if lastPubVerInfo.Status.Value == entity.StPublished && lastPubVerInfo.IsRollback { + log.Errorf("roll back app ver has rollback,info:%+v", lastPubVerInfo) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_MULTI_ROLLBACK_FORBID) + } + //校验是否可以回退----不是最近下架的5个版本 + rollbackList, err := as.appRepo.GetRollbackAbleList(ctx, groupInfo.GroupID, appId, lastPubVerInfo.Sequence) + if err != nil { + log.Errorf("GetRollbackAbleList err:%s,info:%+v", err.Error(), lastPubVerInfo) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + isValidRollbackSeq := false + for _, v := range rollbackList { + if v.Sequence == seq { + isValidRollbackSeq = true + } + } + if !isValidRollbackSeq { + log.Errorf("roll back app not valid,req appId:%s,seq:%d", appId, seq) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_ROLLBACK_FORBID) + } + log.Infof("PubApp appId:[%s],seq:[%d] is rollback!", appId, seq) + } else { + if appVerInfo.Status.Value != entity.StPublishApproved { + log.Errorf("PubApp status not valid,appId:[%s],seq:[%d]", appId, seq) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_INVALID_STATE) + } + } + err = as.pubAppHelp(ctx, appId, seq, accountInfo.Account, true, isRollback, userId, appVerInfo.ActionStatus.ModifiedBy) + if err != nil { + log.Errorf("pubAppHelp err:%s", err.Error()) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_SYSTEM_CALL) + } + + //service.NewWechatInfoService().TouchWechatInfo(traceCtx, appVer.AppID) + //if isDev { + // logExp := make(map[string]interface{}) + // go model.GenOperateData(traceCtx, c, groupID, GenContent(APP_PUB_LOG, appVer.Name, appVer.AppID, appVer.Sequence), logExp, accountInfo.Account) + //} + + //notifySpiderPushApp(traceCtx, req.AppID, client.UP_STATE) + //sendSwanReport(ctx, "userId", userId) + //c.JSON(http.StatusOK, gin.H{}) + sendDelaySms(ctx, appVerInfo.DeveloperID, true, true, true, appId, appVerInfo.Name, seq) + + //上架通过后,更新小程序隐私中的updateTime与effectiveTime + + total, err := as.prviacySettingRepo.Count(ctx, appId) + if total > 0 { + item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("PrviacySettingRepo insert err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + /*if item.EffectiveTime == 0 { + item.EffectiveTime = time.Now().UnixNano() / 1e6 + }*/ + item.UpdateTime = time.Now().UnixNano() / 1e6 + err = as.prviacySettingRepo.UpdateInfo(ctx, *item) + if err != nil { + log.Errorf("PrviacySettingRepo UpdateInfo time err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +//下架小程序 +func (as *AppService) UnpubApp(ctx context.Context, c *gin.Context, appId string, seq int, userId string, isDev bool, reason string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq) + if err != nil { + log.Errorf("UnpubApp GetAppVerInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + log.Debugf("UnpubApp appVerInfo:%+v", appVerInfo) + if appVerInfo.Status.Value != entity.StPublished { + log.Errorf("UnpubApp status err,need approved,appId:%s,seq:%d", appId, seq) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_INVALID_STATE) + } + + var account string + if isDev { + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("UnpubApp get group info err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if groupInfo.GroupID != appVerInfo.GroupID { + log.Errorf("unpublishAppHelp group id not equal appVer group id:%s,get group id:%+v", appVerInfo.GroupID, groupInfo) + return rsp.SetLoc(http.StatusForbidden, utility.FS_FORBIDDEN) + } + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("UnpubApp GetAccountInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + account = accountInfo.Account + } else { + adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("UnpubApp GetAdminAccountInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + account = adminInfo.Account + } + err = as.appRepo.UnpubApp(ctx, appId, seq, account, reason, isDev) + if err != nil { + log.Errorf("UnpubApp db err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if isDev { + logExp := make(map[string]interface{}) + go hCaller.AddOperateLog(c, appVerInfo.GroupID, kafka.GenContent(kafka.APP_DOWN_LOG, appVerInfo.Name, appVerInfo.AppID, appVerInfo.Sequence), logExp, account) + } else { + notifyContent := kafka.NotifyContent{} + notifyContent.Title = fmt.Sprintf("小程序“%s”被下架", appVerInfo.Name) + notifyContent.Result = "fail" + notifyContent.Msg = fmt.Sprintf("小程序 %s(App ID:%s)被进行下架操作。用户暂无法使用小程序的所有服务(关联应用也无法使用)。下架理由为:%s", appVerInfo.Name, appVerInfo.AppID, reason) + notifyContent.Reason = reason + go kafka.GenNotifyData(ctx, appVerInfo.GroupID, 1000, notifyContent) + } + notifySpiderPushApp(ctx, appId, httpcall.DOWN_STATE) + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) RollbackAppList(ctx context.Context, appId, userId string) ([]entity.AppVersion, error) { + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("RollbackAppList GetAccountInfo err:%s", err.Error()) + return nil, err + } + latestPubAppVer, err := as.appRepo.GetLatestPubAppVer(ctx, appId) + if err != nil { + if repository.NotFound(err) { + log.Errorf("RollbackAppList not found,appId:%s", appId) + return make([]entity.AppVersion, 0), nil + } + return nil, err + } + if latestPubAppVer.Status.Value != entity.StPublished { + log.Errorf("RollbackAppList latestPubAppVer no pub,appId:[%s]", appId) + return make([]entity.AppVersion, 0), nil + } + if latestPubAppVer.IsRollback { + log.Errorf("RollbackAppList latestPubAppVer has rollback,appId:[%s]", appId) + return make([]entity.AppVersion, 0), nil + } + rollbackList, err := as.appRepo.GetRollbackAbleList(ctx, accountInfo.OrganId, appId, latestPubAppVer.Sequence) + if err != nil { + log.Errorf("GetRollbackAbleList db err:%s", err.Error()) + return nil, err + } + return rollbackList, nil +} + +func (as *AppService) SubmitApp(ctx context.Context, c *gin.Context, req apiproto.SubmitPublishReqest, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + buildInfo, err := as.buildRepo.GetInfoById(ctx, req.Id) + if as.buildRepo.NotFound(err) || buildInfo == nil { + buildInfo, err = as.buildRepo.GetInfoByBuildId(ctx, req.Id) + if err != nil || buildInfo == nil { + if err != nil { + log.Errorf("SubmitApp get build info err:%s", err.Error()) + } else { + log.Errorf("SubmitApp get build info nil") + } + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + + if buildInfo.AppID != req.AppID { + log.Errorf("buildID err") + return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } + if config.GetConfig().IsOpenAuditSecurity { + auditInfo, err := hCaller.GetAuditDataInfoByBuildInfoId(ctx, buildInfo.BuildInfoId) + log.Debugln("GetAuditDataInfoByBuildInfoId:%v", utility.InterfaceToJsonString(auditInfo)) + if err != nil { + log.Errorf("GetAuditDataInfoByBuildInfoId err:%s", err.Error()) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } + //0无,1审核中,2通过,3不通过 + if auditInfo.Data.Status != 2 && auditInfo.Data.OperOpinion != 1 { + log.Errorf("auditInfo.Data.Status not pass:%v", auditInfo.Data.Status) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } + } + + appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppID) + if err != nil { + log.Errorf("SubmitApp GetAppInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("SubmitApp GetAccountInfo err:%s,user id:%s", err.Error(), userId) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if appInfo.GroupID != accountInfo.OrganId { + log.Errorf("SubmitApp group id not match!") + return rsp.SetLoc(http.StatusBadRequest, utility.FS_BAD_JSON) + } + maxSeqAppVerInfo, err := as.appRepo.GetMaxSeqAppVer(ctx, req.AppID) + if err != nil { + if !repository.NotFound(err) { + log.Errorf("SubmitApp GetMaxSeqAppVer err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } else { + if maxSeqAppVerInfo.Status.Value == entity.StPublishing { + log.Errorf("submitPublishRequest max version Publishing!!!") + return rsp.SetLoc(http.StatusBadRequest, utility.FS_PUBLISHING_OR_UNPUBLISHING) + } + } + oper := c.GetHeader("C-Open-Api") + if oper == "" { + oper = accountInfo.Account + } + SubmitAppReq := entity.SubmitAppReq{ + AppId: req.AppID, + BuildId: req.Id, + Account: oper, + NeedAutoPub: req.NeedAutoPub, + TestInfo: req.TestInfo, + UserId: userId, + } + err = as.appRepo.SubmitApp(ctx, SubmitAppReq, 0, userId) + if err != nil { + log.Errorf("SubmitApp app err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + logExp := make(map[string]interface{}) + + go hCaller.AddOperateLog(c, appInfo.GroupID, kafka.GenContent(kafka.APP_SUB_REVIEW_LOG, appInfo.Name, appInfo.AppID), logExp, oper) + + if config.Cfg.PublishEnv == config.ENV_UAT { + // 通知中心发送消息 + notifyContent := kafka.NotifyContent{} + notifyContent.Title = fmt.Sprintf("%s提交了”%s”小程序审核", accountInfo.Account, appInfo.Name) + notifyContent.Result = "success" + notifyContent.Msg = fmt.Sprintf("%s提交了小程序“%s”(APPID: %s)的上架审核申请", oper, appInfo.Name, appInfo.AppID) + go kafka.GenNotifyData(ctx, accountInfo.OrganId, 1000, notifyContent) + } + + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) ApproveApp(ctx context.Context, req apiproto.ApproveAppReq, isAdmin bool, userId string) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, req.AppID, req.Sequence) + if err != nil { + log.Errorf("ApproveApp get app version info err:%s", err.Error()) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_APP_SEQUENCE_NOT_FOUND) + } + var account string + if isAdmin { + adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("approveApp GetAdminAccountInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_GET_ACCOUNTINFO_ERROR) + } + account = adminInfo.Account + } else { + devAccountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("approveApp GetAdminAccountInfo err:%s", err.Error()) + return rsp.SetLoc(http.StatusBadRequest, utility.FS_GET_ACCOUNTINFO_ERROR) + } + if devAccountInfo.OrganId != appVerInfo.GroupID { + log.Errorf("ApproveApp organ id not match,req organ id:%s,app ver:%+v", devAccountInfo.OrganId, appVerInfo) + return rsp.SetLoc(http.StatusNotFound, utility.FS_FORBIDDEN) + } + account = devAccountInfo.Account + } + if req.RequestFrom != "" { + account = req.RequestFrom + } + var isPass = false + if req.Status == entity.StPublishApproved { + isPass = true + } + var isPubImmediately = false + if appVerInfo.NeedAutoPub && isPass { + isPubImmediately = true + } + log.Infof("isPass:%t isPubImmediately:%t", isPass, isPubImmediately) + err = as.appRepo.ApproveApp(ctx, req.AppID, req.Sequence, account, req.Reason, isPass) + if err != nil { + log.Errorf("ApproveApp db err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + { + //给通知中心发消息 + st := time.Unix(appVerInfo.PublishingStatus.LastUpdated/1000, 0).Format("2006-01-02 15:04") + at := time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04") + notifyContent := kafka.NotifyContent{} + if isPass { + notifyContent.Title = fmt.Sprintf("小程序“%s”上架审核成功", appVerInfo.Name) + notifyContent.Result = "success" + //notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)已经通过审核,可进行后续操作。
申请时间:%s,审核时间:%s", + // appVerInfo.Name, appVerInfo.AppID, st, at) + notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)您提交的小程序已经通过审核,请在小程序详情中进行版本上架操作。
申请时间:%s,审核时间:%s", + appVerInfo.Name, appVerInfo.AppID, st, at) + notifyContent.Reason = req.Reason + } else { + notifyContent.Title = fmt.Sprintf("小程序“%s”上架审核失败", appVerInfo.Name) + notifyContent.Result = "fail" + notifyContent.Msg = fmt.Sprintf("小程序 %s(APP ID: %s)未通过审核,可进行后续操作。
申请时间:%s,审核时间:%s", appVerInfo.Name, appVerInfo.AppID, st, at) + notifyContent.Reason = req.Reason + } + go kafka.GenNotifyData(ctx, appVerInfo.GroupID, 1000, notifyContent) + sendDelaySms(ctx, appVerInfo.DeveloperID, isPass, isPubImmediately, false, req.AppID, appVerInfo.Name, req.Sequence) + } + if isPubImmediately { + err = as.pubAppHelp(ctx, req.AppID, req.Sequence, "自动上架", false, false, "[auto]", appVerInfo.ActionStatus.ModifiedBy) + //err = as.appRepo.PubApp(ctx, req.AppID, req.Sequence, "自动上架", true, false) + if err != nil { + log.Errorf("ApproveApp auto pub app err:%s", err.Error()) + } + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + } else { + appTagStr := "" + if len(appVerInfo.AppTag) > 0 { + for _, v := range appVerInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagStr += tag.Name + "," + log.Debugln("appTagStr", appTagStr) + } + } + } + if len(appTagStr) > 0 { + appTagStr = appTagStr[0 : len(appTagStr)-1] + } + } + } + //sendSwanReport(ctx, "account", appVerInfo.RequestStatus.ModifiedBy) + } + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) pubAppHelp(ctx context.Context, appId string, seq int, account string, isDev, isRollback bool, userId, requestAccount string) error { + //通知灰度发布并更新状态 + var err error + if isDev { //运营端审核通过自动上架,做一个特殊处理 + err = hCaller.PubNotifyRuleEngine(ctx, appId, seq, userId, isDev) + } else { + err = hCaller.PubNotifyRuleEngine(ctx, appId, seq, "", isDev) + } + if err != nil { + log.Errorf("pubAppHelp PubNotifyRuleEngine err:%s", err.Error()) + return err + } + err = as.appRepo.PubApp(ctx, appId, seq, account, isDev, isRollback) + if err != nil { + log.Errorf("PubAppVer err:%s,appId:%s,seq:%d", err.Error(), appId, seq) + return err + } + appVersion, err := as.appRepo.GetAppVerInfo(ctx, appId, seq) + if err != nil { + log.Errorf("pubAppHelp GetAppVerInfo err:%s", err.Error()) + return nil + } + //service.NewWechatInfoService().TouchWechatInfo(traceCtx, appVer.AppID) + //if isDev { + // logExp := make(map[string]interface{}) + // go model.GenOperateData(traceCtx, c, groupID, GenContent(APP_PUB_LOG, appVer.Name, appVer.AppID, appVer.Sequence), logExp, accountInfo.Account) + //} + + //notifySpiderPushApp(traceCtx, req.AppID, client.UP_STATE) + + err = hCaller.TouchWechatInfo(ctx, appId) + if err != nil { + log.Errorf("TouchWechatInfo err:%s", err.Error()) + return nil + } + /*appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return err + } + log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + + if len(appVersion.AppTag) > 0 { + log.Debugln("AppTag:", appVersion.AppTag) + for _, v := range appVersion.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagStr += tag.Name + "," + log.Debugln("appTagStr", appTagStr) + } + } + } + if len(appTagStr) > 0 { + appTagStr = appTagStr[0 : len(appTagStr)-1] + } + }*/ + /* + if len(appVersion.AppTag) > 0 { + for _, v := range appTagInfo.Data.AppClass { + if v.Key == appVersion.AppClass { + appClassStr = v.Name + } + } + }*/ + /*if len(appVersion.CustomData.SourceFile) > 0 { + notifySpiderPubApp(ctx, appVersion.AppID, appVersion.Name, appVersion.CoreDescription, "", appVersion.CustomData.SourceFile[0].SourceFileUrl, appTagStr, appClassStr) + }*/ + go hCaller.PubAppNotifyToMiniprogram(ctx, &appVersion) + sendSwanReport(ctx, "account", requestAccount) + return nil +} + +type GetStatisticsResponse struct { + Created int `json:"created"` + Submited int `json:"submited"` + Approved int `json:"approved"` + Published int `json:"published"` +} + +func (as *AppService) AppStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool, isForbidden int) (GetStatisticsResponse, error) { + var ( + result = GetStatisticsResponse{} + err error + ) + result.Created, err = as.appRepo.GetCreatedStatistics(ctx, startTime, endTime, groupId, isForbidden) + if err != nil { + return GetStatisticsResponse{}, err + } + result.Submited, err = as.appRepo.GetSubmittedStatistics(ctx, startTime, endTime, groupId, distinct) + if err != nil { + return GetStatisticsResponse{}, err + } + result.Approved, err = as.appRepo.GetApprovedStatistics(ctx, startTime, endTime, groupId, distinct) + if err != nil { + return GetStatisticsResponse{}, err + } + result.Published, err = as.appRepo.GetPublishedStatistics(ctx, startTime, endTime, groupId) + if err != nil { + return GetStatisticsResponse{}, err + } + return result, nil +} + +func (as *AppService) GetAppInfoByAppId(ctx context.Context, appId string) (entity.App, error) { + return as.appRepo.GetAppInfo(ctx, appId) +} + +func (as *AppService) GetAppVerInfo(ctx context.Context, appId string, seq int) (entity.AppVersion, error) { + return as.appRepo.GetAppVerInfo(ctx, appId, seq) +} + +func (as *AppService) GetLatestPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + return as.appRepo.GetLatestPubAppVer(ctx, appId) +} + +func (as *AppService) GetOnlineAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + return as.appRepo.GetOnlineAppVer(ctx, appId) +} + +func (as *AppService) GetLatestReviewAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + return as.appRepo.GetLatestReviewAppVer(ctx, appId) +} + +func (as *AppService) GetMaxSeqAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + return as.appRepo.GetMaxSeqAppVer(ctx, appId) +} + +func (as *AppService) GetPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + return as.appRepo.GetLatestPubAppVer(ctx, appId) +} + +func (as *AppService) GetAllPublishedVerList(ctx context.Context, appId string) ([]entity.AppVersion, int, error) { + return as.appRepo.GetAllPublishedVerList(ctx, appId) +} + +func (as *AppService) GetBuildInfo(ctx context.Context, req apiproto.GetBuildAppInfoReq, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + switch req.Type { + case entity.BuildInfoTypeTrial: //获取体验版小程序详情 + return as.GetTrialInfo(ctx, req.CodeId, sdkKey) + case entity.BuildInfoTypeTemporary, entity.BuildInfoTypeRomoteDebug: //获取ide临时小程序详情 + return as.getTempAppBuildInfo(ctx, req.CodeId) + case entity.BuildInfoTypeDevelopment: + return as.GetDevInfo(ctx, req.CodeId, sdkKey) + default: + return nil, utility.DefaultSvrRsp().SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } +} + +func (as *AppService) GetTrialInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + + buildInfo := new(pb.BuildAppInfo) + info, err := as.buildRepo.GetInfoById(ctx, codeId) + if err != nil { + log.Errorf("GetTrialInfo get info err:%s", err.Error()) + if repository.NotFound(err) { + return nil, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if info.Source != entity.APP_BUILD_SOURCE_TRIAL { + log.Errorf("GetTrialInfo id is not a trial info:[%s]", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_NOT_TRIAL_INFO) + } + + appInfo, err := as.appRepo.GetAppInfo(ctx, info.AppID) + if err != nil { + log.Errorf("GetTrialInfo GetAppVerInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + if appInfo.IsForbidden == 1 { + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN) + } + + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID) + if err != nil { + log.Errorf("GetTrialInfo GetGroupInfoByUserId err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + // 获取开发者信息 + //developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID) + //if err != nil { + // log.Errorf("GetDeveloperInfo err:%s", err.Error()) + // return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR) + //} + //status := avs.account.getAccountStatus(groupInfo, developerInfo) + + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + + domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, groupInfo.GroupID) + if err != nil { + log.Errorf("GetTrialInfo ger domain info err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //支付信息过期校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + appStatus, err := as.CheckIdStatus(ctx, appInfo.AppID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appInfo.AppID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("check appid purch status no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + log.Debugf("get group id:%s,sdkKey:%s", appInfo.GroupID, sdkKey) + inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry) + if !inWhiteList { + bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey) + if err != nil { + log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error()) + if repository.NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindingInfo.CooperateStatus.Value != entity.StBindValid { + log.Errorf("GetTrialInfo binding bind invalid,binding info:%+v", bindingInfo) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + //支付信息校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("binding id pay check no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE) + } + } + appAssBind := false + for _, v := range bindingInfo.AppInfos { + if v.AppID == appInfo.AppID { + appAssBind = true + } + } + if !appAssBind { + log.Errorf("GetTrialInfo sdk key not ass binding,appId:[%s]", appInfo.AppID) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appInfo.AppTag) > 0 { + for _, v := range appInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + buildInfo.CodeId = info.Id + buildInfo.CoreDescription = appInfo.CoreDescription + buildInfo.Created = info.Created + buildInfo.CreatedBy = info.CreatedBy + err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, info.CustomData, domainInfo, "cache") + if err != nil { + log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + buildInfo.CustomData = customData + buildInfo.CustomData.DetailDescription = appInfo.CustomData.DetailDescription + buildInfo.GroupId = info.GroupID + buildInfo.GroupName = groupInfo.GroupName + buildInfo.Logo = appInfo.Logo + buildInfo.Name = appInfo.Name + buildInfo.Version = info.Version + buildInfo.IsTemp = false + buildInfo.NeedCrt = domainInfo.NeedCrt + buildInfo.AppId = info.AppID + buildInfo.AppTag = appTagArr + buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType) + buildInfo.ProjectType = int32(appInfo.ProjectType) + buildInfo.DeveloperStatus = int32(getAccountStatus(groupInfo)) + //buildInfoCacheByte, _ = json.Marshal(buildInfo) + //avs.rc.Set(ctx, avs.getTrialInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime) + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, info.AppID) + if err == nil { + buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo) + //return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + return buildInfo, rsp +} + +func (as *AppService) GetDevInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + + buildInfo := new(pb.BuildAppInfo) + + //buildInfoCacheByte, err := avs.rc.GetBytes(ctx, avs.getDevInfoCacheKey(codeId)) + //if err == nil { + // if err = json.Unmarshal(buildInfoCacheByte, buildInfo); err == nil { + // log.Infof("GetDevInfo from cache ...") + // return buildInfo, rsp.SetLoc(gin.H{}, http.StatusOK, common.OK) + // } + //} + + info, err := as.buildRepo.GetInfoById(ctx, codeId) + if err != nil { + log.Errorf("GetDevInfo get info err:%s", err.Error()) + if repository.NotFound(err) { + return nil, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + appInfo, err := as.appRepo.GetAppInfo(ctx, info.AppID) + if err != nil { + log.Errorf("GetDevInfo GetAppVerInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if appInfo.IsForbidden == 1 { + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN) + } + + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID) + if err != nil { + log.Errorf("GetDevInfo GetGroupInfoByUserId err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //// 获取开发者信息 + //developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID) + //if err != nil { + // log.Errorf("GetDeveloperInfo err:%s", err.Error()) + // return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR) + //} + //status := avs.account.getAccountStatus(groupInfo, developerInfo) + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + //if !client.OrganStatusIsValid(groupInfo.ReviewStatus) { + // log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + // return nil, rsp.SetLoc(gin.H{}, http.StatusForbidden, common.FS_ORGAN_STATUS_INVALID) + //} + //支付信息过期校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + appStatus, err := as.CheckIdStatus(ctx, appInfo.AppID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appInfo.AppID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("check appid purch status no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, appInfo.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + + log.Debugf("get group id:%s,sdkKey:%s", appInfo.GroupID, sdkKey) + inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry) + if !inWhiteList { + bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey) + if err != nil { + log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error()) + if repository.NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindingInfo.CooperateStatus.Value != entity.StBindValid { + log.Errorf("GetDevInfo binding bind invalid,binding info:%+v", bindingInfo) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + //支付信息校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("binding id pay check no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE) + } + } + appAssBind := false + for _, v := range bindingInfo.AppInfos { + if v.AppID == appInfo.AppID { + appAssBind = true + } + } + if !appAssBind { + log.Errorf("GetDevInfo sdk key not ass binding,appId:[%s]", appInfo.AppID) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appInfo.AppTag) > 0 { + for _, v := range appInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + buildInfo.CodeId = info.Id + buildInfo.CoreDescription = appInfo.CoreDescription + buildInfo.Created = info.Created + buildInfo.CreatedBy = info.CreatedBy + err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, info.CustomData, domainInfo, "cache") + if err != nil { + log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + buildInfo.CustomData = customData + buildInfo.CustomData.DetailDescription = appInfo.CustomData.DetailDescription + buildInfo.GroupId = info.GroupID + buildInfo.GroupName = groupInfo.GroupName + buildInfo.Logo = appInfo.Logo + buildInfo.Name = appInfo.Name + buildInfo.Version = info.Version + buildInfo.AppId = info.AppID + buildInfo.IsTemp = false + buildInfo.NeedCrt = domainInfo.NeedCrt + buildInfo.DeveloperStatus = int32(getAccountStatus(groupInfo)) + buildInfo.AppTag = appTagArr + buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType) + buildInfo.ProjectType = int32(appInfo.ProjectType) + //buildInfoCacheByte, _ = json.Marshal(buildInfo) + //avs.rc.Set(ctx, avs.getDevInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime) + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, info.AppID) + if err == nil { + buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo) + //return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + return buildInfo, rsp +} + +type GetRuleEngineVerPubListRspItem struct { + Version int `json:"version"` + VersionStr string `json:"versionStr"` +} + +type VerToDescItem struct { + Version int `json:"version"` + Desc string `json:"desc"` +} +type GetRuleEngineVerPubListRsp struct { + VerList []GetRuleEngineVerPubListRspItem `json:"verList"` //大于等于MaxPubVer的序列号列表 + NowPubVer GetRuleEngineVerPubListRspItem `json:"nowPubVer"` //当前上架版本 + MaxPubVer GetRuleEngineVerPubListRspItem `json:"maxPubVer"` //已发布、已下架、审核通过三种状态里面的最大版本号 + VerToDesc []VerToDescItem `json:"verToDesc"` //序列号到版本描述的映射 +} + +func (as *AppService) GetRuleEngineVerPubList(ctx context.Context, appId string) (interface{}, *utility.SvrRsp) { + rspData := GetRuleEngineVerPubListRsp{} + rsp := utility.DefaultSvrRsp() + pubVer, err := as.appRepo.GetOnlineAppVer(ctx, appId) + if err != nil { + if repository.NotFound(err) { + rspData.NowPubVer = GetRuleEngineVerPubListRspItem{Version: -1, VersionStr: ""} + } else { + log.Errorf("GetOnlineAppVer err:%s", err.Error()) + return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + rspData.NowPubVer.Version = pubVer.Sequence + rspData.NowPubVer.VersionStr = pubVer.Version + + maxVerSeq := 0 + latestPubVer, err := as.appRepo.GetLatestPubAppVer(ctx, appId) + if err != nil { + if repository.NotFound(err) { + rspData.MaxPubVer.Version = 0 + rspData.VerList = make([]GetRuleEngineVerPubListRspItem, 0) + } else { + log.Errorf("GetLatestPubAppVer err:%s", err.Error()) + return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + maxVerSeq = latestPubVer.Sequence + rspData.MaxPubVer.Version = latestPubVer.Sequence + rspData.MaxPubVer.VersionStr = latestPubVer.Version + + permitPubList, err := as.appRepo.GetAllPermitGrayPubVers(ctx, appId, maxVerSeq) + if err != nil { + log.Errorf("GetAllPermitGrayPubVers err:%s", err.Error()) + return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + for _, v := range permitPubList { + item := GetRuleEngineVerPubListRspItem{ + Version: v.Sequence, + VersionStr: v.Version, + } + rspData.VerList = append(rspData.VerList, item) + } + //获取版本号对应的版本说明 + type VerToDescTemp struct { + Sequence int `bson:"sequence"` + CustomData map[string]interface{} `bson:"customData"` + } + verList, _, err := as.appRepo.GetAllVers(ctx, appId) + if err != nil { + log.Errorf("GetAllVers err:%s", err.Error()) + return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + for _, v := range verList { + item := VerToDescItem{} + item.Version = v.Sequence + item.Desc = v.CustomData.VersionDescription + rspData.VerToDesc = append(rspData.VerToDesc, item) + } + log.Infof("GetRuleEngineVerPubList rsp:%+v", rspData) + return rspData, rsp +} + +type ListAppsReq struct { + PullType string + PageNo int + PageSize int + SearchText string + SortType string + UserId string + GroupId string + IsDev bool +} + +func (as *AppService) DevListApps(ctx context.Context, req *ListAppsReq) (int, []entity.App, error) { + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, req.UserId) + if err != nil { + log.Errorf("DevListApps GetGroupInfoByUserId err:%s", err.Error()) + return 0, nil, err + } + total, list, err := as.appRepo.ListApps(ctx, groupInfo.GroupID, req.PageNo, req.PageSize, req.SearchText, req.SortType, req.PullType) + if err != nil { + if repository.NotFound(err) { + log.Infof("DevListApps empty!") + return 0, []entity.App{}, nil + } + return 0, nil, err + } + return total, list, err +} + +func (as *AppService) AdminListApps(ctx context.Context, req *ListAppsReq) (int, []entity.App, error) { + total, list, err := as.appRepo.ListApps(ctx, req.GroupId, req.PageNo, req.PageSize, req.SearchText, req.SortType, req.PullType) + if err != nil { + if repository.NotFound(err) { + log.Infof("DevListApps empty!") + return 0, []entity.App{}, nil + } + return 0, nil, err + } + return total, list, err +} + +func (as *AppService) AdminListPubApps(ctx context.Context, req *ListAppsReq) (int, []entity.AppVersion, error) { + list, total, err := as.appRepo.GetPublishedAppList(ctx, req.PageNo, req.PageSize, req.SearchText) + if err != nil { + if repository.NotFound(err) { + log.Infof("DevListApps empty!") + return 0, []entity.AppVersion{}, nil + } + return 0, nil, err + } + return total, list, err +} + +type DevListAppsAndReviewsReq struct { + ListType string `form:"listType"` + GroupId string `form:"groupId"` + AppId string `form:"appId"` + Query string `form:"query"` + Sort string `form:"sort"` + SearchFields string `form:"searchFields"` + SearchText string `form:"searchText"` + PageSize int `form:"pageSize"` + PageNo int `form:"pageNo"` + ReviewsPageSize int `form:"reviewsPageSize"` + ReviewsPageNo int `form:"reviewsPageNo"` +} + +type DevListAppsAndReviewsRsp struct { + Total int `json:"total"` + List []AppsAndReviewRspItem `json:"list"` +} +type ReviewsRsp struct { + Total int `json:"total"` + List []ReviewsRspItem `json:"list"` +} +type AppsAndReviewRspItem struct { + AppId string `json:"appId"` + Name string `json:"name"` + Logo string `json:"logo"` + Version string `json:"version"` + Status string `json:"status"` + ReviewTotal int `json:"reviewTotal"` + ReviewList []ReviewsRspItem `json:"reviewList"` +} +type ReviewsRspItem struct { + Sequence int `json:"sequence"` + Status string `json:"status"` + Version string `json:"version"` +} + +func (as *AppService) ListAppAndReviews(ctx context.Context, appId string, pageNo, pageSize int) (interface{}, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + total, appVers, err := as.appRepo.ListAppVersByAppId(ctx, appId, pageNo, pageSize) + if err != nil { + log.Errorf("ListAppVers err:%s", err.Error()) + return gin.H{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + rspData := ReviewsRsp{} + rspData.List = make([]ReviewsRspItem, 0) + for _, v := range appVers { + reviewInfo := ReviewsRspItem{} + reviewInfo.Status = v.Status.Value + reviewInfo.Sequence = v.Sequence + reviewInfo.Version = v.Version + rspData.List = append(rspData.List, reviewInfo) + } + rspData.Total = total + return rspData, rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) GetAppsByAppIds(ctx context.Context, appIds []string) ([]entity.App, error) { + return as.appRepo.GetAppsByAppIds(ctx, appIds) +} + +func (as *AppService) GetAppsToBinding(ctx context.Context, req apiproto.ListAppsToBindReq) (int, []entity.App, error) { + return as.appRepo.GetAppsToBinding(ctx, req.BindingId, req.PageNo, req.PageSize, req.SearchText) +} + +func (as *AppService) GetLinkAppsByBindingID(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) { + return as.appRepo.GetLinkAppsByBindingId(ctx, bindingId, pageNo, pageSize, searchText) +} + +func (as *AppService) GetLinkAppsBySDKKey(ctx context.Context, sdkKey string, pageNo, pageSize int) (int, []entity.App, error) { + return as.appRepo.GetLinkAppsBySDKKey(ctx, sdkKey, pageNo, pageSize) +} + +func (as *AppService) AdminGetLinkApps(ctx context.Context, searchText string, pageNo, pageSize int) (int, interface{}, error) { + return as.appRepo.AdminGetLinkApps(ctx, pageNo, pageSize, searchText) +} + +func (as *AppService) AdminGetAppReviews(ctx context.Context, req apiproto.AdminGetAppReviewsReq) (int, []entity.AppVersion, error) { + return as.appRepo.GetAppReviews(ctx, req) +} + +func (as *AppService) UpdateGrayPubStatus(ctx context.Context, appId string, seq int, status bool) error { + return as.appRepo.UpdateGrayStatus(ctx, appId, seq, status) +} + +func (as *AppService) GetAppInfo(ctx context.Context, appId string) (entity.App, error) { + return as.appRepo.GetAppInfo(ctx, appId) +} + +func (as *AppService) ListAppVer(ctx context.Context, appId string, pageNo, pageSize int) (int, []entity.AppVersion, error) { + return as.appRepo.ListAppVersByAppId(ctx, appId, pageNo, pageSize) +} + +func (as *AppService) AdminListAppVer(ctx context.Context, pageNo, pageSize int, searchText, t string, groupId string) (int, []entity.AppVersion, error) { + return as.appRepo.ListAppVers(ctx, pageNo, pageSize, searchText, t, groupId) +} + +func (as *AppService) UpdateBuildInfo(ctx context.Context, c *gin.Context, userId string, req apiproto.UpdateAppInfoReq) error { + accountInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("UpdateBuildInfo err:%s", err.Error()) + return err + } + oper := accountInfo.Account + reqFrom := c.GetHeader("C-Open-Api") + if reqFrom != "" { + req.Username = reqFrom + oper = reqFrom + } + info := entity.AppBuildInfo{ + Id: bson.NewObjectId().Hex(), + BuildInfoId: req.BuildInfoId, + AppID: req.AppId, + Source: entity.APP_BUILD_SOURCE_BUILD, + Version: req.UpInfo.Version, + //VersionDescription: req.UpInfo.CustomData.VersionDescription, + GroupID: accountInfo.OrganId, + UserId: req.UserId, + Created: utils.GetNowMs(), + CreatedBy: req.Username, + CustomData: req.UpInfo.CustomData, + Status: true, + StartParams: entity.AppStartParams{}, + } + info.CustomData.Developer = oper + err = as.buildRepo.Insert(ctx, info) + if err != nil { + log.Errorf("insert build info err:%s", err.Error()) + return err + } + //操作日志 + logExp := make(map[string]interface{}) + go hCaller.AddOperateLog(c, info.GroupID, kafka.GenContent(kafka.APP_EDIT_INFO_LOG, req.UpInfo.Version, info.AppID), logExp, oper) + return nil +} + +type GetAppClassPerRspItem struct { + AppClass string `json:"appClass"` + AppClassName string `json:"appClassName"` + Count int `json:"count"` +} +type GetAppClassPerRsp struct { + List []GetAppClassPerRspItem `json:"list"` +} + +func (as *AppService) GetAppClassPer(ctx context.Context, status string) (*GetAppClassPerRsp, error) { + rspList, err := as.appRepo.GetAppClassPer(ctx, status) + if err != nil { + return nil, err + } + rspData := GetAppClassPerRsp{} + rspData.List = make([]GetAppClassPerRspItem, 0) + for _, v := range rspList { + item := GetAppClassPerRspItem{ + AppClass: v.Class, + Count: v.Count, + } + if len(v.Name) > 0 { + item.AppClassName = v.Name[0] + } + rspData.List = append(rspData.List, item) + } + return &rspData, nil +} + +type GetGrayStatisticsVerListRspListItem struct { + PubTime int64 `json:"pub_time"` + UnPubTime int64 `json:"un_pub_time"` + Version int `json:"version"` + VersionStr string `json:"version_str"` +} +type GetGrayStatisticsVerListRsp struct { + Total int `json:"total"` + List []GetGrayStatisticsVerListRspListItem `json:"list"` +} + +func (as *AppService) GetGrayStatisticsVerList(ctx context.Context, appId string, ver int, beginTime, endTime int64) (GetGrayStatisticsVerListRsp, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + num, verInfoList, err := as.appRepo.GetGrayStatisticsVerList(ctx, appId, ver, beginTime, endTime) + if err != nil { + log.Errorf("GetGrayStatisticsVerList err:%s", err.Error()) + if repository.NotFound(err) { + return GetGrayStatisticsVerListRsp{Total: 0, List: make([]GetGrayStatisticsVerListRspListItem, 0)}, rsp + } + return GetGrayStatisticsVerListRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + log.Debugf("GetGrayStatisticsVerList num:%d,err:%+v,ver list:%+v", num, err, verInfoList) + rspData := GetGrayStatisticsVerListRsp{ + List: make([]GetGrayStatisticsVerListRspListItem, 0), + } + for _, v := range verInfoList { + item := GetGrayStatisticsVerListRspListItem{} + item.PubTime = v.PublishedStatus.LastUpdated + item.UnPubTime = v.UnpublishedStatus.LastUpdated + item.Version = v.Sequence + item.VersionStr = v.Version + rspData.List = append(rspData.List, item) + } + rspData.Total = num + return rspData, rsp +} + +type InternalGetAppVerInfoRsp struct { + AppID string `json:"appId"` + Name string `json:"name"` + Sequence int `json:"sequence"` + AppClass string `json:"appClass"` + AppTag []string `json:"appTag"` + AppType string `json:"appType"` + Status proto.AppRspStatus `json:"status"` + DeveloperID string `json:"developerId"` + DeveloperStatus int `json:"developerStatus"` + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + Created int64 `json:"created"` + CreatedBy string `json:"createdBy"` + CustomData proto.AppRspCustomData `json:"customData"` + Version string `json:"version"` + CorporationID string `json:"corporationId"` + CoreDescription string `json:"coreDescription"` + Logo string `json:"logo"` + GroupStatus int `json:"groupStatus,omitempty"` //todo:目前在缓存中,会返回给客户 + InGrayRelease bool `json:"inGrayRelease"` //是否在灰度发布中 + IsTemp bool `json:"isTemp"` + NeedCrt bool `json:"needCrt"` + WechatLoginInfo proto.WechatLoginInfo `json:"wechatLoginInfo"` + PrivacySettingType int `json:"privacySettingType"` + ProjectType int `json:"projectType"` +} + +func (as *AppService) OpenApiGetAppVerInfo(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) { + log.Infof("OpenApiGetAppVerInfo appId:%s,sequence:%d,sdkver:%s", appId, sequence, sdkVer) + rsp := utility.DefaultSvrRsp() + tempRspInfo, err := as.getTempAppInfo(ctx, appId, sequence) + log.Debugf("getTempAppInfo rsp:%+v,err:%+v", tempRspInfo, err) + if err == nil { + return tempRspInfo, rsp + } + //if sequence != 0 { + // appVerCacheRspInfo, err := as.openApiGetAppVerInfoFromCache(ctx, appId, sequence, sdkVer) + // if err == nil { + // return appVerCacheRspInfo, http.StatusOK, common.OK + // } + //} + return as.openApiGetAppVerInfoNoCache(ctx, appId, sequence, sdkVer) +} + +func (as *AppService) getTempAppBuildInfo(ctx context.Context, codeId string) (*pb.BuildAppInfo, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + tempRspInfo, err := as.getTempAppInfo(ctx, codeId, 1) + log.Infof("getTempAppInfo rsp:%+v,err:%+v", tempRspInfo, err) + if err != nil { + log.Errorf("getTempAppInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + appInfo, err := as.appRepo.GetAppInfo(ctx, tempRspInfo.AppID) + if err != nil && !NotFound(err) { + log.Errorf("GetTrialInfo GetAppInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appInfo.AppTag) > 0 { + for _, v := range appInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + buildInfo := new(pb.BuildAppInfo) + buildInfo.CodeId = codeId + buildInfo.CoreDescription = tempRspInfo.CoreDescription + buildInfo.Created = tempRspInfo.Created + buildInfo.CreatedBy = tempRspInfo.CreatedBy + buildInfo.CustomData = ConvertRpcCustomDataToPb(tempRspInfo.CustomData) + buildInfo.CustomData.AppRuntimeDomain = new(pb.AppRuntimeDomain) + buildInfo.GroupId = tempRspInfo.GroupID + buildInfo.GroupName = tempRspInfo.GroupName + buildInfo.Logo = tempRspInfo.Logo + buildInfo.Name = tempRspInfo.Name + buildInfo.Version = tempRspInfo.Version + buildInfo.IsTemp = true + buildInfo.NeedCrt = tempRspInfo.NeedCrt + buildInfo.AppId = tempRspInfo.AppID + buildInfo.AppTag = appTagArr + buildInfo.PrivacySettingType = int32(appInfo.PrivacySettingType) + buildInfo.ProjectType = int32(tempRspInfo.ProjectType) + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, tempRspInfo.AppID) + if err == nil { + buildInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(wechatLoginInfo) + //return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + return buildInfo, rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppService) getTempAppInfo(ctx context.Context, appId string, seq int) (InternalGetAppVerInfoRsp, error) { + rspInfo := InternalGetAppVerInfoRsp{} + //首先判断是否在临时表中 + appTempInfo, err := as.tempAppRepo.GetInfoByAppIdAndSeq(ctx, appId, seq) + if err != nil { + return rspInfo, err + } + rspInfo = InternalGetAppVerInfoRsp{ + AppID: appTempInfo.AppID, + Name: appTempInfo.Name, + Sequence: appTempInfo.Sequence, + AppClass: appTempInfo.AppClass, + AppType: appTempInfo.AppType, + Status: proto.AppRspStatus{ + Value: appTempInfo.Status.Value, + Reason: appTempInfo.Status.Reason, + LastUpdated: appTempInfo.Status.LastUpdated, + ModifiedBy: appTempInfo.Status.ModifiedBy, + }, + DeveloperID: appTempInfo.DeveloperID, + GroupID: appTempInfo.GroupID, + GroupName: "", + Created: appTempInfo.Created, + CreatedBy: appTempInfo.CreatedBy, + Version: appTempInfo.Version, + CoreDescription: appTempInfo.CoreDescription, + Logo: appTempInfo.Logo, + ProjectType: appTempInfo.ProjectType, + } + + rspInfo.CustomData.DetailDescription = appTempInfo.CustomData.DetailDescription + rspInfo.CustomData.VersionDescription = appTempInfo.CustomData.VersionDescription + rspInfo.CustomData.AppRuntimeDomain.Business.Domains = []string{} // = domainData.Business + rspInfo.CustomData.AppRuntimeDomain.Service.Request = []string{} // = domainData.Service + rspInfo.CustomData.AppRuntimeDomain.Service.Socket = []string{} + rspInfo.CustomData.AppRuntimeDomain.Service.Download = []string{} + rspInfo.CustomData.AppRuntimeDomain.Service.Upload = []string{} + rspInfo.CustomData.AppRuntimeDomain.Whitelist.Domains = []string{} // = domainData.Whitelist + rspInfo.CustomData.AppRuntimeDomain.Blacklist.Domains = []string{} + rspInfo.CustomData.SourceFile = make([]proto.RspCustomDataSourceFile, 0) + if len(appTempInfo.CustomData.SourceFile) > 0 { + temp := appTempInfo.CustomData.SourceFile[0] + item := proto.RspCustomDataSourceFile{} + item.SourceFileUrl = "" + item.FileMd5 = temp.FileMd5 + item.Url = temp.Url + item.UploadDate = temp.UploadDate + item.Name = temp.Name + item.BasicPackVer = temp.BasicPackVer + item.Packages = convertPackages2(temp.EncryptPackages) + rspInfo.CustomData.SourceFile = append(rspInfo.CustomData.SourceFile, item) + } + + rspInfo.IsTemp = true + rspInfo.NeedCrt = false + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId) + if err == nil { + rspInfo.WechatLoginInfo = *wechatLoginInfo + //return rspInfo, errors.New("get wechatLoginInfo err") + } + + return rspInfo, nil +} + +func (as *AppService) openApiGetAppVerInfoFromCache(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, error) { + return InternalGetAppVerInfoRsp{}, nil + //verCache := cache.NewAppVerCache() + //cacheInfoByte, err := verCache.Get(ctx, avs.genOpenApiCacheKey(appId, sequence)) + //if err != nil { + // log.Warnf("cache get app ver info err:[%s],app id:[%s],seq:[%d]", err.Error(), appId, sequence) + // return nil, err + //} + ////走缓存 + //log.Debugf("AppVerService OpenApiGetAppVerInfo in cache ...") + //cacheRspInfo := OpenApiAppVerCacheInfo{} + //err = json.Unmarshal(cacheInfoByte, &cacheRspInfo) + //if err != nil { + // return nil, err + //} + // + //rspInfo := InternalGetAppVerInfoRsp{ + // AppID: cacheRspInfo.AppID, + // Name: cacheRspInfo.Name, + // Sequence: cacheRspInfo.Sequence, + // AppClass: cacheRspInfo.AppClass, + // AppType: cacheRspInfo.AppType, + // Status: cacheRspInfo.Status, + // DeveloperID: cacheRspInfo.DeveloperID, + // DeveloperStatus: cacheRspInfo.DeveloperStatus, + // GroupID: cacheRspInfo.GroupID, + // GroupName: cacheRspInfo.GroupName, + // Created: cacheRspInfo.Created, + // CreatedBy: cacheRspInfo.CreatedBy, + // Version: cacheRspInfo.Version, + // CorporationID: cacheRspInfo.CorporationID, + // CoreDescription: cacheRspInfo.CoreDescription, + // Logo: cacheRspInfo.Logo, + // InGrayRelease: cacheRspInfo.InGrayRelease, + //} + // + //err, _, customData := ConvertModelCustomDataToRpc(ctx, avs, cacheRspInfo.GroupID, cacheRspInfo.CustomData, &cacheRspInfo.DomainData, sdkVer) + //if err != nil { + // log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error()) + // return nil, err + //} + //rspInfo.CustomData = *customData + //rspInfo.IsTemp = false + //rspInfo.NeedCrt = cacheRspInfo.DomainData.NeedCrt + //return &rspInfo, nil +} + +func (as *AppService) openApiGetAppVerInfoNoCache(ctx context.Context, appId string, sequence int, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + if sequence == 0 { + return as.GetInDevApp(ctx, appId, sdkVer) + } + appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, sequence) + if err != nil { + log.Errorf("InternalGetAppVerInfo get appVer info err:%s", err.Error()) + if repository.NotFound(err) { + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND) + } + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + //校验企业的状态 + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID) + log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED) + } + } + //获取域名 + domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVer.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR) + } + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("as.appRepo.GetAppInfo err:%s", err.Error()) + if repository.NotFound(err) { + log.Errorf("get appVer not found!") + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + } + + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appVer.AppTag) > 0 { + for _, v := range appVer.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + log.Debugln("AppTag:", appTagArr) + rspInfo := InternalGetAppVerInfoRsp{ + AppID: appVer.AppID, + Name: appVer.Name, + Sequence: appVer.Sequence, + AppClass: appVer.AppClass, + AppTag: appTagArr, + AppType: appVer.AppType, + Status: proto.AppRspStatus{ + Value: appVer.Status.Value, + Reason: appVer.Status.Reason, + LastUpdated: appVer.Status.LastUpdated, + ModifiedBy: appVer.Status.ModifiedBy, + }, + DeveloperID: appVer.DeveloperID, + GroupID: appVer.GroupID, + GroupName: groupInfo.GroupName, + Created: appVer.Created, + CreatedBy: appVer.CreatedBy, + Version: appVer.Version, + CorporationID: appVer.CorporationID, + CoreDescription: appVer.CoreDescription, + Logo: appVer.Logo, + InGrayRelease: appVer.InGrayRelease, + PrivacySettingType: appInfo.PrivacySettingType, + ProjectType: appInfo.ProjectType, + } + err, errCode, customData := ConvertModelCustomDataToRpc(ctx, appVer.GroupID, appVer.CustomData, domainData, sdkVer) + if err != nil { + log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + status := getAccountStatus(groupInfo) + rspInfo.CustomData = *customData + rspInfo.GroupStatus = groupInfo.ReviewStatus + rspInfo.IsTemp = false + rspInfo.NeedCrt = domainData.NeedCrt + rspInfo.DeveloperStatus = status + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId) + if err == nil { + rspInfo.WechatLoginInfo = *wechatLoginInfo + //return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + log.Debugf("rsp info:%+v", rspInfo) + return rspInfo, rsp +} + +//兼容之前sequence为0的情况 +func (as *AppService) GetInDevApp(ctx context.Context, appId, sdkVer string) (InternalGetAppVerInfoRsp, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + app, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("openApiGetAppVerInfoNoCache GetAppInfo err:%,appId:[%]", err.Error(), appId) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + buildInfo, err := as.buildRepo.GetLatestInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("openApiGetAppVerInfoNoCache GetLatestInfoByAppId err:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + log.Debugf("GetInDevApp buildInfo:%+v", buildInfo) + //校验企业的状态 + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, app.GroupID) + log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("InternalGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_COOPERATION_TERMINATED) + } + } + //获取域名 + domainData, err := hCaller.GetDomainInfoByOrganId(ctx, app.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR) + } + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(app.AppTag) > 0 { + for _, v := range app.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + rspInfo := InternalGetAppVerInfoRsp{ + AppID: app.AppID, + Name: app.Name, + Sequence: app.Sequence, + AppClass: app.AppClass, + AppType: app.AppType, + Status: proto.AppRspStatus{ + Value: app.Status.Value, + Reason: app.Status.Reason, + LastUpdated: app.Status.LastUpdated, + ModifiedBy: app.Status.ModifiedBy, + }, + DeveloperID: app.DeveloperID, + GroupID: app.GroupID, + GroupName: groupInfo.GroupName, + Created: app.Created, + CreatedBy: app.CreatedBy, + Version: buildInfo.Version, + CorporationID: app.GroupID, + CoreDescription: app.CoreDescription, + Logo: app.Logo, + InGrayRelease: false, + AppTag: appTagArr, + PrivacySettingType: app.PrivacySettingType, + ProjectType: app.ProjectType, + } + err, errCode, customData := ConvertModelCustomDataToRpc(ctx, app.GroupID, buildInfo.CustomData, domainData, sdkVer) + if err != nil { + log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return InternalGetAppVerInfoRsp{}, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + status := getAccountStatus(groupInfo) + rspInfo.CustomData = *customData + rspInfo.GroupStatus = groupInfo.ReviewStatus + rspInfo.IsTemp = false + rspInfo.NeedCrt = domainData.NeedCrt + rspInfo.DeveloperStatus = status + + log.Debugf("rsp info:%+v", rspInfo) + return rspInfo, rsp +} +func (as *AppService) UpExpire(ctx context.Context, appId string, expire int64) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + + err := as.appRepo.UpdateExpire(ctx, appId, expire) + if err != nil { + log.Errorf("AppService UpExpire err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + /*err = as.appRepo.UpdateExpireAppVersion(ctx, appId, 0, expire) + if err != nil { + log.Errorf("AppService UpExpire err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + }*/ + return rsp.SetLoc(http.StatusOK, utility.OK) +} + +type RuntimeGetAppResponse struct { + AppID string `json:"appId" bson:"appId"` + Name string `json:"name" bson:"name"` + Sequence int `json:"sequence" bson:"sequence"` + AppClass string `json:"appClass" bson:"appClass"` + AppTag []string `json:"appTag" bson:"appTag"` + AppType string `json:"appType" bson:"appType"` + DeveloperID string `json:"developerId" bson:"developerId"` + DeveloperStatus int `json:"developerStatus" bson:"developerStatus"` + GroupID string `json:"groupId" bson:"groupId"` + GroupName string `json:"groupName" bson:"groupName"` + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + CustomData proto.AppRspCustomData `json:"customData" bson:"customData"` + Version string `json:"version" bson:"version"` + CorporationID string `json:"corporationId" bson:"corporationId"` + CoreDescription string `json:"coreDescription" bson:"coreDescription"` + Logo string `json:"logo" bson:"logo"` + Status proto.AppRspStatus `json:"status" bson:"status"` + InGrayRelease bool `json:"inGrayRelease" bson:"inGrayRelease"` //是否在灰度发布中 + IsTemp bool `json:"isTemp"` + NeedCrt bool `json:"needCrt"` //是否需要校验域名证书 + WechatLoginInfo proto.WechatLoginInfo `json:"wechatLoginInfo"` + PrivacySettingType int `json:"privacySettingType"` + ProjectType int `json:"projectType"` +} + +func (as *AppService) RuntimeGetPubAppInfo(ctx context.Context, sdkKey, appId, sdkVer string) (RuntimeGetAppResponse, *utility.SvrRsp) { + resp := &RuntimeGetAppResponse{} + rsp := utility.DefaultSvrRsp() + inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry) + //未命中缓存 + start := time.Now() + log.Infof("RuntimeGetPubAppInfo from cache no match ... ") + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("RuntimeGetPubAppInfo GetAppInfo err:%s", err.Error()) + if repository.NotFound(err) { + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND) + } + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + if appInfo.IsForbidden == 1 { + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN) + } + + app, err := as.appRepo.GetOnlineAppVer(ctx, appId) + if err != nil { + if repository.NotFound(err) { + log.Errorf("RuntimeGetPubAppInfo get info app status invalid,appId:%s", appId) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_SERVICE_UNAVAILABLE) + } + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + log.Debugf("RuntimeGetPubAppInfo online app:%+v", app) + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appInfo.AppTag) > 0 { + for _, v := range appInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + + //支付信息过期校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + appStatus, err := as.CheckIdStatus(ctx, appId) + if err != nil { + log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appId) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("check purch status no ok ") + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + //获取机构信息 + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, app.GroupID) + if err != nil { + log.Errorf("Failed to call GetGroupInfoByUserId: %v", err) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + status := getAccountStatus(groupInfo) + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("group review status no ok ") + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("group review status no ok ") + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + //获取域名信息 + domainData, err := hCaller.GetAppDomainByOrganId(ctx, app.GroupID) + if err != nil { + log.Errorf("Failed to call GetDomainInfo: %v", err) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + //应用状态信息校验 + if !inWhiteList { + //首先判断sdkKey是否存在 + var bindingInfo *entity.Binding + bindingInfo, err = as.bindingRepo.GetBindingByGroupIdAndSdkKey(ctx, app.GroupID, sdkKey) + if err != nil { + log.Errorf("GetBindingByGroupIdAndSdkKey err:%s", err.Error()) + if repository.NotFound(err) { + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_SIGNATURE_SDKKEY_INVAILD) + } + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if bindingInfo.CooperateStatus.Value != entity.StBindValid { + log.Errorf("binding coop stats valid,appId:%s,sdkKey:%s", appId, sdkKey) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + for _, v := range bindingInfo.BundleInfos { + if v.SDKKey == sdkKey && v.IsForbidden == 1 { + log.Errorf("bundleInfo is forbidden", bindingInfo) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + isAppAssBind := false + for _, v := range bindingInfo.AppInfos { + if v.AppID == appId { + isAppAssBind = true + } + } + if !isAppAssBind { + log.Errorf("app id not ass binding,appId:%s,sdkKey:%s", appId, sdkKey) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + //支付信息校验 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("binding pay check no ok,bingdingId:%s", bindingInfo.BindingID) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE) + } + } + } + if GetLicenseValid() != LICENSE_IS_VALID { + log.Errorf("license valid no ok ... ") + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_LICENSE_INVALID_ERR) + } + //返回数据 + err = covertAppToRsp(ctx, &app, resp, sdkVer, domainData) + if err != nil { + log.Errorf("covertAppToRsp err:%s", err.Error()) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + resp.GroupName = groupInfo.GroupName + resp.DeveloperStatus = status + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId) + if err == nil { + resp.WechatLoginInfo = *wechatLoginInfo + //return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + resp.AppTag = appTagArr + resp.PrivacySettingType = appInfo.PrivacySettingType + resp.ProjectType = appInfo.ProjectType + log.Infof("resp:%v", resp) + + fmt.Println("RuntimeGetPubAppInfo get app no cache time consum:", time.Since(start)) + + return *resp, rsp.SetLoc(http.StatusOK, utility.OK) +} + +//type RuleEngineGetAppVerInfoRsp struct { +// AppID string `json:"appId"` +// Name string `json:"name"` +// Sequence int `json:"sequence"` +// AppClass string `json:"appClass"` +// AppType string `json:"appType"` +// DeveloperID string `json:"developerId"` +// DeveloperStatus int `json:"developerStatus"` +// GroupID string `json:"groupId"` +// GroupName string `json:"groupName"` +// Created int64 `json:"created"` +// CreatedBy string `json:"createdBy"` +// CustomData proto.AppRspCustomData `json:"customData"` +// Version string `json:"version"` +// CorporationID string `json:"corporationId"` +// CoreDescription string `json:"coreDescription"` +// Logo string `json:"logo"` +// Status proto.AppRspStatus `json:"status"` +// InGrayRelease bool `json:"inGrayRelease"` //是否在灰度发布中 +// IsTemp bool `json:"isTemp"` +// NeedCrt bool `json:"needCrt"` +//} + +func (as *AppService) RuleEngineGetAppVerInfo(ctx context.Context, appId string, sequence int, sdkKey, sdkVer string) (RuntimeGetAppResponse, *utility.SvrRsp) { + //appVerCache := cache.NewAppVerCache() + //appVerCacheInfoByte, err := appVerCache.Get(ctx, avs.genRuleEngineCacheKey(appId, sequence)) + //if err == nil { + // log.Infof("RuleEngineGetAppVerInfo in cache ...") + // appVerInfo := RuleEngineAppVerCacheInfo{} + // err = json.Unmarshal(appVerCacheInfoByte, &appVerInfo) + // if err == nil { + // //判断是否关联 + // if _, ok := appVerInfo.BindStatus[sdkKey]; ok { + // rsp, err := avs.covertCacheToRuleEngineRsp(ctx, &appVerInfo, sdkVer) + // if err != nil { + // log.Errorf("covertCacheToRuleEngineRsp err:%s", err.Error()) + // return nil, http.StatusInternalServerError, common.FS_SYSTEM_CALL + // } + // return rsp, http.StatusOK, common.OK + // } + // } + //} + + //未命中缓存 + resp := RuntimeGetAppResponse{} + rsp := utility.DefaultSvrRsp() + //首先校验licesne + if GetLicenseValid() != LICENSE_IS_VALID { + log.Errorf("RuleEngineGetAppVerInfo get info license invalid,sdkKey:%s,appId:%s,sequence:%d", sdkKey, appId, sequence) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_LICENSE_INVALID_ERR) + } + appVer, err := as.appRepo.GetAppVerInfo(ctx, appId, sequence) + if err != nil { + log.Errorf("GetAppVerInfo err:%s", err.Error()) + if repository.NotFound(err) { + return resp, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_SEQUENCE_NOT_FOUND) + } + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + //校验企业的状态,非法状态不放入缓存 + log.Infof("get group info id:%s", appVer.GroupID) + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID) + log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo) + if err != nil { + log.Errorf("RuleEngineGetAppVerInfo ger group info err:%s", err.Error()) + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_GROUP_FAILED) + } + status := getAccountStatus(groupInfo) + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + //if !avs.isOrganValid(groupInfo.ReviewStatus) { + // log.Errorf("RuleEngineGetAppVerInfo group ReviewStatus invalid,status:%v", groupInfo.ReviewStatus) + // return nil, http.StatusForbidden, common.FS_ORGAN_STATUS_INVALID + //} + inWhiteList := utility.InArry(sdkKey, config.WhiteSDKArry) + if !inWhiteList { + //校验应用关联状态,非法状态不放入缓存 + binds, err := as.bindingRepo.GetBindingByGroupIdAndSdkKey(ctx, appVer.GroupID, sdkKey) + if err != nil { + log.Errorf("GetBindingByGroupIdAndSdkKey err:%s,GroupID:%s,sdkKey:%s", err.Error(), appVer.GroupID, sdkKey) + if repository.NotFound(err) { + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_SIGNATURE_SDKKEY_INVAILD) + } + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if binds.CooperateStatus.Value != entity.StBindValid { + log.Errorf("RuleEngineGetAppVerInfo CooperateStatus invalid:%s", binds.CooperateStatus.Value) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + + for _, v := range binds.BundleInfos { + if v.SDKKey == sdkKey && v.IsForbidden == 1 { + log.Errorf("bundleInfo is forbidden", binds) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + + isAppAssBinding := false + for _, v := range binds.AppInfos { + if v.AppID == appId { + isAppAssBinding = true + } + } + if !isAppAssBinding { + log.Errorf("RuleEngineGetAppVerInfo get binding info no ass app,appId:%s,sdkKey:%s", appId, sdkKey) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + //校验应用支付状态 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + bindStatus, err := as.CheckIdStatus(ctx, binds.BindingID) + if err != nil { + log.Errorf("RuleEngineGetAppVerInfo get bind id pay status err:%s", err.Error()) + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("GetGrayAppInfo get info bind pay status invaild,bind id:%s", binds.BindingID) + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_PAY_EXPIRE) + } + } + } + //校验小程序的上架状态 + if appVer.Status.Value != entity.StPublished && !appVer.InGrayRelease { + log.Errorf("RuleEngineGetAppVerInfo appVer status invalid:%s", appVer.Status.Value) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_SERVICE_UNAVAILABLE) + } + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("RuleEngineGetAppVerInfo GetAppInfo err:%s", err.Error()) + if repository.NotFound(err) { + return resp, rsp.SetLoc(http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND) + } + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + if appInfo.IsForbidden == 1 { + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_IS_FORBIDDEN) + } + + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagArr := make([]string, 0) + if len(appInfo.AppTag) > 0 { + for _, v := range appInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagArr = append(appTagArr, tag.Name) + } + } + } + } + //校验支付状态 + if config.Cfg.OpenPurchAuth && config.Cfg.IsUatEnv() { + //先校验小程序 + appStatus, err := as.CheckIdStatus(ctx, appId) + if err != nil { + log.Errorf("RuleEngineGetAppVerInfo get app id pay status err:%s", err.Error()) + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("RuleEngineGetAppVerInfo get info app pay status invaild,appId:%s", appId) + return resp, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + //获取域名 + domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVer.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return resp, rsp.SetLoc(http.StatusInternalServerError, utility.FS_GET_DOMAIN_INFO_ERROR) + } + err = covertAppToRsp(ctx, &appVer, &resp, sdkVer, domainData) + if err != nil { + log.Errorf("covertAppToRsp err:%s", err.Error()) + return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + resp.DeveloperStatus = status + resp.GroupName = groupInfo.GroupName + resp.PrivacySettingType = appInfo.PrivacySettingType + resp.ProjectType = appInfo.ProjectType + resp.AppTag = appTagArr + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId) + if err == nil { + resp.WechatLoginInfo = *wechatLoginInfo + //return RuntimeGetAppResponse{}, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SYSTEM_CALL) + } + + return resp, rsp +} + +func (as *AppService) CheckIdStatus(ctx context.Context, id string) (int, error) { + return httpcall.PAY_ID_STATUS_USING, nil + /*switch config.Cfg.ReqType { + //case "grpc": + // return grpcClient.PurchasingGetIdStatus(ctx, id) + default: + status, _, err := hCaller.PayCheckIdStatus(ctx, id) + return status, err + }*/ +} + +func (as *AppService) BatchAppsByIdentity(ctx context.Context, sdkKey string, req *apiproto.BatchAppsByIdentityReq) *pb.BatchAppsByIdentityRsp { + var ( + rsp = new(pb.BatchAppsByIdentityRsp) + ) + rsp.Data = new(pb.BatchAppsByIdentityRsp_DATA) + rsp.Data.AppList = make([]*pb.BatchAppsByIdentityRsp_AppListItem, 0) + rsp.Result = new(pb.CommonResult) + //判断sdkKey是否存在 + sdkExi, err := as.bindingRepo.SdkKeyExi(ctx, sdkKey) + if err != nil { + utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_SYSTEM_CALL, &rsp.Result) + return rsp + } + if !sdkExi { + utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND, &rsp.Result) + return rsp + } + for _, item := range req.Apps { + rspAppListItem := as.getOneAppByIdentity(ctx, req.IdentityType, item.AppId, item.Identity, sdkKey) + rsp.Data.AppList = append(rsp.Data.AppList, rspAppListItem) + } + utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result) + return rsp +} + +func (as *AppService) IdentityAppsCheck(ctx context.Context, sdkKey string, req *apiproto.IdentityAppsCheckReq) *pb.IdentityAppsCheckRsp { + var ( + rsp = new(pb.IdentityAppsCheckRsp) + ) + rsp.Data = new(pb.IdentityAppsCheckRsp_DATA) + rsp.Data.AppList = make([]*pb.IdentityAppsCheckRsp_AppListItem, 0) + rsp.Result = new(pb.CommonResult) + //判断sdkKey是否存在 + sdkExi, err := as.bindingRepo.SdkKeyExi(ctx, sdkKey) + if err != nil { + utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_SYSTEM_CALL, &rsp.Result) + return rsp + } + if !sdkExi { + utility.MakeGrpcCommonResult(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND, &rsp.Result) + return rsp + } + //判断一个小程序identity是否存在 + //todo 加个缓存处理 + for _, a := range req.Apps { + rspAppListItem := as.getOneAppCheckResult(ctx, a.AppId, a.Identity, req.IdentityType, sdkKey) + rsp.Data.AppList = append(rsp.Data.AppList, rspAppListItem) + } + utility.MakeGrpcCommonResult(http.StatusOK, utility.OK, &rsp.Result) + return rsp +} + +func (as *AppService) getOneAppCheckResult(ctx context.Context, appId, identity, identityType, sdkKey string) (rspAppListItem *pb.IdentityAppsCheckRsp_AppListItem) { + rspAppListItem = &pb.IdentityAppsCheckRsp_AppListItem{ + Errcode: utility.OK, + Error: utility.GetErrMsg(utility.OK), + Data: &pb.IdentityAppsCheckRsp_AppListItem_AppListItemData{AppId: appId, Identity: identity, IdentityValid: false}, + } + defer func() { + rspAppListItem.Error = utility.GetErrMsg(rspAppListItem.Errcode) + }() + //cacheInfo, err := e.erc.GetAppCheckValid(ctx, appId, identity, sdkKey) + //if err == nil { + // log.Debugf("getOneAppCheckResult from cache,info:%+v", cacheInfo) + // rspAppListItem.Data.IdentityValid = cacheInfo.IdentityValid + // rspAppListItem.Errcode = cacheInfo.Errcode + // return rspAppListItem + //} + //defer func() { + //if rspAppListItem.Errcode != utility.FS_SYSTEM_CALL { + //setCacheInfo := &AppCheckCacheInfo{IdentityValid: rspAppListItem.Data.IdentityValid, Errcode: rspAppListItem.Errcode} + //log.Debugf("set app check cache info:%+v", cacheInfo) + //if err = e.erc.SetAppCheckValid(ctx, appId, identity, sdkKey, setCacheInfo); err != nil { + // log.Errorf("SetAppCheckValid err:%s", err.Error()) + //} + //} + //}() + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("get app info err:%s", err.Error()) + rspAppListItem.Errcode = utility.FS_SYSTEM_CALL + if repository.NotFound(err) { + rspAppListItem.Errcode = utility.FS_APP_ID_NOT_FOUND + } + return rspAppListItem + } + log.Debugf("get app info:%+v", appInfo) + //判断该小程序是否可用 + if appInfo.Status.Value != entity.StPublished { + log.Errorf("app info status invalid,sdkKey:[%s],appInfo:%+v", sdkKey, appInfo) + return rspAppListItem + } + //判断企业状态 + organInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID) + if err != nil { + log.Errorf("get group info err:%s", err.Error()) + rspAppListItem.Errcode = utility.FS_SYSTEM_CALL + return rspAppListItem + } else { + if !hCaller.JudgeGroupStatusValid(organInfo.ReviewStatus) { + log.Errorf("gropu status invalid,sdkKey:[%s],appId:[%s]", sdkKey, appId) + rspAppListItem.Errcode = utility.FS_ORGAN_STATUS_INVALID + return rspAppListItem + } + } + //判断是否关联 + bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appInfo.GroupID, sdkKey) + if err != nil { + log.Errorf("get binging info err:%s", err.Error()) + rspAppListItem.Errcode = utility.FS_SYSTEM_CALL + if repository.NotFound(err) { + rspAppListItem.Errcode = utility.FS_BIND_NOT_FOUND + } + return rspAppListItem + } else { + if bindingInfo.CooperateStatus.Value == entity.StBindInvalid { + log.Errorf("binding info coop value invalid:%+v,sdkKey:[%s]", bindingInfo, sdkKey) + rspAppListItem.Errcode = utility.FS_COOPERATION_TERMINATED + return rspAppListItem + } + if !repository.IsAssAppId(bindingInfo, appId) { + log.Errorf("binding not ass the appid,sdkKey:[%s],appId:[%s]", sdkKey, appId) + rspAppListItem.Errcode = utility.FS_APP_NOT_ASS_BIND + return rspAppListItem + } + } + //判断版本状态 + appVers, err := as.appRepo.GetAppVerLimitByIdentity(ctx, identityType, appId, identity, config.Cfg.CheckAppVerLimit) + if err != nil { + rspAppListItem.Errcode = utility.FS_SYSTEM_CALL + if repository.NotFound(err) { + rspAppListItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR + } + return rspAppListItem + } else { + if len(appVers) == 0 { + rspAppListItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR + return rspAppListItem + } + rspAppListItem.Data.IdentityValid = as.AppVerIsValid(appVers) + } + + return rspAppListItem +} + +func (as *AppService) getOneAppByIdentity(ctx context.Context, t, appId, identity, sdkKey string) *pb.BatchAppsByIdentityRsp_AppListItem { + rspItem := &pb.BatchAppsByIdentityRsp_AppListItem{ + Errcode: utility.OK, + Error: utility.GetErrMsg(utility.OK), + AppId: appId, + Identity: identity, + AppInfo: nil, + ExternalAppStatus: "", + } + defer func() { + rspItem.Error = utility.GetErrMsg(rspItem.Errcode) + }() + + appVers, err := as.appRepo.GetAppVerLimitByIdentity(ctx, t, appId, identity, config.Cfg.CheckAppVerLimit) + if err != nil { + rspItem.Errcode = utility.FS_SYSTEM_CALL + if repository.NotFound(err) { + rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR + } + return rspItem + } + if len(appVers) == 0 { + rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR + return rspItem + } + //从获取到的三个版本列表中取得一个合适的版本 + appVer := as.GetConcreteVer(appVers) + if appVer == nil { + rspItem.Errcode = utility.FS_IDENTITY_NOT_FOUND_ERR + return rspItem + } + + //判断企业状态 + organInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVer.GroupID) + if err != nil { + rspItem.Errcode = utility.FS_SYSTEM_CALL + return rspItem + } else { + if !hCaller.JudgeGroupStatusValid(organInfo.ReviewStatus) { + rspItem.Errcode = utility.FS_ORGAN_STATUS_INVALID + return rspItem + } + } + + //判断是否关联 + bindingInfo, err := as.bindingRepo.GetInfoBySdkKeyOrganId(ctx, appVer.GroupID, sdkKey) + log.Debugf("get binding info:%+v", bindingInfo) + if err != nil { + log.Errorf("get binging info err:%s", err.Error()) + rspItem.Errcode = utility.FS_SYSTEM_CALL + if repository.NotFound(err) { + rspItem.Errcode = utility.FS_BIND_NOT_FOUND + } + return rspItem + } else { + if bindingInfo.CooperateStatus.Value == entity.StBindInvalid { + rspItem.Errcode = utility.FS_COOPERATION_TERMINATED + return rspItem + } + if !repository.IsAssAppId(bindingInfo, appId) { + rspItem.Errcode = utility.FS_APP_NOT_ASS_BIND + return rspItem + } + } + + rspItem.AppInfo = new(pb.AppInfoRspData) + + as.tool.CovertAppVerToAppRspData(appVer, rspItem.AppInfo) + + //custom 包装 + domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, appVer.GroupID) //域名 + if err != nil { + log.Errorf("get domain err:%s", err.Error()) + } else { + as.tool.PackDomainToAppRspCustom(rspItem.AppInfo, domainInfo) + } + rspItem.AppInfo.CustomData.MenuInfo = nil //菜单 + apiData, err := hCaller.GetApiList(ctx, appVer.GroupID) //api管理 + if err != nil { + log.Errorf("get api list err:%s", err.Error()) + } else { + as.tool.PackApiInfoToAppRspCustom(rspItem.AppInfo, &apiData) + } + + rspItem.AppInfo.GroupName = organInfo.GroupName //企业名称 + rspItem.ExternalAppStatus = as.getAppVerExternalStatus(appVer.Status.Value, appVer.UnpublishedStatus.Type) //做一个状态的转换 + + //放入缓存 + //e.erc.SetAppVerCacheInfo(ctx, appId, identity, &ExternalAppVerCacheInfo{AppInfo: rspItem.AppInfo, ExternalStatus: rspItem.ExternalAppStatus}) + + return rspItem +} + +func (as *AppService) GetConcreteVer(appVers []entity.AppVersion) *entity.AppVersion { + if len(appVers) == 0 { + return nil + } + appVer := appVers[0] + for _, v := range appVers { + if v.Status.Value == entity.StPublished { + appVer = v + break + } + if v.Status.Value == entity.StUnpublished && + v.UnpublishedStatus.Type == entity.TypeUnpublishedDueToNewSeq { + appVer = v + break + } + } + return &appVer +} + +func (as *AppService) getAppVerExternalStatus(statusValue, unPubType string) string { + //做一个状态的转换 + result := "" + switch statusValue { + case entity.StInDevelopment: + result = AppExternalStatusInDevelopment + case entity.StPublishing: + result = AppExternalStatusPublishing + case entity.StPublishWithdrawed: + result = AppExternalStatusPublishWithdrawed + case entity.StPublishApproved: + result = AppExternalStatusPublishApproved + case entity.StPublishRejected: + result = AppExternalStatusPublishRejected + case entity.StPublished: + result = AppExternalStatusPublished + case entity.StUnpublished: + switch unPubType { + case entity.TypeUnpublishedByDev: + result = AppExternalStatusUnpublishedByDev + case entity.TypeUnpublishedByAdmin: + result = AppExternalStatusUnpublishedByAdmin + case entity.TypeUnpublishedDueToNewSeq: + result = AppExternalStatusUnpublishedByNewSeq + } + } + return result +} + +/* + * 第一优先级:AppID 为已上架 ,则可继续使用;如下架则全部不允许使用 + * 第二优先级: + * 当AppID上架的情况下,MD5对应 已上架 / 系统下架,则允许继续使用; + * 如对应状态为在途(审核中/审核已撤销)的,则向下轮询3个序列号,如果3个序列号中包含 已上架/系统下架,则允许使用;如3个序列号均为在途状态,则返回不可用 + * 如为其他状态(不在上述内容内),则返回不可用 + */ +func (as *AppService) AppVerIsValid(appVers []entity.AppVersion) bool { + valid := false + for _, appVerInfo := range appVers { + if appVerInfo.Status.Value == entity.StPublishing || + appVerInfo.Status.Value == entity.StPublishWithdrawed { + continue + } + //首先判断该版本是否可用 + if appVerInfo.Status.Value != entity.StPublished && + appVerInfo.Status.Value != entity.StUnpublished { + log.Errorf("app ver info invalid,app ver:%+v", appVerInfo) + valid = false + break + } + log.Debugf("get app ver info status:%+v", appVerInfo.Status) + //判断该版本下架方式:被运营端下架、被机构端下架、新版本下架 + if appVerInfo.Status.Value == entity.StUnpublished { + if appVerInfo.UnpublishedStatus.Type == entity.TypeUnpublishedDueToNewSeq { + valid = true + break + } + } + if appVerInfo.Status.Value == entity.StPublished { + valid = true + break + } + } + log.Debugf("valid:[%v],appvers:%v", valid, appVers) + return valid +} + +func (as *AppService) GenOfflinePackageInfo(ctx context.Context, appId string, seq int, userId string) (string, error) { + userInfo, err := hCaller.GetAccountInfo(ctx, userId) + if err != nil { + log.Errorf("GenOfflinePackageInfo GetDeveloperInfo err:%s", err.Error()) + return "", err + } + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, appId, seq) + if err != nil { + log.Errorf("GenOfflinePackageInfo db err:%s", err.Error()) + return "", err + } + if userInfo.OrganId != appVerInfo.GroupID { + log.Errorf("GenOfflinePackageInfo organ id no match app ver info group id") + return "", errors.New("group id not match") + } + //文件生成 + if len(appVerInfo.CustomData.SourceFile) == 0 { + log.Errorf("GenOfflinePackageInfo CustomData.SourceFile empty!") + return "", errors.New("db info err") + } + //miniprogram.json + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appVerInfo.GroupID) + if err != nil { + log.Errorf("get group info err:%s", err.Error()) + return "", err + } + miniprogramInfo := covertAppVerToRuleEngineRsp(&appVerInfo) + //获取域名 + domainData, err := hCaller.GetDomainInfoByOrganId(ctx, appVerInfo.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return "", err + } + err, _, customData := ConvertModelCustomDataToRpc(ctx, appVerInfo.GroupID, appVerInfo.CustomData, domainData, "cache") + if err != nil { + log.Errorf("covertCacheInfoToRsp ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return "", err + } + wechatLoginInfo, err := hCaller.GetWeChatLoginInfo(ctx, appId) + if err != nil { + log.Errorf("covertCacheInfoToRsp ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return "", err + } + miniprogramInfo.CustomData = *customData + miniprogramInfo.GroupName = groupInfo.GroupName //附加 + miniprogramInfo.NeedCrt = domainData.NeedCrt + miniprogramInfo.WechatLoginInfo = *wechatLoginInfo + sourceFile := appVerInfo.CustomData.SourceFile[0] + + miniprogramJsonRsp := gin.H{ + "error": "OK", + "errcode": "", + "data": miniprogramInfo, + } + dir := path.Join("/opt/finclip-offline-packages/", bson.NewObjectId().Hex()) + fileDir := path.Join(dir, appVerInfo.AppID) + err = os.MkdirAll(fileDir, os.ModePerm) + if err != nil { + log.Errorf("mkdir err:%s", err.Error()) + return "", err + } + defer os.RemoveAll(dir) + miniprogramJsonFileName := path.Join(fileDir, "miniprogram.json") + log.Debugf("file dir:%s", fileDir) + miniprogramJsonFile, err := os.OpenFile(miniprogramJsonFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + log.Errorf("open file err:%s", err.Error()) + return "", err + } + defer miniprogramJsonFile.Close() + miniprogramJsonByte, _ := json.Marshal(miniprogramJsonRsp) + _, err = miniprogramJsonFile.Write(miniprogramJsonByte) + if err != nil { + log.Errorf("write file err:%s", err.Error()) + return "", err + } + var fileList = make([]string, 0) + fileList = append(fileList, miniprogramJsonFileName) + log.Debugf("sourceFile:%+v", sourceFile) + if len(sourceFile.EncryptPackages) > 0 { //分包 + //分包小程序存储位置 + splitPackFileDir := path.Join(fileDir, "miniprogram") + log.Debugf("splitPackFileDir:%s", splitPackFileDir) + err = os.Mkdir(splitPackFileDir, os.ModePerm) + if err != nil { + log.Errorf("mkdir splitPackFileDir err:%s", err.Error()) + return "", err + } + //下载多个包 + splitPackFileList := make([]string, 0) + for _, p := range sourceFile.EncryptPackages { + tempList := strings.Split(p.FileUrl, "/") + fileBody, err := hCaller.DownloadByNetdiskId(ctx, tempList[len(tempList)-1]) + if err != nil { + log.Errorf("download file err:%s", err.Error()) + return "", err + } + fName := path.Join(splitPackFileDir, p.Filename) + tempFile, err := os.Create(fName) + if err != nil { + log.Errorf("create splitPackFileDir err:%s", err.Error()) + return "", err + } + _, err = tempFile.Write(fileBody) + if err != nil { + log.Errorf("tempFile write err:%s", err.Error()) + return "", err + } + tempFile.Close() + splitPackFileList = append(splitPackFileList, fName) + } + //压缩之后再删除源文件 + miniprogramZipFileName := path.Join(fileDir, "miniprogram.zip") + err = ZipList(splitPackFileList, miniprogramZipFileName) + if err != nil { + log.Errorf("splitPackFileDir zip err:%s", err.Error()) + return "", err + } + err = os.RemoveAll(splitPackFileDir) + if err != nil { + log.Errorf("splitPackFileDir remove err:%s", err.Error()) + return "", err + } + fileList = append(fileList, miniprogramZipFileName) + } else { //整包 + var fileUrl = sourceFile.SourceFileUrl + if sourceFile.EncryptedUrl != "" { + fileUrl = sourceFile.EncryptedUrl + } + if fileUrl == "" { + log.Errorf("file url empty,appId:[%s],sequence:[%d]", appId, seq) + return "", errors.New("db info err") + } + fileBody, err := hCaller.DownloadByNetdiskId(ctx, getFileId(fileUrl)) + if err != nil { + log.Errorf("download file err:%s", err.Error()) + return "", err + } + appFileName := path.Join(fileDir, "app.zip") + //appFileName := path.Join(fileDir, "miniprogram.zip") + appFile, err := os.OpenFile(appFileName, os.O_WRONLY|os.O_CREATE, 0666) + if err != nil { + log.Errorf("one packege open err:%s", err.Error()) + return "", err + } + _, err = appFile.Write(fileBody) + appFile.Close() + if err != nil { + log.Errorf("one packege write file err:%s", err.Error()) + return "", err + } + //再将小程序包压缩为miniprogram.zip + miniprogramZipFileName := path.Join(fileDir, "miniprogram.zip") + err = ZipList([]string{appFileName}, miniprogramZipFileName) + if err != nil { + log.Errorf("zip app file err:%s", err.Error()) + return "", err + } + os.Remove(appFileName) + fileList = append(fileList, miniprogramZipFileName) + } + encryptPwd := utils.GenMd5("miniprogram" + appVerInfo.AppID) + log.Debugf("encryptPwd:%s", encryptPwd) + encryptFileName := fileDir + ".zip" + //err = EncryptZip(fileDir, encryptFileName, encryptPwd) + err = EncryptList(fileList, encryptFileName, encryptPwd) + if err != nil { + log.Errorf("EncryptZip err:%s", err.Error()) + return "", err + } + encryptFile, err := os.Open(encryptFileName) + if err != nil { + log.Errorf("open file err:%s", err.Error()) + return "", err + } + resultUrl, err := hCaller.Upload(ctx, appVerInfo.AppID+".zip", encryptFile, false) + if err != nil { + log.Errorf("upload err:%s", err.Error()) + return "", err + } + log.Debugf("upload id:%s", resultUrl) + return getFileId(resultUrl), nil +} + +func (as *AppService) GetAppClassList(ctx context.Context) ([]entity.CItem, error) { + appClassList, err := as.appRepo.GetAppClassList(ctx) + if err != nil { + return make([]entity.CItem, 0), err + } + + return appClassList, err +} + +func (as *AppService) GetAppTagList(ctx context.Context) ([]entity.TagItem, error) { + appTagList, err := as.appRepo.GetAppTagList(ctx) + if err != nil { + return make([]entity.TagItem, 0), err + } + + return appTagList, err +} + +func (as *AppService) SavePrivacySetting(ctx context.Context, req apiproto.PrivacySettingReq) error { + info := entity.PrivacySettingInfo{} + info.AppId = req.AppId + /*userMessageTypeObj:=entity.UserMessageTypeObj{} + userMessageTypeObj.UserMes=req.UserMessageType.UserMes + userMessageTypeObj.LocationMes=req.UserMessageType.LocationMes + userMessageTypeObj.Microphone=req.UserMessageType.Microphone + userMessageTypeObj.Camera=req.UserMessageType.Camera + userMessageTypeObj.EquipmentMes=req.UserMessageType.EquipmentMes + userMessageTypeObj.AddressBook=req.UserMessageType.AddressBook + userMessageTypeObj.PhotoAlbum=req.UserMessageType.PhotoAlbum + userMessageTypeObj.Calendar=req.UserMessageType.Calendar + userMessageTypeObj.OperationLog=req.UserMessageType.OperationLog + userMessageTypeObj.Bluetooth=req.UserMessageType.Bluetooth + userMessageTypeObj.Others=req.UserMessageType.Others*/ + info.CommitType = req.CommitType + info.UserMessageType = utility.InterfaceToJsonString(req.UserMessageType) + info.SdkMessage = utility.InterfaceToJsonString(req.SdkMessage) + info.ContactInfoEmail = req.ContactInfo.Email + info.ContactInfoPhone = req.ContactInfo.Phone + info.ContactInfoWeChat = req.ContactInfo.WeChat + info.ContactInfoOther = req.ContactInfo.Other + info.AdditionalDocName = req.AdditionalDocName + info.AdditionalDocNetDiskId = req.AdditionalDocNetDiskId + info.IsFirstSave = false + info.AdditionalDocContent = req.AdditionalDocContent + info.FixedStorageTime = req.FixedStorageTime + info.EffectiveTime = time.Now().UnixNano() / 1e6 + info.CreateTime = time.Now().UnixNano() / 1e6 + info.UpdateTime = time.Now().UnixNano() / 1e6 + + total, err := as.prviacySettingRepo.Count(ctx, req.AppId) + if err != nil { + log.Errorf("PrviacySettingRepo Count err:%s", err.Error()) + return err + } + if total > 0 { + err := as.prviacySettingRepo.UpdateInfo(ctx, info) + if err != nil { + log.Errorf("PrviacySettingRepo insert err:%s", err.Error()) + return err + } + } else { + err := as.prviacySettingRepo.Insert(ctx, info) + if err != nil { + log.Errorf("PrviacySettingRepo insert err:%s", err.Error()) + return err + } + } + appInfo, err := as.appRepo.GetAppInfo(ctx, req.AppId) + if err != nil { + log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error()) + if repository.NotFound(err) { + log.Errorf("DevPublishApp get appVer not found!") + return err + } + } + appInfo.PrivacySettingType = req.CommitType + err = as.appRepo.UpdateApp(ctx, appInfo) + if err != nil { + log.Errorf("UpdateAppIsPrivacySetting repo err:%s", err.Error()) + return err + } + return nil +} + +type GetPrivacySettingInfoRsp struct { + AppId string `json:"appId"` + CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况 + UserMessageType entity.UserMessageTypeObj `json:"userMessageType"` //用户使用类型 + SdkMessage []entity.SdkMessageInfoObj `json:"sdkMessage"` //sdk信息 + ContactInfo entity.ContactInfoObj `json:"contactInfo"` //联系方式 + FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间 + IsShortestTime bool `json:"isShortestTime"` //是否是最短时间 + AdditionalDocName string `json:"additionalDocName"` //补充文档名称 + AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容 + AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id + IsFirstSave bool `json:"isFirstSave"` + EffectiveTime int64 `json:"effectiveTime"` + CreateTime int64 `json:"createTime"` + UpdateTime int64 `json:"updateTime"` +} + +func (as *AppService) GetPrivacySettingInfo(ctx context.Context, appId string) (GetPrivacySettingInfoRsp, error) { + rsp := GetPrivacySettingInfoRsp{} + + item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("PrviacySettingRepo insert err:%s", err.Error()) + if NotFound(err) { + rsp.IsFirstSave = true + return rsp, nil + } + return rsp, err + } + rsp.AppId = item.AppId + rsp.FixedStorageTime = item.FixedStorageTime + rsp.IsShortestTime = item.IsShortestTime + var userMessageTypeObj entity.UserMessageTypeObj + json.Unmarshal([]byte(item.UserMessageType), &userMessageTypeObj) + rsp.UserMessageType = userMessageTypeObj + + var sdkMessage []entity.SdkMessageInfoObj + json.Unmarshal([]byte(item.SdkMessage), &sdkMessage) + rsp.SdkMessage = sdkMessage + rsp.CommitType = item.CommitType + rsp.ContactInfo.Phone = item.ContactInfoPhone + rsp.ContactInfo.Email = item.ContactInfoEmail + rsp.ContactInfo.WeChat = item.ContactInfoWeChat + rsp.ContactInfo.Other = item.ContactInfoOther + rsp.AdditionalDocNetDiskId = item.AdditionalDocNetDiskId + rsp.AdditionalDocName = item.AdditionalDocName + rsp.IsFirstSave = item.IsFirstSave + rsp.AdditionalDocContent = item.AdditionalDocContent + rsp.EffectiveTime = item.EffectiveTime + rsp.CreateTime = item.CreateTime + rsp.UpdateTime = item.UpdateTime + + return rsp, nil +} + +func (as *AppService) DelPrivacySettingInfo(ctx context.Context, appId string) error { + err := as.prviacySettingRepo.DelInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("PrviacySettingRepo DelInfoByAppId err:%s", err.Error()) + return err + } + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Errorf("as.appRepo.GetAppVerInfo err:%s", err.Error()) + return err + } + appInfo.PrivacySettingType = 1 + err = as.appRepo.UpdateApp(ctx, appInfo) + if err != nil { + log.Errorf("UpdateAppIsPrivacySetting repo err:%s", err.Error()) + return err + } + return nil +} + +type InternalGetPrivacySettingInfoRsp struct { + AppId string `json:"appId"` + AppName string `json:"appName"` + OrganName string `json:"organName"` + CommitType int `json:"commitType"` //提交类型 //1:本小程序开发者承诺并保证,未以任何方式处理用户的任何信息。如后续有处理用户信息,会及时更新《小程序隐私保护指引》 2:本小程序处理了用户信息,将如实填写并及时更新用户信息处理情况 + UserMessageType entity.UserMessageTypeObj `json:"userMessageType"` //用户使用类型 + SdkMessage []entity.SdkMessageInfoObj `json:"sdkMessage"` //sdk信息 + ContactInfo entity.ContactInfoObj `json:"contactInfo"` //联系方式 + FixedStorageTime int `json:"fixedStorageTime"` //固定存储时间 + IsShortestTime bool `json:"isShortestTime"` //是否是最短时间 + AdditionalDocName string `json:"additionalDocName"` //补充文档名称 + AdditionalDocNetDiskId string `json:"additionalDocNetDiskId"` //补充文档网盘id + AdditionalDocContent string `json:"additionalDocContent"` //补充文档内容 + IsFirstSave bool `json:"isFirstSave"` + EffectiveTime int64 `json:"effectiveTime"` + CreateTime int64 `json:"createTime"` + UpdateTime int64 `json:"updateTime"` +} + +func (as *AppService) InternalGetPrivacySettingInfo(ctx context.Context, appId string) (InternalGetPrivacySettingInfoRsp, error) { + rsp := InternalGetPrivacySettingInfoRsp{} + + /*appVerInfo, err := as.appRepo.GetOnlineAppVer(ctx, appId) + if err != nil { + log.Debugf("getApp GetOnlineAppVer err:%s", err.Error()) + if !NotFound(err) { + log.Errorf("getApp err:%s", err.Error()) + return rsp, err + } + }*/ + + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Debugf("getApp err:%s", err.Error()) + if !NotFound(err) { + log.Errorf("getApp err:%s", err.Error()) + return rsp, err + } + } + + groupInfo, err := hCaller.GetGroupInfoByGroupId(ctx, appInfo.GroupID) + log.Infof("get groupInfo error:%+v,groupInfo:%+v", err, groupInfo) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger group info err:%s", err.Error()) + return rsp, err + } + + item, err := as.prviacySettingRepo.GetInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("PrviacySettingRepo insert err:%s", err.Error()) + return rsp, err + } + rsp.AppName = appInfo.Name + rsp.OrganName = groupInfo.GroupName + rsp.AppId = item.AppId + rsp.FixedStorageTime = item.FixedStorageTime + rsp.IsShortestTime = item.IsShortestTime + var userMessageTypeObj entity.UserMessageTypeObj + json.Unmarshal([]byte(item.UserMessageType), &userMessageTypeObj) + rsp.UserMessageType = userMessageTypeObj + + var sdkMessage []entity.SdkMessageInfoObj + json.Unmarshal([]byte(item.SdkMessage), &sdkMessage) + rsp.SdkMessage = sdkMessage + rsp.CommitType = item.CommitType + rsp.AdditionalDocContent = item.AdditionalDocContent + rsp.ContactInfo.Phone = item.ContactInfoPhone + rsp.ContactInfo.Email = item.ContactInfoEmail + rsp.ContactInfo.WeChat = item.ContactInfoWeChat + rsp.ContactInfo.Other = item.ContactInfoOther + rsp.AdditionalDocNetDiskId = item.AdditionalDocNetDiskId + rsp.AdditionalDocName = item.AdditionalDocName + rsp.IsFirstSave = item.IsFirstSave + rsp.EffectiveTime = item.EffectiveTime + rsp.CreateTime = item.CreateTime + rsp.UpdateTime = item.UpdateTime + + return rsp, nil +} + +type InternalGetAppSearchDataInfoRsp struct { + AppId string `json:"appId"` //小程序Id + GroupID string `json:"groupId"` + Resource string `json:"resource"` //小程序源码地址 + AppName string `json:"appName"` //小程序名称 + OrganName string `json:"organName"` //机构名称 + AppDesc string `json:"appDesc"` //小程序简介 + SdkKeys []string `json:"sdkKeys"` //sdk关联列表 + AppTag string `json:"appTag"` + AppClass string `json:"appClass"` +} + +func (as *AppService) InternalGetAppSearchDataInfo(ctx context.Context, appId string) (InternalGetAppSearchDataInfoRsp, error) { + rsp := InternalGetAppSearchDataInfoRsp{} + + appInfo, err := as.appRepo.GetAppInfo(ctx, appId) + if err != nil { + log.Debugf("getApp GetAppInfo err:%s", err.Error()) + if !NotFound(err) { + log.Errorf("getApp err:%s", err.Error()) + return rsp, err + } + } + appVerInfo, err := as.appRepo.GetOnlineAppVer(ctx, appId) + if err != nil { + log.Debugf("getApp GetOnlineAppVer err:%s", err.Error()) + if !NotFound(err) { + log.Errorf("getApp err:%s", err.Error()) + return rsp, err + } + } + appTagInfo, err := hCaller.GetAppTagConfigInfo(ctx) + if err != nil { + log.Errorln("appTagInfo error:%s", err.Error()) + return rsp, err + } + //log.Debugln("appTagInfo:", appTagInfo.Data.AppTag) + appTagStr := "" + if len(appVerInfo.AppTag) > 0 { + log.Debugln("AppTag:", appVerInfo.AppTag) + for _, v := range appVerInfo.AppTag { + for _, tag := range appTagInfo.Data.AppTag { + if v == tag.Key { + appTagStr += tag.Name + "," + log.Debugln("appTagStr", appTagStr) + } + } + } + if len(appTagStr) > 0 { + appTagStr = appTagStr[0 : len(appTagStr)-1] + } + } + appClassStr := "" + if len(appVerInfo.AppTag) > 0 { + for _, v := range appTagInfo.Data.AppClass { + if v.Key == appVerInfo.AppClass { + appClassStr = v.Name + } + } + } + bindRepo := impl.InitBindingRepo() + result, err := bindRepo.GetAllAssBinds(ctx, appId) + if err != nil { + log.Errorf("notifySpiderPubApp err:%s", err.Error()) + return rsp, err + } + var sdkKeyListMap = make(map[string]bool, 0) + var sdkKeyList = make([]string, 0) + for _, v := range result { + for _, sdkKeyInfo := range v.BundleInfos { + if sdkKeyInfo.IsForbidden == 0 { + if _, ok := sdkKeyListMap[sdkKeyInfo.SDKKey]; !ok { + sdkKeyListMap[sdkKeyInfo.SDKKey] = true + } + } + } + } + for k, _ := range sdkKeyListMap { + sdkKeyList = append(sdkKeyList, k) + } + rsp.AppId = appInfo.AppID + rsp.GroupID = appVerInfo.GroupID + rsp.Resource = appVerInfo.CustomData.SourceFile[0].SourceFileUrl + rsp.AppName = appInfo.Name + rsp.AppDesc = appVerInfo.CoreDescription + rsp.AppTag = appTagStr + rsp.AppClass = appClassStr + rsp.SdkKeys = sdkKeyList + return rsp, nil +} + +type AppObject struct { + AppId string `json:"appId"` //小程序Id + AppName string `json:"appName"` //小程序名称 + Logo string `json:"logo"` +} +type InternalGetAppInfoBySearchTextRsp struct { + AppInfo []AppObject `json:"appInfo"` +} + +func (as *AppService) InternalGetAppInfoBySearchText(ctx context.Context, searchText string) (InternalGetAppInfoBySearchTextRsp, error) { + rsp := InternalGetAppInfoBySearchTextRsp{} + + result, err := as.appRepo.GetAppsBySearchText(ctx, searchText) + if err != nil { + log.Debugf("getApp GetAppsBySearchText err:%s", err.Error()) + return rsp, err + } + for _, v := range result { + item := AppObject{} + item.AppId = v.AppID + item.Logo = v.Logo + item.AppName = v.Name + rsp.AppInfo = append(rsp.AppInfo, item) + } + return rsp, nil +} + +func EncryptZip(src, dst, passwd string) error { + zipfile, err := os.Create(dst) + if err != nil { + return err + } + defer zipfile.Close() + archive := ezip.NewWriter(zipfile) + defer archive.Close() + err = filepath.Walk(src, func(path string, info os.FileInfo, err error) error { + if info.IsDir() { + return nil + } + if err != nil { + return err + } + header, err := ezip.FileInfoHeader(info) + if err != nil { + return err + } + header.Name = strings.TrimPrefix(path, filepath.Dir(src)+"/") + //if info.IsDir() { + // header.Name += "/" + //} else { + // header.Method = zip.Deflate + //} // 设置密码 + header.Method = zip.Deflate + header.SetPassword(passwd) + writer, err := archive.CreateHeader(header) + if err != nil { + return err + } + if !info.IsDir() { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + _, err = io.Copy(writer, file) + } + return err + }) + archive.Flush() + return err +} + +func Zip(pathToZip, destinationPath string) error { + destinationFile, err := os.Create(destinationPath) + if err != nil { + return err + } + myZip := zip.NewWriter(destinationFile) + err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, err error) error { + if info.IsDir() { + return nil + } + if err != nil { + return err + } + relPath := strings.TrimPrefix(filePath, filepath.Dir(pathToZip)) + zipFile, err := myZip.Create(relPath) + if err != nil { + return err + } + fsFile, err := os.Open(filePath) + if err != nil { + return err + } + _, err = io.Copy(zipFile, fsFile) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + err = myZip.Close() + if err != nil { + return err + } + return nil +} + +func ZipList(fileList []string, destinationPath string) error { + fmt.Println(fileList) + destinationFile, err := os.Create(destinationPath) + if err != nil { + return err + } + myZip := zip.NewWriter(destinationFile) + for _, fileName := range fileList { + f, err := os.Open(fileName) + if err != nil { + return err + } + fInfo, err := f.Stat() + if err != nil { + return err + } + if fInfo.IsDir() { + return fmt.Errorf("file:[%s] is dir", fileName) + } + _, name := filepath.Split(fileName) + zipFile, err := myZip.Create(name) + if err != nil { + return err + } + fsFile, err := os.Open(fileName) + if err != nil { + return err + } + _, err = io.Copy(zipFile, fsFile) + if err != nil { + return err + } + } + err = myZip.Close() + if err != nil { + return err + } + return nil +} + +func EncryptList(fileList []string, dst, passwd string) error { + fmt.Println(fileList) + zipfile, err := os.Create(dst) + if err != nil { + return err + } + defer zipfile.Close() + archive := ezip.NewWriter(zipfile) + defer archive.Close() + for _, fileName := range fileList { + fmt.Println("fileName:", fileName) + f, err := os.Open(fileName) + if err != nil { + return err + } + fInfo, err := f.Stat() + if err != nil { + return err + } + if fInfo.IsDir() { + return fmt.Errorf("file:[%s] is dir", fileName) + } + header, err := ezip.FileInfoHeader(fInfo) + if err != nil { + return err + } + _, name := filepath.Split(fileName) + header.Name = name + fmt.Println("header.Name:", header.Name) + header.Method = zip.Deflate + header.SetPassword(passwd) + writer, err := archive.CreateHeader(header) + if err != nil { + return err + } + file, err := os.Open(fileName) + if err != nil { + return err + } + _, err = io.Copy(writer, file) + file.Close() + } + archive.Flush() + return err +} + +func getFileId(fileUrl string) string { + tempList := strings.Split(fileUrl, "/") + return tempList[len(tempList)-1] +} diff --git a/domain/service/app_build_info.go b/domain/service/app_build_info.go new file mode 100644 index 0000000..1949339 --- /dev/null +++ b/domain/service/app_build_info.go @@ -0,0 +1,1222 @@ +package service + +import ( + "context" + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/cache/redis" + "finclip-app-manager/infrastructure/client/grpc" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +type AppAppletInfoService struct { + appBuildInfoRepo repository.IAppBuildInfoRepo + appRepo repository.AppRepository + tempAppRepo repository.IAppTempInfoRepo + qrcodeRepo repository.IQrCodeInfoRepo +} + +func NewAppAppletInfoService() *AppAppletInfoService { + return &AppAppletInfoService{ + appBuildInfoRepo: impl.InitBuildInfoRepo(), + appRepo: impl.InitAppRepo(), + tempAppRepo: impl.InitAppTempInfoRepo(), + qrcodeRepo: impl.InitQrCodeInfoRepo(), + } +} + +type GetPubVerListRspItem struct { + AppID string `json:"appId" bson:"appId"` + Name string `json:"name" bson:"name"` + Version string `json:"version" bson:"version"` + Sequence int `json:"sequence" bson:"sequence"` + AppBuildID string `json:"appBuildID" bson:"appBuildID"` + AppBuildInfoId string `json:"buildInfoId" bson:"buildInfoId"` + PathAndQuery string `json:"pathAndQuery" bson:"pathAndQuery"` + StartParams entity.AppStartParams `json:"startParams"` + WechatInfo WechatInfoRsp `json:"wechatInfo" bson:"wechatInfo"` +} +type WechatInfoRsp struct { + WechatAppSecret string `json:"wechatAppSecret" bson:"wechatAppSecret"` + WechatAppId string `json:"wechatAppId" bson:"wechatAppId"` + WechatPath string `json:"wechatPath" bson:"wechatPath"` + WechatSize string `json:"wechatSize" bson:"wechatSize"` + QrcodeUrl string `json:"qrcodeUrl" bson:"qrcodeUrl"` + QrcodeDownloadUrl string `json:"qrcodeDownloadUrl" bson:"qrcodeDownloadUrl"` + Updated int64 `json:"updated" bson:"updated"` + ShowHint bool `json:"showHint" bson:"-"` // 是否展示提示 +} + +func (as *AppAppletInfoService) GetAppBuilds(ctx context.Context, operatorID, appId string, pageSize, pageNo int) ([]entity.AppBuildInfo, int64, error) { + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, operatorID) + if err != nil { + return nil, 0, err + + } + total, res, err := as.appBuildInfoRepo.GetAppBuilds(ctx, groupInfo.GroupID, appId, pageSize, pageNo) + if err != nil { + log.Errorf("GetAppBuilds err:%s", err.Error()) + return nil, 0, err + } + return res, total, nil +} + +func (as *AppAppletInfoService) GetAppVerBuildInfos(c *gin.Context) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + appId := c.Query("appId") + + if appId == "" { + log.Errorf("appId is empty!!!") + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_LACK_OF_APPID, nil) + return + } + + app, err := as.appRepo.GetAppInfo(traceCtx, appId) + if err != nil { + if as.appBuildInfoRepo.NotFound(err) { + utility.MakeLocRsp(c, http.StatusNotFound, utility.FS_APP_ID_NOT_FOUND, nil) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil) + return + } + + //获取体验版信息 + trialResult, err := as.appBuildInfoRepo.GetTrialInfoByAppId(traceCtx, appId) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil) + return + } + log.Debugf("trialResult data:", trialResult) + //获取线上版信息 + //publishSvr := service.NewAppVerService() + publishedList, _, err := as.appRepo.GetAllPublishedVerList(traceCtx, appId) + //&& !avs.appVerT.NotFound() + if err != nil { + log.Errorf("GetAllPublishedVerList db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil) + return + } + var pubResult []GetPubVerListRspItem + for _, v := range publishedList { + pubItem := GetPubVerListRspItem{} + if len(v.AppBuildID) > 0 { + appInfo, err := as.appBuildInfoRepo.GetInfoById(traceCtx, v.AppBuildID) + if err != nil { + log.Errorf("GetInfoById err:%s", err.Error()) + return + } else { + pubItem.AppID = v.AppID + pubItem.AppBuildID = v.AppBuildID + //pubItem.AppBuildInfoId = appInfo.BuildInfoId + pubItem.AppBuildInfoId = appInfo.Id + pubItem.Sequence = v.Sequence + pubItem.Version = v.Version + pubItem.Name = v.Name + pubItem.PathAndQuery = appInfo.StartParams.PathAndQuery + } + wechatInfo, err := hCaller.GetWeChatInfo(traceCtx, v.AppID) + if err != nil { + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, nil) + return + } + + if wechatInfo.Updated == 0 { + wechatInfo.Updated = app.PublishedStatus.LastUpdated + } + info := WechatInfoRsp{} + + info.WechatAppSecret = wechatInfo.WechatAppSecret + info.WechatAppId = wechatInfo.WechatAppId + info.WechatPath = wechatInfo.WechatPath + info.QrcodeUrl = wechatInfo.QrcodeUrl + info.QrcodeDownloadUrl = wechatInfo.QrcodeDownloadUrl + info.Updated = wechatInfo.Updated + info.WechatSize = wechatInfo.WechatSize + + pubItem.WechatInfo = info + + pubResult = append(pubResult, pubItem) + } + } + log.Debugf("pubResult data:", pubResult) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{"trialVer": trialResult, "pubVer": pubResult}) +} + +func (as *AppAppletInfoService) UpdateTrialApp(ctx context.Context, userId, Id, Type, AppId string) error { + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("UpdateTrialApp get user info err:%s,useid:[%s]", err.Error(), userId) + return err + } + buildInfo, err := as.appBuildInfoRepo.GetInfoById(ctx, Id) + if err != nil { + log.Errorf("UpdateTrialApp get info err:%s", err.Error()) + return err + } + if groupInfo.GroupID != buildInfo.GroupID { + log.Errorf("UpdateTrialApp user group id not match info id,userId:[%s]", userId) + return err + } + err = as.UpdateTrial(ctx, Id, Type, AppId) + if err != nil { + log.Errorf("UpdateTrial error:", err.Error()) + return err + } + return nil +} + +func (as *AppAppletInfoService) UpdateTrial(ctx context.Context, infoId, opType, appId string) error { + + var err error + switch opType { + case "add": + nowTrailInfo, err := as.appBuildInfoRepo.GetTrialInfoByAppId(ctx, appId) + if err != nil { + if !repository.NotFound(err) { + log.Errorf("get now trial info err:%s", err.Error()) + return err + } + } else { + //todo 这里需确定是否需要删除缓存 + //avs.updateTrialInfoCache(ctx, "del", nowTrailInfo.Id) + //取消之前的 + err = as.appBuildInfoRepo.CancelTrial(ctx, nowTrailInfo.Id) + if err != nil { + log.Errorf("add trial before cancel trial err:%s", err.Error()) + return err + } + } + err = as.appBuildInfoRepo.AddTrial(ctx, infoId) + if err != nil { + log.Errorf("AppBuildService AddTrial err:%s", err.Error()) + return err + } + //添加二维码信息 + qrcodeInfo := &entity.QrCodeInfo{ + Type: entity.QrCodeTypeTrial, + Uuid: GenTrialQrCodeUuid(appId), + AppId: appId, + Sequence: 0, + ApiServer: config.Cfg.ApiServer, + CodeId: infoId, + StartParams: entity.AppStartParams{}, + CreateTime: utils.GetNowMs(), + } + err = as.qrcodeRepo.GenInfo(ctx, qrcodeInfo) + case "cancel": + //todo 这里需确定是否需要删除缓存 + //as.appBuildInfoRepo.UpdateTrialInfoCache(ctx, "del", infoId) + err = as.appBuildInfoRepo.CancelTrial(ctx, infoId) + } + if err != nil { + log.Errorf("AppBuildService AddTrial err:%s", err.Error()) + return err + } + + err = hCaller.TrialQrReset(ctx, infoId) + if err != nil { + //utility.MakeLocRsp(http.StatusInternalServerError, utility.FS_DB_ERR) + return err + } + return nil +} + +func (as *AppAppletInfoService) UpdateTrialAppPathAndQueryHand(ctx context.Context, userId, TraceId, PathAndQuery string) error { + + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("UpdateTrialAppPathHand GetAccountInfo err:%s,userId:[%s]", err.Error(), userId) + return err + } + trialInfo, err := as.appBuildInfoRepo.GetTrialInfoById(ctx, TraceId) + if err != nil { + if err.Error() == "not found" { + log.Errorf("UpdateTrialAppPathHand id not trial,TraceId:%+v", TraceId) + return err + } + log.Errorf("GetTrialInfoById err:%s", err.Error()) + return err + } + if groupInfo.GroupID != trialInfo.GroupID { + log.Errorf("req user info group id not match up info userId:%s", userId) + return err + } + /*params := trialInfo.StartParams + params.PathAndQuery = req.PathAndQuery*/ + params := entity.AppStartParams{} + params.PathAndQuery = PathAndQuery + + err = as.UpdateTrialAppStartParams(ctx, TraceId, params) + if err != nil { + log.Errorf("AppBuildService AddTrial err:%s", err.Error()) + return err + } + return nil +} + +func (as *AppAppletInfoService) UpdateTrialAppStartParams(ctx context.Context, infoId string, params entity.AppStartParams) error { + log.Debugf("UpdateTrialAppStartParams info id:[%s],params:%+v", infoId, params) + err := as.appBuildInfoRepo.UpdateTrialStartParams(ctx, infoId, params) + if err != nil { + log.Errorf("UpdateTrialAppPath db err:%s", err.Error()) + return err + } + qrcodeSvr := NewQrCodeInfoService() + err = qrcodeSvr.UpdateTrialStartParams(ctx, infoId, params) + if err != nil { + log.Errorf("UpdateTrialStartParams db err:%s", err.Error()) + return err + } + //err = NewRedDotService().TrialQrReset(ctx, infoId) + + err = hCaller.TrialQrReset(ctx, infoId) + if err != nil { + //utility.MakeLocRsp(http.StatusInternalServerError, utility.FS_DB_ERR) + return err + } + return nil +} + +type GetTrialAppInfoRsp struct { + Info interface{} `json:"info"` + QrcodeHasRead bool `json:"qrcodeHasRead"` +} + +func (as *AppAppletInfoService) GetTrialAppInfo(ctx context.Context, userId, appId string) (GetTrialAppInfoRsp, error) { + + rspData := GetTrialAppInfoRsp{} + + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, userId) + if err != nil { + log.Errorf("GetTrialAppInfo get user info err:%s,useid:[%s]", err.Error(), userId) + return rspData, err + } + buildInfo, err := as.appBuildInfoRepo.GetTrialInfoByAppId(ctx, appId) + if err != nil { + if err.Error() != "not found" { + log.Errorf("GetTrialAppInfo get info err:%s", err.Error()) + return rspData, err + } + return rspData, err + } + if groupInfo.GroupID != buildInfo.GroupID { + log.Errorf("GetTrialAppInfo user group id not match info id,userId:[%s]", userId) + return rspData, err + } + + qrcodeHasRead, err := hCaller.IsTrialHasRead(ctx, buildInfo.Id, userId) + if err != nil { + log.Errorf("TrialHasRead err:%s", err.Error()) + return rspData, err + } + rspData.Info = buildInfo + rspData.QrcodeHasRead = qrcodeHasRead + return rspData, nil +} + +func (as *AppAppletInfoService) GetInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + //先从缓存中取 + /*infoByte, err := avs.rc.GetBytes(ctx, "mop_app_manage_build_info_"+id) + if err == nil { + common.GLog.Debugf("GetInfoById from redis,id:%s", id) + rspInfo := new(model.AppBuild) + if err = json.Unmarshal(infoByte, &rspInfo); err == nil { + return rspInfo, err + } + }*/ + info, err := as.appBuildInfoRepo.GetInfoById(ctx, id) + if err != nil { + log.Errorf("GetInfoById err:%s", err.Error()) + if repository.NotFound(err) { + return nil, entity.ErrNotFound + } + return nil, err + } + //infoByte, _ = json.Marshal(info) + //avs.rc.Set(ctx, "mop_app_manage_build_info_"+id, string(infoByte), config.Cfg.RedisExpireTime) + return info, nil +} + +func (as *AppAppletInfoService) GetInfoByBuildInfoId(ctx context.Context, buildInfo string) (*entity.AppBuildInfo, error) { + info, err := as.appBuildInfoRepo.GetInfoByBuildInfoId(ctx, buildInfo) + if err != nil { + log.Errorf("GetInfoByBuildInfoId err:%s", err.Error()) + if repository.NotFound(err) { + return nil, entity.ErrNotFound + } + return nil, err + } + return info, nil +} + +func (as *AppAppletInfoService) GetManageAppList(ctx context.Context, userId, sdkKey, apiServer string) (interface{}, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + rspAppList := make([]apiproto.GetManageAppListRspDataItem, 0) + sdkInWhiteList := utils.InArry(sdkKey, config.WhiteSDKArry) + //白名单的特殊处理 + if sdkInWhiteList { + groups := make([]string, 0) + /*//获取用户id对应的所有机构Id + authInfo, err := hCaller.GetAuthByUserIdAndGroups(ctx, "getUserIdGroupsAndAuth", userId, []string{}) + if err != nil { + log.Errorf("GetManageAppList GetAuthByUserIdAndGroups err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if !authInfo.HasAuth {*/ + //是否为企业管理员 + groupMap := make(map[string]string) + adminInfo, err := hCaller.GetIsOrganCreator(ctx, userId) + if err != nil { + log.Errorf("GetManageAppList GetIsOrganAdmin err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if adminInfo.IsCreator { + groupMap[adminInfo.OrganId] = adminInfo.OrganId + } + /*//小程序创建者 + appByCreatorInfo, err := as.appRepo.GetAppByCreator(ctx, userId) + if err != nil { + log.Errorf("GetManageAppList GetIsOrganCreator err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if len(appByCreatorInfo) > 0 { + for _, v := range appByCreatorInfo { + groupMap[v.GroupID] = v.GroupID + } + }*/ + //获取用户id对应的所有机构Id + authInfo, err := hCaller.GetAuthByUserIdAndGroups(ctx, "getUserIdGroupsAndAuth", userId, []string{}) + if err != nil { + log.Errorf("GetManageAppList GetAuthByUserIdAndGroups err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if !authInfo.HasAuth && !adminInfo.IsCreator { + log.Errorf("GetAuthByUserIdAndGroups user id no auth,rsp:%+v,userId:%s", authInfo, userId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_MANAGE_APP_NO_AUTH) + } + //获取对应机构id下的所有小程序 + for id, v := range authInfo.AuthList { + if v.Dev || v.Trial { + groupMap[id] = id + } + } + + for _, v := range groupMap { + groups = append(groups, v) + } + + total, appVers, err := as.appRepo.GetAppsByGroupIds(ctx, groups) + if err != nil { + log.Errorf("GetManageAppList get app ver err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + for _, info := range appVers { + item := apiproto.GetManageAppListRspDataItem{AppId: info.AppID, Name: info.Name, Logo: info.Logo} + rspAppList = append(rspAppList, item) + } + return gin.H{"total": total, "appList": rspAppList, "apiServer": apiServer}, rsp.SetLoc(http.StatusOK, utility.OK) + } + + //首先获取sdkKey关联的所有小程序 + bindInfoList, err := impl.InitBindingRepo().GetBindListBySdkKey(ctx, sdkKey) + if err != nil { + log.Errorf("GetManageAppList GetBindListBySdkKey err:%s", err.Error()) + if !impl.InitBindingRepo().NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } else { + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_NOT_FOUND) + } + } + appIdList := make([]string, 0) + groups := make([]string, 0) + for _, v := range bindInfoList { + groups = append(groups, v.GroupID) + } + appIdMap := make(map[string]string) + //userId为企业管理员 + adminInfo, err := hCaller.GetIsOrganCreator(ctx, userId) + if err != nil { + log.Errorf("GetManageAppList GetIsOrganAdmin err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if adminInfo.IsCreator { + for _, v := range bindInfoList { + if v.GroupID == adminInfo.OrganId { + for _, appInfo := range v.AppInfos { + //appIdList = append(appIdList, appInfo.AppID) + appIdMap[appInfo.AppID] = appInfo.AppID + } + } + } + } + //判断这些企业下面有没有这个userId + authInfo, err := hCaller.GetAuthByUserIdAndGroups(ctx, "getUserInGroupsAuth", userId, groups) + if err != nil { + log.Errorf("GetManageAppList GetAuthByUserIdAndGroups err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + fmt.Println("authInfo", utility.InterfaceToJsonString(authInfo)) + + if !authInfo.HasAuth && !adminInfo.IsCreator { + log.Errorf("GetAuthByUserIdAndGroups user id no auth,rsp:%+v,userId:%s", authInfo, userId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_MANAGE_APP_NO_AUTH) + } + for _, v := range bindInfoList { + if info, ok := authInfo.AuthList[v.GroupID]; ok { + if info.Dev || info.Trial { + for _, appInfo := range v.AppInfos { + appIdMap[appInfo.AppID] = appInfo.AppID + } + } + } + } + for _, v := range appIdMap { + appIdList = append(appIdList, v) + } + //获取所有的小程序详情 + appVers, err := as.appRepo.GetAppsByAppIds(ctx, appIdList) + for _, info := range appVers { + item := apiproto.GetManageAppListRspDataItem{AppId: info.AppID, Name: info.Name, Logo: info.Logo} + rspAppList = append(rspAppList, item) + } + return gin.H{"total": len(appIdList), "appList": rspAppList, "apiServer": apiServer}, rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppAppletInfoService) GetManageAppVerList(ctx context.Context, t, appId, apiServer string) (*apiproto.GetManageAppVerListRspData, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + rspData := apiproto.GetManageAppVerListRspData{} + //todo 结果不是数组,只有一个 + releaseInfo, err := as.appRepo.GetOnlineAppVer(ctx, appId) + if err != nil { + if !repository.NotFound(err) { + log.Errorf("GetManageAppVerList GetPubVerInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + rspData.ReleaseInfo = nil + } else { + rspData.ReleaseInfo = &apiproto.ManageReleaseInfo{ + AppId: releaseInfo.AppID, + Version: releaseInfo.Version, + VersionDescription: releaseInfo.CustomData.VersionDescription, + CreateBy: releaseInfo.CustomData.Developer, + CreateAt: releaseInfo.Created, + } + if len(releaseInfo.CustomData.SourceFile) > 0 { + rspData.ReleaseInfo.CreateAt = releaseInfo.CustomData.SourceFile[0].UploadDate + } + } + trialInfo, err := as.appBuildInfoRepo.GetTrialInfoByAppId(ctx, appId) + if err != nil { + log.Errorf("GetManageAppVerList GetTrialInfoByAppId err:%s", err.Error()) + if !repository.NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + } else { + rspData.TrialInfo = &apiproto.ManageTrialInfo{ + CodeId: trialInfo.Id, + Version: trialInfo.Version, + VersionDescription: trialInfo.CustomData.VersionDescription, + CreateBy: trialInfo.CreatedBy, + CreateAt: trialInfo.Created, + QrcodeSign: as.getQrCodeSign(entity.BuildInfoTypeTrial, trialInfo.Id, apiServer), + } + } + rspData.DevInfo = &apiproto.ManageDevInfo{Total: 0, List: make([]apiproto.ManageDevInfoItem, 0)} + if t == "dev" { + total, devList, err := as.appBuildInfoRepo.GetList(ctx, appId, 1, config.Cfg.ManageAppDevCount) + if err != nil { + log.Errorf("GetManageAppVerList GetList err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + rspData.DevInfo.Total = int(total) + for _, v := range devList { + if v.Status { + rspData.DevInfo.List = append(rspData.DevInfo.List, apiproto.ManageDevInfoItem{ + CodeId: v.Id, + Version: v.Version, + VersionDescription: v.CustomData.VersionDescription, + CreateBy: v.CreatedBy, + CreateAt: v.Created, + QrcodeSign: as.getQrCodeSign(entity.BuildInfoTypeDevelopment, v.Id, apiServer), + }) + } + } + } + rspData.ApiServer = apiServer + log.Infof("GetManageAppVerList rsp:%+v", rspData) + return &rspData, rsp.SetLoc(http.StatusOK, utility.OK) +} + +func (as *AppAppletInfoService) FixDevListStatus(ctx context.Context) *utility.SvrRsp { + rsp := utility.DefaultSvrRsp() + + result, err := as.appBuildInfoRepo.GetAll(ctx) + if err != nil { + log.Errorf("FixDevListStatus GetAll err:%s", err.Error()) + return rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + log.Infof("FixDevListStatus total:%v", len(result)) + type TempBuildInfo struct { + Id string `bson:"id"` + Status bool `bson:"status"` + } + var succTotal = 0 + //todo 获取编译服务appletbuilds表数据 + + /*for _, v := range result { + info := TempBuildInfo{} + err = buildT.GetOneV2(traceCtx, bson.M{"id": v.BuildInfoId}, &info) + if err != nil { + log.Errorf("buildT GetOneV2 err:%s", err.Error()) + } else { + err = t.UpdateOne(traceCtx, bson.M{"id": v.Id}, bson.M{"$set": bson.M{"status": info.Status}}) + if err != nil { + log.Errorf("UpdateOne err:%s", err.Error()) + } else { + succTotal += 1 + } + } + log.Infof("update info:%+v,info:%+v", v, info) + //break + }*/ + + for _, v := range result { + result, err := hCaller.GetAppletInfoById(ctx, v.BuildInfoId) + if err != nil { + log.Errorf("buildT GetOneV2 err:%s", err.Error()) + } else { + err = as.appBuildInfoRepo.UpdateOneStatus(ctx, v.Id, result.Status) + if err != nil { + log.Errorf("UpdateOne err:%s", err.Error()) + } else { + succTotal += 1 + } + } + log.Infof("update info:%+v,info:%+v", v, result) + + } + + log.Infof("FixDevListStatus total:%d,success total:%d", len(result), succTotal) + return rsp.SetLoc(http.StatusOK, utility.OK) + +} + +/*func (as *AppAppletInfoService) GetBuildInfo(ctx context.Context, req apiproto.GetBuildAppInfoReq, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + switch req.Type { + case entity.BuildInfoTypeTrial: //获取体验版小程序详情 + return as.GetTrialInfo(ctx, req.CodeId, sdkKey) + case entity.BuildInfoTypeTemporary: //获取ide临时小程序详情 + return as.getTempAppInfo(ctx, req.CodeId) + case entity.BuildInfoTypeDevelopment: + return as.GetDevInfo(ctx, req.CodeId, sdkKey) + default: + return nil, utility.DefaultSvrRsp().SetLoc(http.StatusBadRequest, utility.FS_PARAM_ERR) + } +}*/ + +func (as *AppAppletInfoService) DevGetTrialInfo(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + info, err := as.appBuildInfoRepo.GetTrialInfoByAppId(ctx, appId) + if as.appBuildInfoRepo.NotFound(err) { + log.Debugln("DevGetTrialInfo not found !") + return info, entity.NotFoundErr + } + return info, err +} + +func (as *AppAppletInfoService) GetTrialInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + + buildInfo := new(pb.BuildAppInfo) + rsp := utility.DefaultSvrRsp() + + /*buildInfoCacheByte, err := avs.rc.GetBytes(ctx, avs.getTrialInfoCacheKey(codeId)) + if err == nil { + if err = json.Unmarshal(buildInfoCacheByte, buildInfo); err == nil { + log.Infof("GetTrialInfo from cache ...") + return buildInfo, nil + } + }*/ + + info, err := as.appBuildInfoRepo.GetInfoById(ctx, codeId) + if err != nil { + log.Errorf("GetTrialInfo get info err:%s", err.Error()) + if as.appBuildInfoRepo.NotFound(err) { + return buildInfo, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + if info.Source != entity.APP_BUILD_SOURCE_TRIAL { + log.Infoln("GetTrialInfo id is not a trial info:[%s]", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_NOT_TRIAL_INFO) + } + + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, info.AppID, 0) + if err != nil { + log.Errorf("GetTrialInfo GetAppVerInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, appVerInfo.GroupID) + if err != nil { + log.Errorf("GetTrialInfo GetGroupInfoByUserId err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + // 获取开发者信息 + //developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID) + //if err != nil { + // log.Errorf("GetDeveloperInfo err:%s", err.Error()) + // return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR) + //} + //status := avs.account.getAccountStatus(groupInfo, developerInfo) + + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetTrialInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + + domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, groupInfo.GroupID) + if err != nil { + log.Errorf("GetTrialInfo ger domain info err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //支付信息过期校验 + if config.Cfg.OpenPurchAuth && config.Cfg.PublishEnv == config.ENV_UAT { + appStatus, err := as.CheckIdStatus(ctx, appVerInfo.AppID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appVerInfo.AppID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("check appid purch status no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + log.Debugf("get group id:%s,sdkKey:%s", appVerInfo.GroupID, sdkKey) + inWhiteList := utils.InArry(sdkKey, config.WhiteSDKArry) + if !inWhiteList { + repo := impl.InitBindingRepo() + bindingInfo, err := repo.GetInfoBySdkKeyOrganId(ctx, appVerInfo.GroupID, sdkKey) + if err != nil { + log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error()) + if repo.NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindingInfo.CooperateStatus.Value != entity.StBindValid { + log.Errorf("GetTrialInfo binding bind invalid,binding info:%+v", bindingInfo) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + //支付信息校验 + if config.Cfg.OpenPurchAuth && config.Cfg.PublishEnv == config.ENV_UAT { + bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("binding id pay check no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE) + } + } + appAssBind := false + for _, v := range bindingInfo.AppInfos { + if v.AppID == appVerInfo.AppID { + appAssBind = true + } + } + if !appAssBind { + log.Errorf("GetTrialInfo sdk key not ass binding,appId:[%s]", appVerInfo.AppID) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + + buildInfo.CodeId = info.Id + buildInfo.CoreDescription = appVerInfo.CoreDescription + buildInfo.Created = info.Created + buildInfo.CreatedBy = info.CreatedBy + err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, appVerInfo.CustomData, domainInfo, "cache") + if err != nil { + log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + buildInfo.CustomData = customData + buildInfo.GroupId = info.GroupID + buildInfo.GroupName = groupInfo.GroupName + buildInfo.Logo = appVerInfo.Logo + buildInfo.Name = appVerInfo.Name + buildInfo.Version = appVerInfo.Version + buildInfo.IsTemp = false + buildInfo.NeedCrt = domainInfo.NeedCrt + buildInfo.AppId = info.AppID + accountService := NewAccountInfoService() + buildInfo.DeveloperStatus = int32(accountService.getAccountStatus(groupInfo)) + //buildInfoCacheByte, _ := json.Marshal(buildInfo) + + //avs.rc.Set(ctx, avs.getTrialInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime) + return buildInfo, rsp +} + +func (as *AppAppletInfoService) getTempAppInfo(ctx context.Context, codeId string) (*pb.BuildAppInfo, *utility.SvrRsp) { + //todo 获取临时小程序数据 + //tempRspInfo, err := as.appRepo.getTempAppInfo(ctx, codeId, 1) + + /*rsp := utility.DefaultSvrRsp() + tempRspInfo, err := as.appRepo.getTempAppInfo(ctx, codeId, 1) + common.GLog.Infof("getTempAppInfo rsp:%+v,err:%+v", tempRspInfo, err) + if err != nil { + common.GLog.Errorf("getTempAppInfo err:%s", err.Error()) + return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR) + } + buildInfo := new(pb.BuildAppInfo) + buildInfo.CodeId = codeId + buildInfo.CoreDescription = tempRspInfo.CoreDescription + buildInfo.Created = tempRspInfo.Created + buildInfo.CreatedBy = tempRspInfo.CreatedBy + buildInfo.CustomData = ConvertRpcCustomDataToPb(tempRspInfo.CustomData) + buildInfo.CustomData.AppRuntimeDomain = new(pb.AppRuntimeDomain) + buildInfo.GroupId = tempRspInfo.GroupID + buildInfo.GroupName = tempRspInfo.GroupName + buildInfo.Logo = tempRspInfo.Logo + buildInfo.Name = tempRspInfo.Name + buildInfo.Version = tempRspInfo.Version + buildInfo.IsTemp = true + buildInfo.NeedCrt = tempRspInfo.NeedCrt + buildInfo.AppId = tempRspInfo.AppID + + return buildInfo, rsp.SetLoc(gin.H{}, http.StatusOK, common.OK)*/ + return nil, nil +} + +func (as *AppAppletInfoService) GetDevInfo(ctx context.Context, codeId, sdkKey string) (*pb.BuildAppInfo, *utility.SvrRsp) { + rsp := utility.DefaultSvrRsp() + buildInfo := new(pb.BuildAppInfo) + + /*buildInfoCacheByte, err := avs.rc.GetBytes(ctx, avs.getDevInfoCacheKey(codeId)) + if err == nil { + if err = json.Unmarshal(buildInfoCacheByte, buildInfo); err == nil { + log.Infof("GetDevInfo from cache ...") + return buildInfo, rsp.SetLoc(gin.H{}, http.StatusOK, common.OK) + } + }*/ + + info, err := as.appBuildInfoRepo.GetInfoById(ctx, codeId) + if err != nil { + log.Errorf("GetDevInfo get info err:%s", err.Error()) + if as.appBuildInfoRepo.NotFound(err) { + return nil, rsp.SetLoc(http.StatusNotFound, utility.FS_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + + appVerInfo, err := as.appRepo.GetAppVerInfo(ctx, info.AppID, 0) + if err != nil { + log.Errorf("GetDevInfo GetAppVerInfo err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_DB_ERR) + } + groupInfo, err := hCaller.GetGroupInfoByUserId(ctx, appVerInfo.GroupID) + if err != nil { + log.Errorf("GetDevInfo GetGroupInfoByUserId err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + //// 获取开发者信息 + //developerInfo, err := client.GetDeveloperInfo(ctx, appVerInfo.DeveloperID) + //if err != nil { + // log.Errorf("GetDeveloperInfo err:%s", err.Error()) + // return nil, rsp.SetLoc(gin.H{}, http.StatusInternalServerError, common.FS_SERVER_ERR) + //} + //status := avs.account.getAccountStatus(groupInfo, developerInfo) + if config.Cfg.IsUatEnv() { + if !hCaller.UatOrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } else { + if !hCaller.OrganStatusIsValid(groupInfo.ReviewStatus) { + log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_ORGAN_STATUS_INVALID) + } + } + //if !client.OrganStatusIsValid(groupInfo.ReviewStatus) { + // log.Errorf("GetDevInfo get info organ info invalid,code id:%s", codeId) + // return nil, rsp.SetLoc(gin.H{}, http.StatusForbidden, common.FS_ORGAN_STATUS_INVALID) + //} + //支付信息过期校验 + if config.Cfg.OpenPurchAuth && config.Cfg.PublishEnv == config.ENV_UAT { + appStatus, err := as.CheckIdStatus(ctx, appVerInfo.AppID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,appId:%s", err.Error(), appVerInfo.AppID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if appStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("check appid purch status no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_PAY_EXPIRE) + } + } + domainInfo, err := hCaller.GetAppDomainByOrganId(ctx, appVerInfo.GroupID) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + + log.Debugf("get group id:%s,sdkKey:%s", appVerInfo.GroupID, sdkKey) + inWhiteList := utils.InArry(sdkKey, config.WhiteSDKArry) + if !inWhiteList { + repo := impl.InitBindingRepo() + bindingInfo, err := repo.GetInfoBySdkKeyOrganId(ctx, appVerInfo.GroupID, sdkKey) + if err != nil { + log.Errorf("GetInfoBySdkKeyOrganId err:%s", err.Error()) + if repo.NotFound(err) { + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_BIND_NOT_FOUND) + } + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindingInfo.CooperateStatus.Value != entity.StBindValid { + log.Errorf("GetDevInfo binding bind invalid,binding info:%+v", bindingInfo) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_COOPERATION_TERMINATED) + } + //支付信息校验 + if config.Cfg.OpenPurchAuth && config.Cfg.PublishEnv == entity.ENV_UAT { + bindStatus, err := as.CheckIdStatus(ctx, bindingInfo.BindingID) + if err != nil { + log.Errorf("CheckIdStatus err:%s,bindingId:%s", err.Error(), bindingInfo.BindingID) + return nil, rsp.SetLoc(http.StatusInternalServerError, utility.FS_SERVER_ERR) + } + if bindStatus == httpcall.PAY_ID_STATUS_EXPIRE { + log.Errorf("binding id pay check no ok ") + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_BIND_PAY_EXPIRE) + } + } + appAssBind := false + for _, v := range bindingInfo.AppInfos { + if v.AppID == appVerInfo.AppID { + appAssBind = true + } + } + if !appAssBind { + log.Errorf("GetDevInfo sdk key not ass binding,appId:[%s]", appVerInfo.AppID) + return nil, rsp.SetLoc(http.StatusForbidden, utility.FS_APP_NOT_ASS_BIND) + } + } + + buildInfo.CodeId = info.Id + buildInfo.CoreDescription = appVerInfo.CoreDescription + buildInfo.Created = info.Created + buildInfo.CreatedBy = info.CreatedBy + err, errCode, customData := ConvertModelCustomDataToPb(ctx, info.GroupID, appVerInfo.CustomData, domainInfo, "cache") + if err != nil { + log.Errorf("ConvertModelCustomDataToPb err:%s", err.Error()) + return nil, rsp.SetLoc(http.StatusInternalServerError, errCode) + } + buildInfo.CustomData = customData + buildInfo.GroupId = info.GroupID + buildInfo.GroupName = groupInfo.GroupName + buildInfo.Logo = appVerInfo.Logo + buildInfo.Name = appVerInfo.Name + buildInfo.Version = info.Version + buildInfo.AppId = info.AppID + buildInfo.IsTemp = false + buildInfo.NeedCrt = domainInfo.NeedCrt + accountService := NewAccountInfoService() + + buildInfo.DeveloperStatus = int32(accountService.getAccountStatus(groupInfo)) + + //buildInfoCacheByte, _ = json.Marshal(buildInfo) + //avs.rc.Set(ctx, avs.getDevInfoCacheKey(codeId), string(buildInfoCacheByte), config.Cfg.RedisTrialExpireTime) + + return buildInfo, rsp +} + +func (as *AppAppletInfoService) GetTrialInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + return as.appBuildInfoRepo.GetTrialInfoByAppId(ctx, appId) +} + +func (as *AppAppletInfoService) GetLatestInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + return as.appBuildInfoRepo.GetLatestInfoByAppId(ctx, appId) +} + +func (as *AppAppletInfoService) CheckIdStatus(ctx context.Context, id string) (int, error) { + return httpcall.PAY_ID_STATUS_USING, nil + /*switch config.Cfg.ReqType { + case "grpc": + return grpc.PurchasingGetIdStatus(ctx, id) + default: + status, _, err := hCaller.PayCheckIdStatus(ctx, id) + return status, err + }*/ +} + +type MenuInfoFetcher interface { + GetMenuRspInfo(ctx context.Context) (*proto.MenuInfoRspData, error) +} + +func ConvertModelCustomDataToPb( + ctx context.Context, + //rs MenuInfoFetcher, + groupId string, + data entity.CustomDataInfo, + domainInfo *httpcall.DomainResponseData, + sdkVer string, +) (error, string, *pb.CustomData) { + var err error + if domainInfo == nil { + domainInfo, err = hCaller.GetDomainInfoByOrganId(ctx, groupId) + if err != nil { + log.Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) + return err, utility.FS_GET_DOMAIN_INFO_ERROR, nil + } + } + + menuRsp, err := GetMenuRspInfo(ctx) + if err != nil { + log.Errorf("GetDevInfo GetMenuRspInfo err:%+v", err) + return err, utility.FS_SERVER_ERR, nil + } + + apiData, err := hCaller.GetApiList(ctx, groupId) + if err != nil { + log.Errorf("get api list err:%s", err.Error()) + return err, utility.FS_SERVER_ERR, nil + } + res := new(pb.CustomData) + res.ApiInfo = nil + if apiData != nil { + res.ApiInfo = make([]*pb.ApiInfoRspData, 0) + for _, v := range apiData { + res.ApiInfo = append(res.ApiInfo, &pb.ApiInfoRspData{Url: v.Url, ApiName: v.ApiName}) + } + } + if menuRsp != nil { + res.MenuInfo = new(pb.MenuInfoRspData) + res.MenuInfo.Total = int32(menuRsp.Total) + res.MenuInfo.List = make([]*pb.MenuInfoRspDataItem, 0) + for _, v := range menuRsp.List { + res.MenuInfo.List = append(res.MenuInfo.List, &pb.MenuInfoRspDataItem{Name: v.Name, Id: v.ID, Image: v.Image}) + } + } + + res.DetailDescription = data.DetailDescription + res.VersionDescription = data.VersionDescription + res.SourceFile = make([]*pb.SourceFileData, 0) + for _, v := range data.SourceFile { + item := &pb.SourceFileData{ + FileMd5: v.FileMd5, + Name: v.Name, + UploadDate: v.UploadDate, + Url: v.Url, + SourceFileUrl: "", + BasicPackVer: v.BasicPackVer, + } + if sdkVer != "" { + isEncry := false + if sdkVer == "cache" { + isEncry = true + } else { + isEncry, err = GetSdkVerEncryResult(ctx, sdkVer) + if err != nil { + return err, utility.FS_SERVER_ERR, nil + } + } + if isEncry && v.EncryptedUrl != "" { // && v.EncryptedFileMd5 != "" { + item.Url = v.EncryptedUrl + item.FileMd5 = v.EncryptedFileMd5 + } + } + for _, val := range v.EncryptPackages { + item.Packages = append(item.Packages, &pb.Package{ + Root: val.Root, + Name: val.Name, + Pages: val.Pages, + Independent: val.Independent, + Filename: val.Filename, + FileUrl: val.FileUrl, + FileMd5: val.FileMd5, + }) + } + res.SourceFile = append(res.SourceFile, item) + } + res.AppRuntimeDomain = GetPbRuntimeDomains(domainInfo) + return nil, "", res +} + +func GetSdkVerEncryResult(ctx context.Context, sdkVer string) (bool, error) { + var isEncry bool + var err error + /*isEncry, ok := cache.GetSdkVerResult(ctx, sdkVer) + if ok { + return isEncry, nil + }*/ + switch config.Cfg.ReqType { + case "grpc": + isEncry, err = grpc.GetSdkVerEncrypted(ctx, sdkVer) + default: + isEncry, err = httpcall.NewClient().GetSdkVerIsEncrypted(ctx, sdkVer) + } + if err != nil { + return false, err + } + //cache.SetSdkVerResult(ctx, sdkVer, isEncry) + return isEncry, nil +} +func GetPbRuntimeDomains(domainInfo *httpcall.DomainResponseData) *pb.AppRuntimeDomain { + result := &pb.AppRuntimeDomain{} + result.Business = &pb.AppRuntimeDomain_Business{Domains: make([]string, 0)} + if domainInfo.Business.Domains != nil { + result.Business.Domains = domainInfo.Business.Domains + } + result.Service = &pb.AppRuntimeDomain_Service{ + Download: make([]string, 0), + Request: make([]string, 0), + Socket: make([]string, 0), + Upload: make([]string, 0), + } + if domainInfo.Service.Download != nil { + result.Service.Download = domainInfo.Service.Download + } + if domainInfo.Service.Request != nil { + result.Service.Request = domainInfo.Service.Request + } + if domainInfo.Service.Socket != nil { + result.Service.Socket = domainInfo.Service.Socket + } + if domainInfo.Service.Download != nil { + result.Service.Upload = domainInfo.Service.Upload + } + + result.Whitelist = &pb.AppRuntimeDomain_Whitelist{Domains: make([]string, 0)} + if domainInfo.Whitelist.Domains != nil { + result.Whitelist.Domains = domainInfo.Whitelist.Domains + } + result.Blacklist = &pb.AppRuntimeDomain_Blacklist{Domains: make([]string, 0)} + if domainInfo.Blacklist.Domains != nil { + result.Blacklist.Domains = domainInfo.Blacklist.Domains + } + return result +} +func GetMenuRspInfo(ctx context.Context) (*proto.MenuInfoRspData, error) { + //非私有化环境置为nil + if !config.Cfg.IsPrivateEnv() { + return nil, nil + } + menuCreated, err := MenuHasCreated(ctx) + if err != nil { + return nil, err + } + if !menuCreated { + return nil, nil + } + result := new(proto.MenuInfoRspData) + result.List = make([]proto.MenuInfoRspDataItem, 0) + /*cacheRsp, err := rs.menuCache.Get(ctx) + if err == nil { + result.Total = cacheRsp.Total + for _, m := range cacheRsp.List { + item := proto.MenuInfoRspDataItem{} + item.ID = m.ID + item.Name = m.Name + item.Image = m.Image + result.List = append(result.List, item) + } + return result, nil + }*/ + + menuCacheInfo := apiproto.GetAllMenuRsp{} + + repoRspList, total, err := impl.InitMenuInfoRepo().GetAllMenuList(ctx, []string{"sortNum"}) + if err != nil { + return nil, err + } + result.Total = total + menuCacheInfo.Total = total + for _, m := range repoRspList { + item := proto.MenuInfoRspDataItem{} + item.ID = m.InfoId + item.Name = m.Name + item.Image = m.ImageUrl + result.List = append(result.List, item) + + cacheItem := apiproto.GetAllMenuRspItem{ + TraceId: m.TraceId, + Name: m.Name, + ID: m.InfoId, + Image: m.ImageUrl, + SortNum: m.SortNum, + CreateTime: m.CreateTime, + UpdateTime: m.UpdateTime, + UpdateOperator: m.UpdateOperator, + } + menuCacheInfo.List = append(menuCacheInfo.List, cacheItem) + } + + return result, nil +} + +type EncryptInfo struct { + ApiServer string `json:"apiServer"` + CodeId string `json:"codeId"` + Type string `json:"type"` + Uuid string `json:"uuid"` +} + +func (as *AppAppletInfoService) getQrCodeSign(t, codeId, apiServer string) string { + s, _ := json.Marshal(EncryptInfo{ApiServer: apiServer, Type: t, CodeId: codeId, Uuid: uuid.NewV4().String()}) + return utils.EncodeAESContent(string(s)) +} + +func MenuHasCreated(ctx context.Context) (bool, error) { + //先从redis中取 + val, err := redis.RedisGet(ctx, utility.MenuCreatedKey) + fmt.Println("get string val:", val, ",err:", err) + if err == nil { + return true, nil + } + if !redis.RedisNotFound(err) { + return false, err + } + menuCount, err := impl.InitMenuInfoRepo().AllCount(ctx) + if err != nil { + return false, err + } + if menuCount > 0 { + redis.RedisSet(ctx, utility.MenuCreatedKey, utility.MenuCreatedValue, 0) + return true, nil + } + return false, nil +} + +func ConvertWechatLoginInfoToPb(info *proto.WechatLoginInfo) *pb.WechatLoginInfo { + rsp := new(pb.WechatLoginInfo) + rsp.WechatOriginId = info.WechatOriginId + rsp.ProfileUrl = info.ProfileUrl + rsp.PhoneUrl = info.PhoneUrl + rsp.PaymentUrl = info.PaymentUrl + for _, v := range info.ExtUrls { + ext := pb.ExtUrls{ + FieldName: v.FieldName, + PageUrl: v.PageUrl, + } + rsp.ExtUrls = append(rsp.ExtUrls, &ext) + } + return rsp +} diff --git a/domain/service/app_config.go b/domain/service/app_config.go new file mode 100644 index 0000000..09bf43d --- /dev/null +++ b/domain/service/app_config.go @@ -0,0 +1,79 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/repository" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/utility" + "net/http" + "time" +) + +type AppConfigService struct { + AppOperConfigRepo repository.IAppOperConfigRepo +} + +func NewAppConfigService() *AppConfigService { + return &AppConfigService{ + AppOperConfigRepo: impl.InitAppOperConfigRepo(), + } +} + +type GetOperConfigRsp struct { + AutoReviewApp int `json:"autoReviewApp"` +} + +func (a *AppConfigService) GetOperConfig(ctx context.Context) (GetOperConfigRsp, string) { + item, err := a.AppOperConfigRepo.Find(ctx) + //没有不需要返回错误 + if err != nil { + log.Errorln("a.AppOperConfigRepo.Find err:%s", err.Error()) + } + + var result GetOperConfigRsp + result.AutoReviewApp = item.AutoReviewApp + + return result, utility.OK +} + +type UpdateAppOperCofigReq struct { + AutoReviewApp int `json:"autoReviewApp"` +} + +func (a *AppConfigService) UpdateAppOperCofig(ctx context.Context, req UpdateAppOperCofigReq) (string, int) { + if req.AutoReviewApp != 0 && req.AutoReviewApp != 1 { + log.Errorln("param err") + return utility.FS_PARAM_ERR, http.StatusBadRequest + } + + log.Debugf("UpdateAppOperCofig:%s\n", utility.InterfaceToJsonString(req)) + + item, err := a.AppOperConfigRepo.Find(ctx) + + found := true + if repository.NotFound(err) { + item.CreateTime = time.Now().UnixNano() / 1e6 + item.UpdateTime = item.CreateTime + found = false + } else { + item.UpdateTime = time.Now().UnixNano() / 1e6 + log.Debugf("UpdateAppOperCofig found\n") + } + item.AutoReviewApp = req.AutoReviewApp + + if found { + err = a.AppOperConfigRepo.Update(ctx, item) + if err != nil { + log.Errorln("a.AppOperConfigRepo.Update err:%s", err.Error()) + return utility.FS_DB_ERR, http.StatusBadRequest + } + } else { + err = a.AppOperConfigRepo.Insert(ctx, item) + if err != nil { + log.Errorln("a.AppOperConfigRepo.Insert err:%s", err.Error()) + return utility.FS_DB_ERR, http.StatusBadRequest + } + } + + return utility.OK, http.StatusOK +} diff --git a/domain/service/app_temp_info.go b/domain/service/app_temp_info.go new file mode 100644 index 0000000..fdb6026 --- /dev/null +++ b/domain/service/app_temp_info.go @@ -0,0 +1,146 @@ +package service + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "net/http" + + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend/apm" + "gopkg.in/mgo.v2/bson" +) + +type AppTempInfoService struct { +} + +func NewAppTempInfoService() *AppTempInfoService { + var s AppTempInfoService + return &s +} + +func (s AppTempInfoService) UpdateTempApp(c *gin.Context, appId string, req *proto.UpdateTempAppInfoReq) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + + var ( + rspData = make(map[string]interface{}) + ) + + repo := impl.InitAppTempInfoRepo() + appTempInfo, err := repo.GetInfoByAppId(traceCtx, appId) + if err != nil { + log.Errorf("GetInfoByAppIdAndSeq err:%s", err.Error()) + if repo.NotFound(err) { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_APP_SEQUENCE_NOT_FOUND, rspData) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData) + return + } + + if appTempInfo.CustomData.SourceFile == nil { + appTempInfo.CustomData.SourceFile = make([]entity.CustomDataSourceFile, 0) + } + appTempInfo.Name = req.AppName + appTempInfo.Logo = req.AppLogo + sourceFileInfo := entity.CustomDataSourceFile{ + FileMd5: req.FileMd5, + Name: req.Name, + SourceFileUrl: req.SourceFileUrl, + UploadDate: req.UploadDate, + Url: req.Url, + EncryptedUrl: req.EncryptedUrl, + EncryptedFileMd5: req.EncryptedFileMd5, + Packages: convertPackages(req.Packages), + EncryptPackages: convertPackages(req.EncryptPackages), + } + + appTempInfo.CustomData.SourceFile = append(appTempInfo.CustomData.SourceFile, sourceFileInfo) + log.Infof("new temp info:%+v", appTempInfo) + err = repo.UpdateInfo(traceCtx, appTempInfo) + if err != nil { + log.Errorf("UpdateInfo err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData) + return + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +func (s AppTempInfoService) GenTempApp(c *gin.Context, req proto.CreateTempAppInfoReq) { + traceCtx := apm.ApmClient().TraceContextFromGin(c) + var ( + rspData = make(map[string]interface{}) + appId = bson.NewObjectId().Hex() + ) + + if req.ProjectType < 0 || req.ProjectType > 2 { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_PARAM_ERR, nil) + return + } + log.Infof("GenTempApp appId:[%s]", appId) + appTempInfo := repository.NewDefaultInfo(appId, req.ProjectType) + + repo := impl.InitAppTempInfoRepo() + err := repo.Insert(traceCtx, appTempInfo) + if err != nil { + log.Errorf("GenTempApp db err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData) + return + } + + nowMs := utils.GetNowMs() + qrcodeInfo := &entity.QrCodeInfo{ + Type: entity.QrCodeTypeTemporary, + Uuid: GenTemporaryQrCodeUuid(appId, entity.AppTempDefSequence), + AppId: appId, + Sequence: appTempInfo.Sequence, + ApiServer: config.Cfg.ApiServer, + CodeId: "", //codeid 和 appid 相同 + StartParams: entity.AppStartParams{}, + ExpireTime: nowMs + int64(config.Cfg.QRcodeExpireTime*1e3), + CreateTime: nowMs, + } + //插入二维码信息 + qrCodeRepo := impl.InitQrCodeInfoRepo() + err = qrCodeRepo.GenInfo(traceCtx, qrcodeInfo) + if err != nil { + log.Errorf("gen temp qrcode info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_DB_ERR, rspData) + return + } + log.Infof("GenTempApp appId:[%s]", appId) + rspData["appId"] = appId + rspData["sequence"] = entity.AppTempDefSequence + log.Infof("GenTempApp rsp:%+v", rspData) + utility.MakeLocRsp(c, http.StatusOK, utility.OK, rspData) + return +} + +func convertPackages(old []proto.Package) []entity.Package { + n := len(old) + if n == 0 { + return nil + } + + res := make([]entity.Package, 0, n) + + for _, val := range old { + res = append(res, entity.Package{ + Root: val.Root, + Name: val.Name, + Pages: val.Pages, + Independent: val.Independent, + Filename: val.Filename, + FileUrl: val.FileUrl, + FileMd5: val.FileMd5, + }) + } + + return res +} diff --git a/domain/service/binding.go b/domain/service/binding.go new file mode 100644 index 0000000..09cd59d --- /dev/null +++ b/domain/service/binding.go @@ -0,0 +1,2332 @@ +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 + } +} diff --git a/domain/service/boxtool.go b/domain/service/boxtool.go new file mode 100644 index 0000000..a8dcd2a --- /dev/null +++ b/domain/service/boxtool.go @@ -0,0 +1,120 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + pb "finclip-app-manager/infrastructure/protobuf/golang" +) + +type BoxTool struct{} + +func NewBoxTool() *BoxTool { + return &BoxTool{} +} + +func (b *BoxTool) CovertAppVerToAppRspData(appVer *entity.AppVersion, rspData *pb.AppInfoRspData) { + if appVer == nil { + return + } + if rspData == nil { + rspData = new(pb.AppInfoRspData) + } + rspData.AppClass = appVer.AppClass + rspData.AppId = appVer.AppID + rspData.AppType = appVer.AppType + rspData.CoreDescription = appVer.CoreDescription + rspData.CorporationId = appVer.CorporationID + rspData.Created = appVer.Created + rspData.CreatedBy = appVer.CreatedBy + rspData.DeveloperId = appVer.DeveloperID + rspData.GroupId = appVer.GroupID + //rspItem.AppInfo.GroupName = appVer.groupname + rspData.InGrayRelease = appVer.InGrayRelease + rspData.Logo = appVer.Logo + rspData.Name = appVer.Name + rspData.Sequence = int32(appVer.Sequence) + rspData.Version = appVer.Version + rspData.IsTemp = false + + rspData.Status = new(pb.Status) + rspData.Status.Value = appVer.Status.Value + rspData.Status.Reason = appVer.Status.Reason + rspData.Status.ModifiedBy = appVer.Status.ModifiedBy + rspData.Status.LastUpdated = appVer.Status.LastUpdated + + if rspData.CustomData == nil { + rspData.CustomData = new(pb.CustomData) + } + err, _, customData := ConvertModelCustomDataToPb(context.Background(), appVer.GroupID, appVer.CustomData, nil, "") + if err != nil { + log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return + } + rspData.CustomData = customData + + return +} + +func (b *BoxTool) PackDomainToAppRspCustom(rspData *pb.AppInfoRspData, domainInfo *httpcall.DomainResponseData) { + if rspData.CustomData == nil { + rspData.CustomData = new(pb.CustomData) + } + if rspData.CustomData.AppRuntimeDomain == nil { + rspData.CustomData.AppRuntimeDomain = new(pb.AppRuntimeDomain) + } + if domainInfo != nil { + rspData.CustomData.AppRuntimeDomain = new(pb.AppRuntimeDomain) + rspData.CustomData.AppRuntimeDomain.Business = new(pb.AppRuntimeDomain_Business) + rspData.CustomData.AppRuntimeDomain.Business.Domains = domainInfo.Business.Domains + rspData.CustomData.AppRuntimeDomain.Service = new(pb.AppRuntimeDomain_Service) + rspData.CustomData.AppRuntimeDomain.Service.Socket = domainInfo.Service.Socket + rspData.CustomData.AppRuntimeDomain.Service.Request = domainInfo.Service.Request + rspData.CustomData.AppRuntimeDomain.Service.Download = domainInfo.Service.Download + rspData.CustomData.AppRuntimeDomain.Service.Upload = domainInfo.Service.Upload + rspData.CustomData.AppRuntimeDomain.Whitelist = new(pb.AppRuntimeDomain_Whitelist) + rspData.CustomData.AppRuntimeDomain.Whitelist.Domains = domainInfo.Whitelist.Domains + rspData.CustomData.AppRuntimeDomain.Blacklist = new(pb.AppRuntimeDomain_Blacklist) + rspData.CustomData.AppRuntimeDomain.Blacklist.Domains = domainInfo.Blacklist.Domains + } +} + +func (b *BoxTool) PackMenuToAppRspCustom(rspData *pb.AppInfoRspData, menuInfo *proto.MenuInfoRspData) { + if rspData.CustomData == nil { + rspData.CustomData = new(pb.CustomData) + } + if menuInfo != nil { + rspData.CustomData.MenuInfo = new(pb.MenuInfoRspData) + rspData.CustomData.MenuInfo.Total = int32(menuInfo.Total) + rspData.CustomData.MenuInfo.List = make([]*pb.MenuInfoRspDataItem, 0) + if menuInfo.List != nil { + for _, v := range menuInfo.List { + item := pb.MenuInfoRspDataItem{} + item.Name = v.Name + item.Image = v.Image + item.Id = v.ID + rspData.CustomData.MenuInfo.List = append(rspData.CustomData.MenuInfo.List, &item) + } + } + } +} + +func (b *BoxTool) PackApiInfoToAppRspCustom(rspData *pb.AppInfoRspData, apiInfo *[]proto.ApiInfoRspData) { + if rspData.CustomData == nil { + rspData.CustomData = new(pb.CustomData) + } + rspData.CustomData.ApiInfo = nil + if apiInfo != nil && config.Cfg.EnableApiManage() { + if rspData.CustomData.ApiInfo == nil { + rspData.CustomData.ApiInfo = make([]*pb.ApiInfoRspData, 0) + } + for _, v := range *apiInfo { + item := new(pb.ApiInfoRspData) + item.Url = v.Url + item.ApiName = v.ApiName + rspData.CustomData.ApiInfo = append(rspData.CustomData.ApiInfo, item) + } + } +} diff --git a/domain/service/license_check.go b/domain/service/license_check.go new file mode 100644 index 0000000..1a6e7a4 --- /dev/null +++ b/domain/service/license_check.go @@ -0,0 +1,125 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + + "gitlab.finogeeks.club/finclip-backend/apm" + + "sync" + "time" +) + +const ( + LICENSE_VALID_EXPIRE = 60 + + LICENSE_IS_VALID = 0 + BUNDLE_ID_COUNT_INVAILD = 1 +) + +var LicenseValid int32 +var mutex = sync.Mutex{} + +func GetLicenseValid() int32 { + result := LicenseValid + return result +} + +func LicenceCheckStart() { + //LICENSE_VALID_EXPIRE跑一次 + go func() { + updateLicenseValid(context.Background()) + t := time.NewTicker(time.Second * LICENSE_VALID_EXPIRE) + for { + select { + case <-t.C: + func() { + span, ctx := apm.ApmClient().CreateLocalSpan(context.Background()) + span.SetOperationName("updateLicenseValid") + defer span.End() + go updateLicenseValid(ctx) + }() + } + } + }() +} + +func updateLicenseValid(ctx context.Context) { + var upErr error = nil + + defer func(e error) { + if e != nil { + log.Debugf("updateLicenseValid panic err:%s", e.Error()) + upValid(LICENSE_IS_VALID) + } + }(upErr) + licenseInfo, err := hCaller.GetLicense(ctx) + if err != nil { + upErr = err + log.Errorf("updateLicenseValid get license info err:%s", err.Error()) + return + } + log.Debugf("updateLicenseValid get license info:%+v", licenseInfo) + bindingTotal, err := getBindingNum(ctx) + if err != nil { + upErr = err + log.Errorf("updateLicenseValid get binding count err:%s", err.Error()) + return + } + log.Debugf("updateLicenseValid get binding count:%d", bindingTotal) + bundleIdTotal, err := getBundleIdNum(ctx) + if err != nil { + upErr = err + log.Errorf("updateLicenseValid get bundle id count err:%s", err.Error()) + return + } + log.Debugf("updateLicenseValid get bundle id count:%d", bundleIdTotal) + //获取小程序数量 + appNum, err := getAppNum(ctx) + if err != nil { + upErr = err + log.Errorf("updateLicenseValid get app count err:%s", err.Error()) + return + } + //校验应用数量 + + if (licenseInfo.BundleIdCount < bundleIdTotal) || + (licenseInfo.CooAppCount < bindingTotal) || + (licenseInfo.AppCount < appNum) { + log.Errorf("updateLicenseValid bundle id or app num over limit,"+ + "license info:%+v,bundle id num:%d,appNum:%d", licenseInfo, bundleIdTotal, appNum) + upValid(BUNDLE_ID_COUNT_INVAILD) + } else { + upValid(LICENSE_IS_VALID) + } +} + +func upValid(result int32) { + mutex.Lock() + defer mutex.Unlock() + LicenseValid = result + log.Debugf("upValid valid:%d", LicenseValid) +} + +func getAppNum(ctx context.Context) (int, error) { + appRepo := impl.InitAppRepo() + count, err := appRepo.AppCount(ctx, "") + if err != nil { + log.Errorf("license valid update err:%s", err.Error()) + } + return count, err +} + +func getBindingNum(ctx context.Context) (int, error) { + bindingRepo := impl.InitBindingRepo() + return bindingRepo.GetCountByStatus(ctx, "Valid", entity.BINGING_PLATFORM_ALL) +} + +func getBundleIdNum(ctx context.Context) (int, error) { + if config.GetConfig().IsPrivateEnv() { + return impl.InitBundleRepo().AllCount(ctx) + } + return 0, nil +} diff --git a/domain/service/link_audit.go b/domain/service/link_audit.go new file mode 100644 index 0000000..7318369 --- /dev/null +++ b/domain/service/link_audit.go @@ -0,0 +1,24 @@ +package service + +import ( + "context" + impl "finclip-app-manager/infrastructure/db/repo" +) + +type LinkAuditService struct { +} + +func NewLinkAuditService() *LinkAuditService { + var s LinkAuditService + return &s +} + +func (s LinkAuditService) Count(ctx context.Context, appID string, groupId string, bindingID string, stLinkAudit string) (int, error) { + repo := impl.InitLinkAuditRepo() + return repo.Count(ctx, appID, groupId, bindingID, stLinkAudit) +} + +func (s LinkAuditService) NotFound(err error) bool { + repo := impl.InitLinkAuditRepo() + return repo.NotFound(err) +} diff --git a/domain/service/menu_info.go b/domain/service/menu_info.go new file mode 100644 index 0000000..fb12c38 --- /dev/null +++ b/domain/service/menu_info.go @@ -0,0 +1,180 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/infrastructure/cache/redis" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/utility" + "github.com/gin-gonic/gin" + "gopkg.in/mgo.v2/bson" + "net/http" + "time" +) + +type MenuInfoService struct { +} + +func NewMenuInfoService() *MenuInfoService { + var s MenuInfoService + return &s +} + +func (m *MenuInfoService) AddMenu(ctx context.Context, c *gin.Context, req *apiproto.AddMenuReq) { + errRsp := make(map[string]interface{}) + userId := c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY) + adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("get admin info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + now := time.Now().UnixNano() / 1e6 + menuInfo := entity.MenuInfo{ + TraceId: bson.NewObjectId().Hex(), + Name: req.Name, + InfoId: req.ID, + ImageUrl: req.Image, + CreateTime: now, + UpdateTime: now, + UpdateOperator: adminInfo.Account, + } + + repo := impl.InitMenuInfoRepo() + err = repo.Add(ctx, &menuInfo) + if err != nil { + log.Errorf("add menu err:%s", err.Error()) + if err == entity.MenuIdOrNameExiErr { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_MENU_ID_EXITS_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + + //m.menuCache.UpdateMemMenuCreatedInfo(true) + //m.menuCache.SetRedisMenuCreatedInfo(ctx) + //m.menuCache.Update(ctx) + redis.RedisSet(ctx, utility.MenuCreatedKey, utility.MenuCreatedValue, 0) + errRsp["traceId"] = menuInfo.TraceId + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, errRsp) + return +} + +func (m *MenuInfoService) DelMenu(ctx context.Context, c *gin.Context, traceId string) { + userId := c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY) + _, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("get admin info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + + repo := impl.InitMenuInfoRepo() + err = repo.DelByTraceId(ctx, traceId) + if err != nil { + log.Errorf("del menu err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + + //m.menuCache.Update(ctx) + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} + +func (m *MenuInfoService) UpdateMenu(ctx context.Context, c *gin.Context, traceId string, req *apiproto.UpdateMenuReq) { + userId := c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY) + adminInfo, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("get admin info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + repo := impl.InitMenuInfoRepo() + menuInfo, err := repo.GetInfoByTraceId(ctx, traceId) + if err != nil { + log.Errorf("get menu info by trace id err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + + menuInfo.Name = req.Name + menuInfo.ImageUrl = req.Image + menuInfo.InfoId = req.ID + menuInfo.UpdateOperator = adminInfo.Account + + err = repo.UpdateInfo(ctx, traceId, menuInfo) + if err != nil { + if err == entity.MenuIdOrNameExiErr { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_MENU_ID_EXITS_ERR, gin.H{}) + return + } + log.Errorf("update menu err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + + //m.menuCache.Update(ctx) + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} + +func (m *MenuInfoService) GetAllMenu(ctx context.Context, c *gin.Context) { + result := apiproto.GetAllMenuRsp{} + + repo := impl.InitMenuInfoRepo() + infoList, total, err := repo.GetAllMenuList(ctx, []string{"sort_num"}) + if err != nil { + log.Errorf("get all menu err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, result) + return + } + result.List = make([]apiproto.GetAllMenuRspItem, 0) + result.Total = total + for _, v := range infoList { + item := apiproto.GetAllMenuRspItem{} + item.TraceId = v.TraceId + item.Name = v.Name + item.Image = v.ImageUrl + item.ID = v.InfoId + item.SortNum = v.SortNum + item.CreateTime = v.CreateTime + item.UpdateTime = v.UpdateTime + item.UpdateOperator = v.UpdateOperator + result.List = append(result.List, item) + } + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, result) + return +} + +func (m *MenuInfoService) SortMenu(ctx context.Context, c *gin.Context, req *apiproto.MenuSortReq) { + userId := c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY) + _, err := hCaller.GetAdminAccountInfo(ctx, userId) + if err != nil { + log.Errorf("get admin info err:%s", err.Error()) + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SYSTEM_CALL, gin.H{}) + return + } + repo := impl.InitMenuInfoRepo() + err = repo.Sort(ctx, req) + if err != nil { + log.Errorf("sort menu err:%s", err.Error()) + if err.Error() == "has deleted" { + utility.MakeLocRsp(c, http.StatusBadRequest, utility.FS_DATA_HAS_DEL_ERR, gin.H{}) + return + } + utility.MakeLocRsp(c, http.StatusInternalServerError, utility.FS_SERVER_ERR, gin.H{}) + return + } + + //m.menuCache.Update(ctx) + + utility.MakeLocRsp(c, http.StatusOK, utility.OK, gin.H{}) + return +} diff --git a/domain/service/protocol/req.go b/domain/service/protocol/req.go new file mode 100644 index 0000000..b71b188 --- /dev/null +++ b/domain/service/protocol/req.go @@ -0,0 +1,6 @@ +package protocol + +/** +* DDD: domain 领域层-service-protocol +* 领域服务协议: application层将gin http请求翻译成service可以理解的协议 +**/ diff --git a/domain/service/public.go b/domain/service/public.go new file mode 100644 index 0000000..1d8bf24 --- /dev/null +++ b/domain/service/public.go @@ -0,0 +1,587 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "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/logger" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "finclip-app-manager/infrastructure/utils" +) + +var ( + log = logger.GetLogger() + hCaller = httpcall.NewClient() +) + +func NotFound(err error) bool { + return repository.NotFound(err) +} + +func ConvertModelCustomDataToRpc( + ctx context.Context, + groupId string, + data entity.CustomDataInfo, + domain *httpcall.DomainResponseData, + sdkVer string, +) (error, string, *proto.AppRspCustomData) { + err, errCode, customData := ConvertModelCustomDataToPb(ctx, groupId, data, domain, sdkVer) + if err != nil { + return err, errCode, nil + } + return nil, "", convertPbCustomDataToRpc(customData) +} + +func convertPbCustomDataToRpc(info *pb.CustomData) *proto.AppRspCustomData { + rsp := new(proto.AppRspCustomData) + rsp.DetailDescription = info.DetailDescription + rsp.VersionDescription = info.VersionDescription + rsp.AppRuntimeDomain = *GetProtoRuntimeDomainsFromPb(info) + if info.MenuInfo != nil { + rsp.MenuInfo = new(proto.MenuInfoRspData) + rsp.MenuInfo.Total = int(info.MenuInfo.Total) + if info.MenuInfo.List != nil { + if len(info.MenuInfo.List) == 0 { + rsp.MenuInfo.List = make([]proto.MenuInfoRspDataItem, 0) + } else { + for _, v := range info.MenuInfo.List { + item := proto.MenuInfoRspDataItem{} + item.Name = v.Name + item.Image = v.Image + item.ID = v.Id + rsp.MenuInfo.List = append(rsp.MenuInfo.List, item) + } + } + } + } + if info.ApiInfo != nil { + apiInfos := []proto.ApiInfoRspData{} + for i := 0; i < len(info.ApiInfo); i++ { + api := info.ApiInfo[i] + item := proto.ApiInfoRspData{ApiName: api.ApiName, Url: api.Url} + apiInfos = append(apiInfos, item) + } + rsp.ApiInfo = &apiInfos + } + if len(info.ApiInfo) == 0 && config.GetConfig().EnableApiManage() { + rsp.ApiInfo = &[]proto.ApiInfoRspData{{ApiName: "", Url: ""}} + } + + rsp.SourceFile = make([]proto.RspCustomDataSourceFile, 0) + if len(info.SourceFile) > 0 { + temp := info.SourceFile[0] + item := proto.RspCustomDataSourceFile{} + item.Name = temp.Name + item.Url = temp.Url + item.FileMd5 = temp.FileMd5 + item.SourceFileUrl = temp.SourceFileUrl + item.UploadDate = temp.UploadDate + item.BasicPackVer = temp.BasicPackVer + for _, val := range temp.Packages { + item.Packages = append(item.Packages, proto.Package{ + Root: val.Root, + Name: val.Name, + Pages: val.Pages, + Independent: val.Independent, + Filename: val.Filename, + FileUrl: val.FileUrl, + FileMd5: val.FileMd5, + }) + } + rsp.SourceFile = append(rsp.SourceFile, item) + } + return rsp +} + +func GetProtoRuntimeDomainsFromPb(data *pb.CustomData) *proto.AppRuntimeDomainData { + domainInfo := data.AppRuntimeDomain + result := &proto.AppRuntimeDomainData{} + if domainInfo == nil { + return result + } + if domainInfo.Business.Domains != nil { + result.Business.Domains = domainInfo.Business.Domains + } + if domainInfo.Service.Download != nil { + result.Service.Download = domainInfo.Service.Download + } + if domainInfo.Service.Request != nil { + result.Service.Request = domainInfo.Service.Request + } + if domainInfo.Service.Socket != nil { + result.Service.Socket = domainInfo.Service.Socket + } + if domainInfo.Service.Download != nil { + result.Service.Upload = domainInfo.Service.Upload + } + if domainInfo.Whitelist.Domains != nil { + result.Whitelist.Domains = domainInfo.Whitelist.Domains + } + if domainInfo.Blacklist.Domains != nil { + result.Blacklist.Domains = domainInfo.Blacklist.Domains + } + return result +} + +func covertAppToRsp(ctx context.Context, info *entity.AppVersion, rsp *RuntimeGetAppResponse, sdkVer string, domainData *httpcall.DomainResponseData) error { + rsp.AppID = info.AppID + rsp.Name = info.Name + rsp.Sequence = info.Sequence + rsp.AppClass = info.AppClass + rsp.AppTag = info.AppTag + rsp.AppType = info.AppType + rsp.DeveloperID = info.DeveloperID + rsp.GroupID = info.GroupID + rsp.GroupName = "" + rsp.Created = info.Created + rsp.CreatedBy = info.CreatedBy + rsp.Version = info.Version + rsp.CorporationID = info.CorporationID + rsp.CoreDescription = info.CoreDescription + rsp.Logo = info.Logo + err, _, customData := ConvertModelCustomDataToRpc(ctx, info.GroupID, info.CustomData, domainData, sdkVer) + if err != nil { + log.Errorf("openApiGetAppVerInfoFromCache ConvertModelCustomDataToRpc err:[%s]", err.Error()) + return err + } + rsp.CustomData = *customData + rsp.Status.Value = info.Status.Value + rsp.Status.ModifiedBy = info.Status.ModifiedBy + rsp.Status.Reason = info.Status.Reason + rsp.Status.LastUpdated = info.Status.LastUpdated + rsp.IsTemp = false + rsp.NeedCrt = domainData.NeedCrt + rsp.InGrayRelease = info.InGrayRelease + return nil +} + +func ConvertRpcCustomDataToPb(info proto.AppRspCustomData) *pb.CustomData { + rsp := new(pb.CustomData) + rsp.DetailDescription = info.DetailDescription + rsp.VersionDescription = info.VersionDescription + rsp.AppRuntimeDomain = GetPbRuntimeDomainsFromProto(info.AppRuntimeDomain) + if info.MenuInfo != nil { + rsp.MenuInfo = new(pb.MenuInfoRspData) + rsp.MenuInfo.Total = int32(info.MenuInfo.Total) + if info.MenuInfo.List != nil { + for _, v := range info.MenuInfo.List { + item := pb.MenuInfoRspDataItem{} + item.Name = v.Name + item.Image = v.Image + item.Id = v.ID + rsp.MenuInfo.List = append(rsp.MenuInfo.List, &item) + } + } + } + if info.ApiInfo != nil { + apiInfos := *info.ApiInfo + for i := 0; i < len(apiInfos); i++ { + api := apiInfos[i] + item := &pb.ApiInfoRspData{ApiName: api.ApiName, Url: api.Url} + rsp.ApiInfo = append(rsp.ApiInfo, item) + } + } + if len(rsp.ApiInfo) == 0 && config.GetConfig().EnableApiManage() { + item := &pb.ApiInfoRspData{ApiName: "", Url: ""} + rsp.ApiInfo = append(rsp.ApiInfo, item) + } + + rsp.SourceFile = make([]*pb.SourceFileData, 0) + if len(info.SourceFile) > 0 { + temp := info.SourceFile[0] + item := new(pb.SourceFileData) + item.Name = temp.Name + item.Url = temp.Url + item.FileMd5 = temp.FileMd5 + item.SourceFileUrl = temp.SourceFileUrl + item.UploadDate = temp.UploadDate + item.BasicPackVer = temp.BasicPackVer + for _, val := range temp.Packages { + item.Packages = append(item.Packages, &pb.Package{ + Root: val.Root, + Name: val.Name, + Pages: val.Pages, + Independent: val.Independent, + Filename: val.Filename, + FileUrl: val.FileUrl, + FileMd5: val.FileMd5, + }) + } + rsp.SourceFile = append(rsp.SourceFile, item) + } + return rsp +} + +func GetPbRuntimeDomainsFromProto(domainInfo proto.AppRuntimeDomainData) *pb.AppRuntimeDomain { + return &pb.AppRuntimeDomain{ + Business: &pb.AppRuntimeDomain_Business{ + Domains: domainInfo.Business.Domains, + }, + Service: &pb.AppRuntimeDomain_Service{ + Download: domainInfo.Service.Download, + Request: domainInfo.Service.Request, + Socket: domainInfo.Service.Socket, + Upload: domainInfo.Service.Upload, + }, + Whitelist: &pb.AppRuntimeDomain_Whitelist{ + Domains: domainInfo.Whitelist.Domains, + }, + Blacklist: &pb.AppRuntimeDomain_Blacklist{ + Domains: domainInfo.Blacklist.Domains, + }, + } +} + +type RuleEngineGetAppVerInfoRsp struct { + AppID string `json:"appId"` + Name string `json:"name"` + Sequence int `json:"sequence"` + AppClass string `json:"appClass"` + AppType string `json:"appType"` + DeveloperID string `json:"developerId"` + DeveloperStatus int `json:"developerStatus"` + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + Created int64 `json:"created"` + CreatedBy string `json:"createdBy"` + CustomData proto.AppRspCustomData `json:"customData"` + Version string `json:"version"` + CorporationID string `json:"corporationId"` + CoreDescription string `json:"coreDescription"` + Logo string `json:"logo"` + Status proto.AppRspStatus `json:"status"` + InGrayRelease bool `json:"inGrayRelease"` //是否在灰度发布中 + IsTemp bool `json:"isTemp"` + NeedCrt bool `json:"needCrt"` + WechatLoginInfo proto.WechatLoginInfo `json:"wechatLoginInfo"` +} + +func covertAppVerToRuleEngineRsp(appVer *entity.AppVersion) (rsp *RuleEngineGetAppVerInfoRsp) { + if appVer == nil { + return + } + rsp = &RuleEngineGetAppVerInfoRsp{ + AppID: appVer.AppID, + Name: appVer.Name, + Sequence: appVer.Sequence, + AppClass: appVer.AppClass, + AppType: appVer.AppType, + DeveloperID: appVer.DeveloperID, + GroupID: appVer.GroupID, + Created: appVer.Created, + CreatedBy: appVer.CreatedBy, + Version: appVer.Version, + CorporationID: appVer.CorporationID, + CoreDescription: appVer.CoreDescription, + Logo: appVer.Logo, + InGrayRelease: appVer.InGrayRelease, + } + rsp.Status.ModifiedBy = appVer.Status.ModifiedBy + rsp.Status.Reason = appVer.Status.Reason + rsp.Status.LastUpdated = appVer.Status.LastUpdated + rsp.Status.Value = appVer.Status.Value + + rsp.IsTemp = false + return +} + +func getAccountStatus(groupIDData *httpcall.GroupIDData) int { + //if developerData.Type == client.ORGAN_ACCOUNT_TYPE_PERSON { + // return developerData.Status + //} + //if developerData.Type == client.ORGAN_ACCOUNT_TYPE_BUSINESS { + log.Infof("getAccountStatus-----groupIDData.ReviewStatus: %d\n", groupIDData.ReviewStatus) + if config.Cfg.IsUatEnv() { + if groupIDData.ReviewStatus == httpcall.StOrganApproved { + return httpcall.ORGAN_STATUS_NORMAL + } + if groupIDData.ReviewStatus == httpcall.StOrganUnApproved { + return httpcall.ORGAN_STATUS_FREEZE + } + } + //} + + // 私有化环境固定返回1 + return httpcall.ORGAN_STATUS_NORMAL +} + +func convertPackages2(old []entity.Package) []proto.Package { + n := len(old) + if n == 0 { + return nil + } + + res := make([]proto.Package, 0, n) + + for _, val := range old { + res = append(res, proto.Package{ + Root: val.Root, + Name: val.Name, + Pages: val.Pages, + Independent: val.Independent, + Filename: val.Filename, + FileUrl: val.FileUrl, + FileMd5: val.FileMd5, + }) + } + + return res +} + +func CovertAppToPbAppInfoRsp(info *RuntimeGetAppResponse) *pb.AppInfoRspData { + if info == nil { + return nil + } + rspInfo := &pb.AppInfoRspData{} + + rspInfo.AppId = info.AppID + rspInfo.AppClass = info.AppClass + rspInfo.AppId = info.AppID + rspInfo.AppType = info.AppType + rspInfo.CoreDescription = info.CoreDescription + rspInfo.CorporationId = info.CorporationID + rspInfo.Created = info.Created + rspInfo.CreatedBy = info.CreatedBy + rspInfo.DeveloperId = info.DeveloperID + rspInfo.GroupId = info.GroupID + rspInfo.GroupName = info.GroupName + rspInfo.InGrayRelease = info.InGrayRelease + rspInfo.Logo = info.Logo + rspInfo.Name = info.Name + rspInfo.Sequence = int32(info.Sequence) + rspInfo.Version = info.Version + rspInfo.CustomData = ConvertRpcCustomDataToPb(info.CustomData) + rspInfo.Status = new(pb.Status) + rspInfo.Status.Value = info.Status.Value + rspInfo.Status.Reason = info.Status.Reason + rspInfo.Status.ModifiedBy = info.Status.ModifiedBy + rspInfo.Status.LastUpdated = info.Status.LastUpdated + rspInfo.IsTemp = info.IsTemp + rspInfo.NeedCrt = info.NeedCrt + rspInfo.DeveloperStatus = int32(info.DeveloperStatus) + rspInfo.WechatLoginInfo = new(pb.WechatLoginInfo) + rspInfo.WechatLoginInfo.WechatOriginId = info.WechatLoginInfo.WechatOriginId + rspInfo.WechatLoginInfo.ProfileUrl = info.WechatLoginInfo.ProfileUrl + rspInfo.WechatLoginInfo.PhoneUrl = info.WechatLoginInfo.PhoneUrl + rspInfo.WechatLoginInfo.PaymentUrl = info.WechatLoginInfo.PaymentUrl + for _, v := range info.WechatLoginInfo.ExtUrls { + ext := pb.ExtUrls{ + FieldName: v.FieldName, + PageUrl: v.PageUrl, + } + rspInfo.WechatLoginInfo.ExtUrls = append(rspInfo.WechatLoginInfo.ExtUrls, &ext) + } + rspInfo.AppTag = info.AppTag + rspInfo.PrivacySettingType = int32(info.PrivacySettingType) + rspInfo.ProjectType = int32(info.ProjectType) + return rspInfo +} + +func CovertInternalAppToPbAppInfoRsp(info *InternalGetAppVerInfoRsp) *pb.AppInfoRspData { + if info == nil { + return nil + } + rspInfo := &pb.AppInfoRspData{} + + rspInfo.AppId = info.AppID + rspInfo.AppClass = info.AppClass + rspInfo.AppId = info.AppID + rspInfo.AppType = info.AppType + rspInfo.CoreDescription = info.CoreDescription + rspInfo.CorporationId = info.CorporationID + rspInfo.Created = info.Created + rspInfo.CreatedBy = info.CreatedBy + rspInfo.DeveloperId = info.DeveloperID + rspInfo.GroupId = info.GroupID + rspInfo.GroupName = info.GroupName + rspInfo.InGrayRelease = info.InGrayRelease + rspInfo.Logo = info.Logo + rspInfo.Name = info.Name + rspInfo.Sequence = int32(info.Sequence) + rspInfo.Version = info.Version + rspInfo.CustomData = ConvertRpcCustomDataToPb(info.CustomData) + rspInfo.Status = new(pb.Status) + rspInfo.Status.Value = info.Status.Value + rspInfo.Status.Reason = info.Status.Reason + rspInfo.Status.ModifiedBy = info.Status.ModifiedBy + rspInfo.Status.LastUpdated = info.Status.LastUpdated + rspInfo.IsTemp = info.IsTemp + rspInfo.NeedCrt = info.NeedCrt + rspInfo.DeveloperStatus = int32(info.DeveloperStatus) + rspInfo.WechatLoginInfo = ConvertWechatLoginInfoToPb(&info.WechatLoginInfo) + rspInfo.AppTag = info.AppTag + rspInfo.PrivacySettingType = int32(info.PrivacySettingType) + rspInfo.ProjectType = int32(info.ProjectType) + return rspInfo +} + +//金易联活动上报 +func sendSwanReport(traceCtx context.Context, t, id string) { + if !config.GetConfig().SwanReportEnable { + return + } + log.Infof("sendSwanReport req t:[%s],id:[%s]", t, id) + var ( + accountInfo *httpcall.AccountInfoData + err error + ) + /*if t == "userId" { + accountInfo, err = hCaller.GetAccountInfo(traceCtx, id) + if err != nil { + log.Errorf("sendSwanReport get account info err:%s", err.Error()) + return + } + if len(accountInfo.Phone) == 0 { + log.Errorf("sendSwanReport get account info phone len is 0") + return + } + } else {*/ + accountInfo, err = hCaller.GetAccountInfoByAccount(traceCtx, id) + if err != nil { + log.Errorf("sendSwanReport get account info err:%s", err.Error()) + return + } + //} + if len(accountInfo.Phone) == 0 { + log.Errorf("sendSwanReport get account info phone len is 0") + return + } + hCaller.SwanReport(traceCtx, accountInfo.Phone, "上架小程序") +} + +func sendDelaySms(traceCtx context.Context, developerID string, isPass, isPubImmediately, isPub bool, appId, appName string, sequence int) { + if !config.Cfg.IsFdepEnv() && !config.Cfg.IsUatEnv() { + return + } + accountInfo, err := hCaller.GetAccountInfo(traceCtx, developerID) + if err != nil { + log.Errorf("sendSmsNotify get account info err:%s", err.Error()) + return + } + decryptPhone, err := utils.DES_ECB{}.DecryptDES_ECB(accountInfo.Phone, utils.DES_CRYPT_KEY) + if err != nil { + log.Errorf("DecryptDES_ECB err:%s", err.Error()) + return + } + // 上架通过审核的小程序 + if isPub { + // 删除待发生的审核通过短信 + if config.GetConfig().ThirdEnv == httpcall.THIRD_ENV_ZHAOS { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_ZHAOS_APP_PUBLISH_SUCC, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_ZHAOS_APP_PUBLISH_SUCC, appId, appName, sequence, err.Error()) + } + } else { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_APP_PUBLISH_SUCC, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_APP_PUBLISH_SUCC, appId, appName, sequence, err.Error()) + } + } + return + } + // 还在审核阶段 + // 审核通过 + if isPass { + // 不是立即上架 + if !isPubImmediately { + // 延迟发送审核通过短信,并删除原来的待发生的申请上架审核短信, 在audit中做 + if config.GetConfig().ThirdEnv == httpcall.THIRD_ENV_ZHAOS { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_ZHAOS_APP_PUBLISH_APPROVE, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_ZHAOS_APP_PUBLISH_APPROVE, appId, appName, sequence, err.Error()) + } + } else { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_APP_PUBLISH_APPROVE, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_APP_PUBLISH_APPROVE, appId, appName, sequence, err.Error()) + } + } + } else { + // 是立即上架,删除原来的待发生的申请上架审核短信 + if config.GetConfig().ThirdEnv == httpcall.THIRD_ENV_ZHAOS { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_ZHAOS_APP_PUBLISH_IMMED, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_ZHAOS_APP_PUBLISH_IMMED, appId, appName, sequence, err.Error()) + } + } else { + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_APP_PUBLISH_IMMED, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_APP_PUBLISH_IMMED, appId, appName, sequence, err.Error()) + } + } + } + } else { + if config.GetConfig().ThirdEnv == httpcall.THIRD_ENV_ZHAOS { + // 拒绝,立即发送拒绝短信 + if err = hCaller.SendThirdSms(traceCtx, httpcall.SMS_ZHAOS_APP_PUBLISH_REJECT, decryptPhone, appName); err != nil { + log.Errorf("SendThirdSms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_ZHAOS_APP_PUBLISH_REJECT, appId, appName, sequence, err.Error()) + } + // 删除原来的待发生的申请上架审核短信 + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_ZHAOS_APP_PUBLISH_REJECT, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_ZHAOS_APP_PUBLISH_REJECT, appId, appName, sequence, err.Error()) + } + } else { + // 拒绝,立即发送拒绝短信 + if err = hCaller.SendSmsNotify(traceCtx, httpcall.SMS_APP_PUBLISH_REJECT, decryptPhone, appName); err != nil { + log.Errorf("sendSmsNotify smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_APP_PUBLISH_REJECT, appId, appName, sequence, err.Error()) + } + // 删除原来的待发生的申请上架审核短信 + if err = hCaller.SendDelaySms(traceCtx, httpcall.SMS_APP_PUBLISH_REJECT, decryptPhone, appId, appName, sequence); err != nil { + log.Errorf("SendDelaySms smsType:%s appId:%s appName:%s sequence:%d err:%s", httpcall.SMS_APP_PUBLISH_REJECT, appId, appName, sequence, err.Error()) + } + } + } +} + +func notifySpiderPubApp(ctx context.Context, appId, appName, desc, organName, sourceUrl, appTag, appClass string) { + //获取小程序关联的sdkKeys + bindRepo := impl.InitBindingRepo() + result, err := bindRepo.GetAllAssBinds(ctx, appId) + if err != nil { + log.Errorf("notifySpiderPubApp err:%s", err.Error()) + return + } + var sdkKeyListMap = make(map[string]bool, 0) + var sdkKeyList = make([]string, 0) + for _, v := range result { + for _, sdkKeyInfo := range v.BundleInfos { + if _, ok := sdkKeyListMap[sdkKeyInfo.SDKKey]; !ok { + sdkKeyListMap[sdkKeyInfo.SDKKey] = true + } + } + } + for k, _ := range sdkKeyListMap { + sdkKeyList = append(sdkKeyList, k) + } + + req := &httpcall.SpiderPubReq{ + AppId: appId, + AppName: appName, + AppDesc: desc, + OrganName: organName, + SdkKeys: sdkKeyList, + Resource: sourceUrl, + AppTag: appTag, + AppClass: appClass, + } + + log.Infof("notifySpiderPubApp req:%+v", req) + _, err = hCaller.PubAppNotifySearchApp(ctx, req) + if err != nil { + log.Errorf("notfiy spider publishApp appId:%s err:%s", appId, err.Error()) + } else { + log.Infof("notify spider publishApp appId:%s succ", appId) + } + return +} + +func notifySpiderPushApp(ctx context.Context, appId string, state int) { + notifys := &httpcall.NotifySpiderUpdate{Type: httpcall.STATE_UPDATE, State: httpcall.StateUpdate{ + AppId: appId, + State: state, + }} + _, err := hCaller.Notify(ctx, notifys) + if err != nil { + log.Errorf("notfiy spider publishApp appId:%s err:%s", appId, err.Error()) + } else { + log.Infof("notify spider publishApp appId:%s succ", appId) + } +} diff --git a/domain/service/qr_code_info.go b/domain/service/qr_code_info.go new file mode 100644 index 0000000..c4a50ae --- /dev/null +++ b/domain/service/qr_code_info.go @@ -0,0 +1,275 @@ +package service + +import ( + "context" + "encoding/base64" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/config" + impl "finclip-app-manager/infrastructure/db/repo" + "finclip-app-manager/infrastructure/utils" + "fmt" +) + +const ( + qrcodePrefix = "-f-" + qrcodeSuffix = "--" +) + +type QrCodeInfoService struct { + qrcodeRepo repository.IQrCodeInfoRepo + buildInfoRepo repository.IAppBuildInfoRepo +} + +func NewQrCodeInfoService() *QrCodeInfoService { + return &QrCodeInfoService{ + qrcodeRepo: impl.InitQrCodeInfoRepo(), + buildInfoRepo: impl.InitBuildInfoRepo(), + } +} + +func (q *QrCodeInfoService) GenQrcodeInfo(ctx context.Context, req proto.GenQrcodeReq) (*entity.QrCodeInfo, error) { + var ( + info *entity.QrCodeInfo + err error + ) + + //首先查看是否已经存在uuid + switch req.Type { + case entity.QrCodeTypeReview: + info, err = q.qrcodeRepo.GetReviewInfo(ctx, req.AppId, req.Sequence) + case entity.QrCodeTypeRelease: + info, err = q.qrcodeRepo.GetReleaseInfo(ctx, req.AppId) + case entity.QrCodeTypeTrial: + info, err = q.qrcodeRepo.GetTrialInfo(ctx, req.AppId) + case entity.QrCodeTypeTemporary: + info, err = q.qrcodeRepo.GetTemporaryInfo(ctx, req.AppId, req.Sequence) + case entity.QrCodeTypeRomoteDebug: + info, err = q.qrcodeRepo.GetRemoteDebugInfo(ctx, req.AppId, req.Sequence) + default: + return nil, errors.New("type err") + } + if err != nil { + if !q.qrcodeRepo.NotFound(err) { + return nil, err + } + //不存在则进行插入 + info, err = q.insertQrcodeInfo(ctx, req) + if err != nil { + log.Errorf("insertQrcodeInfo err:%s", err.Error()) + return nil, err + } + return info, nil + } + //ide 临时小程序更新二维码时需更新过期时间 + if info.Type == entity.QrCodeTypeTemporary || info.Type == entity.QrCodeTypeRomoteDebug || info.Type == entity.QrCodeTypeReview { + expTime := int64(0) + if info.Type == entity.QrCodeTypeReview { + expTime = utils.GetNowMs() + int64(config.GetConfig().ReviewQRcodeExpireTime*1e3) + } else { + expTime = utils.GetNowMs() + int64(config.GetConfig().QRcodeExpireTime*1e3) + } + err = q.qrcodeRepo.UpdateInfo(ctx, info.Uuid, map[string]interface{}{"expire_time": expTime}) + if err != nil { + return nil, err + } + info.ExpireTime = expTime + if req.Type == entity.QrCodeTypeTemporary { + path := req.StartParams.Path + query := req.StartParams.Query + appStartParams := entity.AppStartParams{} + if len(query) > 0 { + appStartParams.PathAndQuery = path + "?" + query + } else { + appStartParams.PathAndQuery = path + } + err = q.qrcodeRepo.UpdateStartParamsByUuid(ctx, info.Uuid, appStartParams) + if err != nil { + return nil, err + } + } + } + if req.ApiServer != info.ApiServer { + err = q.qrcodeRepo.UpdateApiServer(ctx, info.Uuid, req.ApiServer) + if err != nil { + log.Errorf("GenQrcodeInfo UpdateApiServer err:%s", err.Error()) + return nil, err + } + info.ApiServer = req.ApiServer + } + return info, nil +} + +func (q *QrCodeInfoService) insertQrcodeInfo(ctx context.Context, req proto.GenQrcodeReq) (*entity.QrCodeInfo, error) { + //首先查看是否已经存在uuid + var ( + qrCodeInfo *entity.QrCodeInfo + nowMs = utils.GetNowMs() + ) + + path := req.StartParams.Path + query := req.StartParams.Query + appStartParams := entity.AppStartParams{} + if len(query) > 0 { + appStartParams.PathAndQuery = path + "?" + query + } else { + appStartParams.PathAndQuery = path + } + + switch req.Type { + case entity.QrCodeTypeReview: + //生成该版本的二维码信息 + qrCodeInfo = &entity.QrCodeInfo{ + Type: entity.QrCodeTypeReview, + Uuid: GenReviewQrCodeUuid(req.AppId, req.Sequence), + AppId: req.AppId, + Sequence: req.Sequence, + ApiServer: req.ApiServer, + CodeId: req.CodeId, + StartParams: appStartParams, + CreateTime: nowMs, + DebugInfo: req.DebugInfo, + ExpireTime: nowMs + int64(config.GetConfig().ReviewQRcodeExpireTime*1e3), + } + case entity.QrCodeTypeRelease: + qrCodeInfo = &entity.QrCodeInfo{ + Type: entity.QrCodeTypeRelease, + Uuid: GenReleaseQrCodeUuid(req.AppId), + AppId: req.AppId, + Sequence: req.Sequence, + ApiServer: req.ApiServer, + StartParams: appStartParams, + ExpireTime: 0, + CreateTime: nowMs, + DebugInfo: req.DebugInfo, + } + case entity.QrCodeTypeTrial: + qrCodeInfo = &entity.QrCodeInfo{ + Type: entity.QrCodeTypeTrial, + Uuid: GenTrialQrCodeUuid(req.AppId), + AppId: req.AppId, + Sequence: 0, + ApiServer: req.ApiServer, + CodeId: req.CodeId, + //todo ccc + StartParams: appStartParams, + CreateTime: nowMs, + DebugInfo: req.DebugInfo, + } + case entity.QrCodeTypeTemporary: + qrCodeInfo = &entity.QrCodeInfo{ + Type: entity.QrCodeTypeTemporary, + Uuid: GenTemporaryQrCodeUuid(req.AppId, entity.AppTempDefSequence), + AppId: req.AppId, + Sequence: entity.AppTempDefSequence, + ApiServer: req.ApiServer, + CodeId: "", + StartParams: appStartParams, + ExpireTime: nowMs + int64(config.GetConfig().QRcodeExpireTime*1e3), + CreateTime: nowMs, + DebugInfo: req.DebugInfo, + } + case entity.QrCodeTypeRomoteDebug: + qrCodeInfo = &entity.QrCodeInfo{ + Type: entity.QrCodeTypeRomoteDebug, + Uuid: GenRemoteDebugQrCodeUuid(req.AppId, entity.AppTempDefSequence), + AppId: req.AppId, + Sequence: entity.AppTempDefSequence, + ApiServer: req.ApiServer, + CodeId: "", + StartParams: appStartParams, + ExpireTime: nowMs + int64(config.GetConfig().QRcodeExpireTime*1e3), + CreateTime: nowMs, + DebugInfo: req.DebugInfo, + } + default: + return nil, errors.New("type err") + } + return qrCodeInfo, q.qrcodeRepo.Insert(ctx, qrCodeInfo) +} + +func (q *QrCodeInfoService) DeleteWechatQrcode(ctx context.Context, req apiproto.DeleteWechatInfoReq) error { + //wechatT := db.NewTable(db.TableWechatInfo) + //params := map[string]interface{}{"qrcodeUrl": "", "qrcodeDownloadUrl": "", "updated": time.Now().UnixNano() / 1e6} + //wechatT.UpdateOne(ctx, bson.M{"appId": req.AppId}, bson.M{"$set": params}) + //s.ResetWechatHint(ctx, req.AppId) + + err := hCaller.DeleteWechatQrcode(ctx, req) + if err != nil { + return err + } + return nil +} + +func (q *QrCodeInfoService) GetQrcodeInfo(ctx context.Context, uuid string) (*entity.QrCodeInfo, error) { + repo := impl.InitQrCodeInfoRepo() + info, err := repo.GetInfoByUuid(ctx, uuid) + if err != nil { + if repo.NotFound(err) { + return nil, entity.NotFoundErr + } + return nil, err + } + return info, nil +} + +func (q *QrCodeInfoService) UpdateTrialStartParams(ctx context.Context, codeId string, params entity.AppStartParams) error { + _, err := q.qrcodeRepo.GetInfoByCodeId(ctx, codeId) + if err != nil { + if !repository.NotFound(err) { + return err + } + buildInfo, err := q.buildInfoRepo.GetInfoById(ctx, codeId) + if err != nil { + return err + } + newQrcodeInfo := &entity.QrCodeInfo{ + Type: entity.QrCodeTypeTrial, + Uuid: GenTrialQrCodeUuid(buildInfo.AppID), + AppId: buildInfo.AppID, + Sequence: 0, + ApiServer: config.Cfg.ApiServer, + CodeId: codeId, + //todo ccc + StartParams: params, + CreateTime: utils.GetNowMs(), + } + err = q.qrcodeRepo.Insert(ctx, newQrcodeInfo) + if err != nil { + return err + } + } + return q.qrcodeRepo.UpdateTrialStartParams(ctx, codeId, params) +} + +func GenReviewQrCodeUuid(appId string, seq int) string { + s := utils.Gen16Md5(fmt.Sprintf("type=%s&appId=%s&sequence=%d", entity.QrCodeTypeReview, appId, seq)) + return UuidJoinFix(base64.RawURLEncoding.EncodeToString([]byte(s))) +} + +func GenReleaseQrCodeUuid(appId string) string { + s := utils.Gen16Md5(fmt.Sprintf("type=%s&appId=%s", entity.QrCodeTypeRelease, appId)) + return UuidJoinFix(base64.RawURLEncoding.EncodeToString([]byte(s))) +} + +func GenTrialQrCodeUuid(appId string) string { + s := utils.Gen16Md5(fmt.Sprintf("type=%s&appId=%s", entity.QrCodeTypeTrial, appId)) + return UuidJoinFix(base64.RawURLEncoding.EncodeToString([]byte(s))) +} + +func GenTemporaryQrCodeUuid(appId string, seq int) string { + s := utils.Gen16Md5(fmt.Sprintf("type=%s&appId=%s&sequence=%d", entity.QrCodeTypeTemporary, appId, seq)) + return UuidJoinFix(base64.RawURLEncoding.EncodeToString([]byte(s))) +} + +func GenRemoteDebugQrCodeUuid(appId string, seq int) string { + s := utils.Gen16Md5(fmt.Sprintf("type=%s&appId=%s&sequence=%d", entity.QrCodeTypeRomoteDebug, appId, seq)) + return UuidJoinFix(base64.RawURLEncoding.EncodeToString([]byte(s))) +} + +func UuidJoinFix(id string) string { + return qrcodePrefix + id + qrcodeSuffix +} diff --git a/domain/service/red_dot.go b/domain/service/red_dot.go new file mode 100644 index 0000000..d9b761f --- /dev/null +++ b/domain/service/red_dot.go @@ -0,0 +1,25 @@ +package service + +import ( + "context" +) + +//const ( +// RedDotTypePubApp = "pubApp" +// RedDotTypeTrialApp = "trialApp" +//) + +type RedDotService struct { +} + +func NewRedDotService() *RedDotService { + var s RedDotService + return &s +} + +func (s RedDotService) ReadTrialQr(ctx context.Context, id string, userId string) error { + return hCaller.ReadTrialQr(ctx, id, userId) + + //repo := impl.InitRedDotRepo() + //return repo.ReadTrialQr(ctx, RedDotTypeTrialApp, id, userId) +} diff --git a/domain/service/service.go b/domain/service/service.go new file mode 100644 index 0000000..47b4c06 --- /dev/null +++ b/domain/service/service.go @@ -0,0 +1,6 @@ +package service + +/** +* DDD: domain 领域层-service +* 领域服务(Domain Services): 一些行为无法归类到实体对象或值对象上,本质是一些操作,而非事物,命名开头是动词 +**/ diff --git a/domain/service/type_config.go b/domain/service/type_config.go new file mode 100644 index 0000000..87b5d9d --- /dev/null +++ b/domain/service/type_config.go @@ -0,0 +1,85 @@ +package service + +import ( + "context" + "finclip-app-manager/domain/entity" + impl "finclip-app-manager/infrastructure/db/repo" + "gitlab.finogeeks.club/finclip-backend/apm" + "time" +) + +func InitTypeConfig() { + span, ctx := apm.ApmClient().CreateLocalSpan(context.Background()) + span.Log(time.Now(), "config.Cfg.IsMOP init") + defer span.End() + repo := impl.InitTypeConfigRepo() + total, _, err := repo.GetAll(ctx) + if err != nil && !repo.NotFound(err) { + panic(err) + } + + if total == 0 { + for _, v := range entity.MopCfg { + err := repo.Insert(ctx, &v) + if err != nil { + log.Errorf("init type config err:%s", err.Error()) + break + } + } + return + } +} + +type TypeConfigService struct { +} + +func NewTypeConfigService() *TypeConfigService { + var s TypeConfigService + return &s +} + +func (s *TypeConfigService) GetTypeConfigList(ctx context.Context, pageSize int, pageNo int) (int, []entity.TypeConfig, error) { + repo := impl.InitTypeConfigRepo() + total, configs, err := repo.GetSome(ctx, pageSize, pageNo) + + if repo.NotFound(err) { + return 0, []entity.TypeConfig{}, nil + } + + return total, configs, err +} + +func (s *TypeConfigService) GetAllTypeConfigList(ctx context.Context) (int, []entity.TypeConfig, error) { + repo := impl.InitTypeConfigRepo() + total, configs, err := repo.GetAll(ctx) + if repo.NotFound(err) { + return 0, []entity.TypeConfig{}, nil + } + + return total, configs, err +} + +func (s *TypeConfigService) Exist(ctx context.Context, namespace string, value string) (bool, error) { + repo := impl.InitTypeConfigRepo() + return repo.Exist(ctx, namespace, value) +} + +func (s *TypeConfigService) GetNowSortNumInfo(ctx context.Context) (*entity.TypeConfig, error) { + repo := impl.InitTypeConfigRepo() + return repo.GetNowSortNumInfo(ctx) +} + +func (s *TypeConfigService) Insert(ctx context.Context, typeConfig *entity.TypeConfig) error { + repo := impl.InitTypeConfigRepo() + return repo.Insert(ctx, typeConfig) +} + +func (s *TypeConfigService) Delete(ctx context.Context, typeConfigId string) error { + repo := impl.InitTypeConfigRepo() + return repo.Delete(ctx, typeConfigId) +} + +func (s *TypeConfigService) NotFound(err error) bool { + repo := impl.InitTypeConfigRepo() + return repo.NotFound(err) +} diff --git a/domain/value-object/value_object.go b/domain/value-object/value_object.go new file mode 100644 index 0000000..aaf5545 --- /dev/null +++ b/domain/value-object/value_object.go @@ -0,0 +1,6 @@ +package valueObject + +/** +* DDD: domain 领域层-值对象 +* 值对象(Value Objects): 无需唯一标识的对象。 +**/ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..afbcd16 --- /dev/null +++ b/go.mod @@ -0,0 +1,44 @@ +module finclip-app-manager + +require ( + github.com/Chain-Zhang/pinyin v0.1.3 + github.com/Shopify/sarama v1.24.1 + github.com/SkyAPM/go2sky v0.5.0 + github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0 + github.com/bitly/go-simplejson v0.5.0 + github.com/bluele/gcache v0.0.2 + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/bsm/sarama-cluster v2.1.15+incompatible + github.com/caarlos0/env/v6 v6.3.0 + github.com/garyburd/redigo v1.6.0 + github.com/gin-gonic/gin v1.7.1 + github.com/go-redis/redis/v8 v8.11.3 + github.com/go-resty/resty/v2 v2.7.0 + github.com/golang/protobuf v1.5.2 // indirect + github.com/gomodule/redigo v2.0.0+incompatible // indirect + github.com/gorilla/mux v1.7.3 // indirect + github.com/hashicorp/consul/api v1.7.0 + github.com/jinzhu/copier v0.3.5 + github.com/mbobakov/grpc-consul-resolver v1.4.3 + github.com/openzipkin/zipkin-go v0.2.2 + github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.4.0 + github.com/satori/go.uuid v1.2.0 + github.com/tealeg/xlsx v1.0.5 + github.com/xdg-go/scram v1.1.1 + github.com/zzfup/go-fetch v1.0.1 + gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo v1.0.1 + gitlab.finogeeks.club/finclip-backend-v2/finclip-redis v0.0.0-20210723095205-13a1cd72e5d4 + gitlab.finogeeks.club/finclip-backend/apm v0.2.4 + gitlab.finogeeks.club/finclip-backend/mop-middleware-auth v0.1.23 + gitlab.finogeeks.club/finclip-backend/rmconf v0.1.1 + golang.org/x/text v0.3.7 // indirect + google.golang.org/grpc v1.29.1 + google.golang.org/protobuf v1.27.1 + gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 + gorm.io/driver/mysql v1.2.3 + gorm.io/gorm v1.22.5 +) + +go 1.13 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..97dd376 --- /dev/null +++ b/go.sum @@ -0,0 +1,538 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Chain-Zhang/pinyin v0.1.3 h1:RzErNyNwVa8z2sOLCuXSOtVdY/AsARb8mBzI2p2qtnE= +github.com/Chain-Zhang/pinyin v0.1.3/go.mod h1:5iHpt9p4znrnaP59/hfPMnAojajkDxQaP9io+tRMPho= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.24.1 h1:svn9vfN3R1Hz21WR2Gj0VW9ehaDGkiOS+VqlIcZOkMI= +github.com/Shopify/sarama v1.24.1/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/SkyAPM/go2sky v0.5.0 h1:9RDBQviaeazG7PJMLLnMcU4U++PORbqEls4ix4OEgQw= +github.com/SkyAPM/go2sky v0.5.0/go.mod h1:TANzYw5EvIlTidGWvQxtvO87rM6C746HkM0xkWqnPQw= +github.com/SkyAPM/go2sky-plugins/gin/v3 v3.0.0-20200929011259-46b345515dcd/go.mod h1:PJOl29eK8/DkEva1PozhZDqMDHFbVY89mas9L8rbiwQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0 h1:BVts5dexXf4i+JX8tXlKT0aKoi38JwTXSe+3WUneX0k= +github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0/go.mod h1:FDIQmoMNJJl5/k7upZEnGvgWVZfFeE6qHeN7iCMbCsA= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.2 h1:EyUnxyP2yaGpLgMiuyyz8sHnByqeTJUfGs72pdH0i4A= +github.com/armon/go-metrics v0.3.2/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= +github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bsm/sarama-cluster v2.1.15+incompatible h1:RkV6WiNRnqEEbp81druK8zYhmnIgdOjqSVi0+9Cnl2A= +github.com/bsm/sarama-cluster v2.1.15+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= +github.com/caarlos0/env/v6 v6.3.0 h1:PaqGnS5iHScZ5SnZNBPvQbA2VE/eMAwlp51mKGuEZLg= +github.com/caarlos0/env/v6 v6.3.0/go.mod h1:nXKfztzgWXH0C5Adnp+gb+vXHmMjKdBnMrSVSczSkiw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/frankban/quicktest v1.10.2 h1:19ARM85nVi4xH7xPXuc5eM/udya5ieh7b/Sv+d844Tk= +github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= +github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/form v3.1.4+incompatible h1:lvKiHVxE2WvzDIoyMnWcjyiBxKt2+uFJyZcPYWsLnjI= +github.com/go-playground/form v3.1.4+incompatible/go.mod h1:lhcKXfTuhRtIZCIKUeJ0b5F207aeQCPbZU09ScKjwWg= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= +github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8= +github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.7.0 h1:tGs8Oep67r8CcA2Ycmb/8BLBcJ70St44mF2X10a/qPg= +github.com/hashicorp/consul/api v1.7.0/go.mod h1:1NSuaUUkFaJzMasbfq/11wKYWSR67Xn6r2DXKhuDNFg= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.6.0 h1:FfhMEkwvQl57CildXJyGHnwGGM4HMODGyfjGwNM1Vdw= +github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.1.0 h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc= +github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= +github.com/hashicorp/serf v0.9.3 h1:AVF6JDQQens6nMHT9OGERBvK0f8rPrAGILnsKLr6lzM= +github.com/hashicorp/serf v0.9.3/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= +github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbobakov/grpc-consul-resolver v1.4.3 h1:jnwggRTBeSg8QtAc1cQcFUmBo6FGPSWOV3LTxU1Bhgc= +github.com/mbobakov/grpc-consul-resolver v1.4.3/go.mod h1:4XagwDYAljLu9tulY7bKuynGZgrx5siDRRlrdU5d3yg= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= +github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zzfup/go-fetch v1.0.1 h1:K6kaDv4Asp6zTMsKJZbY4OdgjgXS9D1JHMlmVyS3yiA= +github.com/zzfup/go-fetch v1.0.1/go.mod h1:HJgl/egXQ5uBAsuvdUeuOkminiCzlA1Of1wJuN30cU4= +gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo v1.0.1 h1:GBQQxSdr1L4vvPnplmYa7/ZW/BHpRrdtP7qd5wMqMrs= +gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo v1.0.1/go.mod h1:MKzEpaTj8iVHHbkvdVryKgVc+yYNlu0ccWvc5ERjgTE= +gitlab.finogeeks.club/finclip-backend-v2/finclip-redis v0.0.0-20210723095205-13a1cd72e5d4 h1:5TIEQFaTRoZac7X/2ZeSBzswJFtgDrSvArknEQgn+/c= +gitlab.finogeeks.club/finclip-backend-v2/finclip-redis v0.0.0-20210723095205-13a1cd72e5d4/go.mod h1:kEPGV2TGliSBEWGPHMw/V+1Kjj6Ls9gCKpXuUCFBvbw= +gitlab.finogeeks.club/finclip-backend/apm v0.2.4 h1:tWroZ500nXoGrxppJqtuGMTM5rBHADWn/DcPIOJV53g= +gitlab.finogeeks.club/finclip-backend/apm v0.2.4/go.mod h1:Qpl3kqAC1ZhoEOH0nwDiwycOCRlZvchlxOQeOyFYy4Q= +gitlab.finogeeks.club/finclip-backend/mop-middleware-auth v0.1.23 h1:wTv1YT1jaLZyW1CMQUuKjqXayFSicCZ4GRtFJOUQSmQ= +gitlab.finogeeks.club/finclip-backend/mop-middleware-auth v0.1.23/go.mod h1:tK4vYEMCvbr9h5Hx1HKK1yB59GbUbTfnCBZpzA+T22o= +gitlab.finogeeks.club/finclip-backend/rmconf v0.1.1 h1:gyVCjtA9OarRVrqJ9+kqmVPpCOHbQf0iPuWnja46MsY= +gitlab.finogeeks.club/finclip-backend/rmconf v0.1.1/go.mod h1:RORGCrEwiuSRJF6VFWvEniHlhd0HQ8lgLgB4xj/TBC0= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181010134911-4d1c5fb19474/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200210034751-acff78025515/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.2.3 h1:cZqzlOfg5Kf1VIdLC1D9hT6Cy9BgxhExLj/2tIgUe7Y= +gorm.io/driver/mysql v1.2.3/go.mod h1:qsiz+XcAyMrS6QY+X3M9R6b/lKM1imKmcuK9kac5LTo= +gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk= +gorm.io/gorm v1.22.5 h1:lYREBgc02Be/5lSCTuysZZDb6ffL2qrat6fg9CFbvXU= +gorm.io/gorm v1.22.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/infrastructure/cache/mem/mem.go b/infrastructure/cache/mem/mem.go new file mode 100644 index 0000000..dd6bd1a --- /dev/null +++ b/infrastructure/cache/mem/mem.go @@ -0,0 +1,33 @@ +package mem + +import ( + "time" + + "github.com/bluele/gcache" +) + +//如果不够用修改100000 +var memCache gcache.Cache = gcache.New(100000).LRU().Build() + +type MemCache struct { + c gcache.Cache +} + +func NewMemCache() *MemCache { + return &MemCache{ + c: memCache, + } +} + +func (m *MemCache) Set(k string, v interface{}, d time.Duration) { + m.c.SetWithExpire(k, v, d) +} + +func (m *MemCache) Get(k string) (interface{}, bool) { + v, err := m.c.Get(k) + if err == nil { + return v, true + } + + return v, false +} diff --git a/infrastructure/cache/redis/redis.go b/infrastructure/cache/redis/redis.go new file mode 100644 index 0000000..a80dd5c --- /dev/null +++ b/infrastructure/cache/redis/redis.go @@ -0,0 +1,175 @@ +package redis + +import ( + "context" + "finclip-app-manager/infrastructure/config" + "strings" + "time" + + "github.com/SkyAPM/go2sky" + "github.com/garyburd/redigo/redis" + goRedis "github.com/go-redis/redis/v8" + fcredis "gitlab.finogeeks.club/finclip-backend-v2/finclip-redis" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +const ( + MODE_SINGLE = "single" + MODE_SENTINEL = "sentinel" + MODE_SENTINEL_V2 = "sentinel_v2" + MODE_CLUSTER = "cluster" + MODE_CLUSTER_V2 = "cluster_v2" +) + +func init() { + RedisStart() +} + +func RedisStart() { + cfg := config.GetConfig() + switch cfg.RedisMode { + case "single": + opt, err := goRedis.ParseURL(cfg.RedisAddr) + if err != nil { + panic(err) + } + opt.Password = cfg.RedisPassword + err = fcredis.Init("single", opt) + if err != nil { + panic(err) + } + case "sentinel", "sentinel_v2": + opt := &goRedis.FailoverOptions{ + SentinelAddrs: strings.Split(cfg.RedisSentinelAddr, ","), + SentinelPassword: cfg.RedisSentinelPassword, + MasterName: cfg.RedisMasterName, + DB: cfg.RedisDatabase, + } + if err := fcredis.Init("sentinel", opt); err != nil { + panic(err) + } + case "cluster", "cluster_v2": + opt := &goRedis.ClusterOptions{ + Addrs: strings.Split(cfg.RedisAddr, ","), + Password: cfg.RedisPassword, + } + if err := fcredis.Init("cluster", opt); err != nil { + panic(err) + } + } + return +} + +func createRedisSpan(ctx context.Context, action string) go2sky.Span { + switch config.GetConfig().RedisMode { + case MODE_SENTINEL_V2: + span := apm.ApmClient().CreateRedisExitSpan(ctx, action, + config.GetConfig().RedisSentinelAddr, "") + span.Log(time.Now(), "Mode", config.GetConfig().RedisMode) + span.Log(time.Now(), "MasterName", config.GetConfig().RedisMasterName) + return span + case MODE_CLUSTER: + span := apm.ApmClient().CreateRedisExitSpan(ctx, action, + config.GetConfig().RedisAddr, "") + span.Log(time.Now(), "Mode", config.GetConfig().RedisMode) + return span + case MODE_CLUSTER_V2: + span := apm.ApmClient().CreateRedisExitSpan(ctx, action, + config.GetConfig().RedisAddr, "") + span.Log(time.Now(), "Mode", config.GetConfig().RedisMode) + return span + default: + if config.GetConfig().RedisMode == MODE_SENTINEL { + span := apm.ApmClient().CreateRedisExitSpan(ctx, action, + config.GetConfig().RedisSentinelAddr, "") + span.Log(time.Now(), "Mode", config.GetConfig().RedisMode) + span.Log(time.Now(), "MasterName", config.GetConfig().RedisMasterName) + return span + } else { + span := apm.ApmClient().CreateRedisExitSpan(ctx, action, + config.GetConfig().RedisAddr, "") + span.Log(time.Now(), "Mode", config.GetConfig().RedisMode) + return span + } + } +} + +func RedisSet(ctx context.Context, key string, value string, expireTime int) (err error) { + span := createRedisSpan(ctx, "RedisSet") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Set(ctx, "finclip_"+key, value, time.Duration(expireTime)*time.Second).Err() +} + +func RedisGet(ctx context.Context, key string) (s string, err error) { + span := createRedisSpan(ctx, "RedisGet") + span.Log(time.Now(), "key", key) + return fcredis.Client().Get(ctx, "finclip_"+key).Result() +} + +func RedisGetNum(ctx context.Context, key string) (s int, err error) { + span := createRedisSpan(ctx, "RedisGet") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Get(ctx, "finclip_"+key).Int() +} + +func RedisDel(ctx context.Context, key string) (err error) { + span := createRedisSpan(ctx, "RedisDel") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Del(ctx, "finclip_"+key).Err() +} + +func Setnx(ctx context.Context, key string, value string, expireTime int) (exi bool, err error) { + span := createRedisSpan(ctx, "Setnx") + span.Log(time.Now(), "key", key) + defer span.End() + notExi, err := fcredis.Client().SetNX(ctx, "finclip_"+key, value, time.Duration(expireTime)*time.Second).Result() + return !notExi, err +} + +func RedisSetByte(ctx context.Context, key string, value []byte, expireTime int) (err error) { + span := createRedisSpan(ctx, "RedisSetByte") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Set(ctx, "finclip_"+key, value, time.Duration(expireTime)*time.Second).Err() +} + +func RedisGetByte(ctx context.Context, key string) (bytes []byte, err error) { + span := createRedisSpan(ctx, "RedisGetByte") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Get(ctx, "finclip_"+key).Bytes() +} + +func RedisSetExpire(ctx context.Context, key string, sec int) (err error) { + span := createRedisSpan(ctx, "RedisSetExpire") + span.Log(time.Now(), "key", key) + defer span.End() + return fcredis.Client().Expire(ctx, "finclip_"+key, time.Duration(sec)*time.Second).Err() +} + +func RedisIncrValue(ctx context.Context, key string) (value int, err error) { + span := createRedisSpan(ctx, "RedisIncrValue") + span.Log(time.Now(), "key", key) + result, err := fcredis.Client().Incr(ctx, "finclip_"+key).Result() + return int(result), err + +} + +func RedisGetIntValue(ctx context.Context, key string) (val int, err error) { + return fcredis.Client().Get(ctx, "finclip_"+key).Int() +} + +func TryLock(ctx context.Context, key string, lockTime time.Duration) (ok bool, err error) { + return fcredis.Lock(ctx, "finclip_"+key, lockTime*time.Second) +} + +func Unlock(ctx context.Context, key string) error { + return fcredis.Client().Del(ctx, "finclip_"+key).Err() +} + +func RedisNotFound(err error) bool { + return err == goRedis.Nil || err == redis.ErrNil +} diff --git a/infrastructure/client/grpc/grpc.go b/infrastructure/client/grpc/grpc.go new file mode 100644 index 0000000..e8c1393 --- /dev/null +++ b/infrastructure/client/grpc/grpc.go @@ -0,0 +1,122 @@ +package grpc + +import ( + "errors" + pb "finclip-app-manager/infrastructure/protobuf/golang" + "finclip-app-manager/infrastructure/utility" + "fmt" + "sync" + "sync/atomic" + "unsafe" + + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + + _ "github.com/mbobakov/grpc-consul-resolver" +) + +var ( + grpcConnectManager GrpcConnectManager + initOnce sync.Once +) + +func GetGrpcConnManager() *GrpcConnectManager { + initOnce.Do(func() { + grpcConnectManager.GrpcConnectItemMap = make(map[string]GrpcConnectItem) + }) + + return &grpcConnectManager +} + +type GrpcConnectItem struct { //单个连接建立,例如:和账号系统多实例连接上,一个item可以理解为对应一个mop服务多实例的连接 + ClientConn unsafe.Pointer + ServerName string +} + +type GrpcConnectManager struct { + CreateLock sync.Mutex //防止多协程同时建立连接 + GrpcConnectItemMap map[string]GrpcConnectItem //一开始是空 +} + +//param是指url的参数,例如:wait=10s&tag=mop,代表这个连接超时10秒建立,consul的服务tag是mop +func (g *GrpcConnectManager) GetConn(consulUrl, server, param string) (*grpc.ClientConn, error) { + if connItem, ok := g.GrpcConnectItemMap[server]; ok { //first check + if atomic.LoadPointer(&connItem.ClientConn) != nil { + return (*grpc.ClientConn)(connItem.ClientConn), nil + } + } + + g.CreateLock.Lock() + defer g.CreateLock.Unlock() + + fmt.Println("GetConn lock") + connItem, ok := g.GrpcConnectItemMap[server] + if ok { //double check + if atomic.LoadPointer(&connItem.ClientConn) != nil { + cc := (*grpc.ClientConn)(connItem.ClientConn) + if g.checkState(cc) == nil { + return cc, nil + } else { //旧的连接存在服务端断开的情况,需要先关闭 + cc.Close() + } + } + } + + target := "consul://" + consulUrl + "/" + server + if param != "" { + target += "?" + param + } + + fmt.Println("new conn, url=" + target) + cli, err := g.newGrpcConn(target) + if err != nil { + return nil, err + } + + var newItem GrpcConnectItem + newItem.ServerName = server + + atomic.StorePointer(&newItem.ClientConn, unsafe.Pointer(cli)) + g.GrpcConnectItemMap[server] = newItem + + return cli, nil +} + +func (g *GrpcConnectManager) checkState(conn *grpc.ClientConn) error { + state := conn.GetState() + switch state { + case connectivity.TransientFailure, connectivity.Shutdown: + return errors.New("ErrConn") + } + + return nil +} + +func (g *GrpcConnectManager) newGrpcConn(target string) (*grpc.ClientConn, error) { + conn, err := grpc.Dial( + target, + //grpc.WithBlock(), + grpc.WithInsecure(), + grpc.WithBalancerName("round_robin"), + //grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`), + ) + if err != nil { + return nil, err + } + + return conn, nil +} + +func MakeGrpcCommonResult(httpStatus int, errCode string, result **pb.CommonResult) { + *result = &pb.CommonResult{} + (*result).Error = utility.GetErrMsg(errCode) + (*result).Errcode = errCode + (*result).Httpcode = int32(httpStatus) +} + +func MakeGrpcCommonResultNoLoc(httpStatus int, errCode, errmsg string, result **pb.CommonResult) { + *result = &pb.CommonResult{} + (*result).Error = errmsg + (*result).Errcode = errCode + (*result).Httpcode = int32(httpStatus) +} diff --git a/infrastructure/client/grpc/mop_account_system.go b/infrastructure/client/grpc/mop_account_system.go new file mode 100644 index 0000000..6b0e345 --- /dev/null +++ b/infrastructure/client/grpc/mop_account_system.go @@ -0,0 +1,41 @@ +package grpc + +import ( + "context" + "errors" + "finclip-app-manager/infrastructure/config" + pb "finclip-app-manager/infrastructure/protobuf/golang" +) + +func GetGroupInfoByGroupId(ctx context.Context, organId string) (*pb.GetBusinessInfoByIdRsp_DATA, error) { + var rsp *pb.GetBusinessInfoByIdRsp + var err error + for i := 0; i < 2; i++ { + conn, err1 := GetGrpcConnManager().GetConn(config.GetConfig().ConsulAddr, "mop-account-system", "tag="+config.GetConfig().ConsulTag) + if err1 != nil { + err = err1 + continue + } + c := pb.NewMopAccountSystemClient(conn) + var req pb.GetBusinessInfoByIdReq + req.OrganTraceId = organId + rsp, err = c.GetBusinessInfoById(ctx, &req) + if err != nil { + log.Errorf("err=%s", err.Error()) + continue + } else { + err = nil + break + } + } + + if err != nil { + return nil, err + } + + if rsp.Result.Httpcode != 200 { + return nil, errors.New(rsp.Result.Error) + } + + return rsp.Data, nil +} diff --git a/infrastructure/client/grpc/mop_applet_build_manager.go b/infrastructure/client/grpc/mop_applet_build_manager.go new file mode 100644 index 0000000..c274cf2 --- /dev/null +++ b/infrastructure/client/grpc/mop_applet_build_manager.go @@ -0,0 +1,42 @@ +package grpc + +import ( + "context" + "errors" + "finclip-app-manager/infrastructure/config" + pb "finclip-app-manager/infrastructure/protobuf/golang" +) + +func GetSdkVerEncrypted(ctx context.Context, sdkVer string) (bool, error) { + + var rsp *pb.QueryEncryptedRsp + var err error + for i := 0; i < 2; i++ { + conn, err1 := GetGrpcConnManager().GetConn(config.GetConfig().ConsulAddr, "mop-applet-build-manager", "tag="+config.GetConfig().ConsulTag) + if err1 != nil { + err = err1 + continue + } + c := pb.NewMopAppletBuildMangerClient(conn) + var req pb.QueryEncryptedReq + req.SdkVersion = sdkVer + rsp, err = c.QueryEncrypted(ctx, &req) + if err != nil { + log.Errorf("err=%s", err.Error()) + continue + } else { + err = nil + break + } + } + + if err != nil { + return false, err + } + + if rsp.Result.Httpcode != 200 { + return false, errors.New(rsp.Result.Error) + } + + return rsp.Data.Encrypted, nil +} diff --git a/infrastructure/client/grpc/mop_domain_manager.go b/infrastructure/client/grpc/mop_domain_manager.go new file mode 100644 index 0000000..c1d843c --- /dev/null +++ b/infrastructure/client/grpc/mop_domain_manager.go @@ -0,0 +1,74 @@ +package grpc + +import ( + "context" + "errors" + "finclip-app-manager/infrastructure/config" + pb "finclip-app-manager/infrastructure/protobuf/golang" +) + +func GetDomainInfo(ctx context.Context, appId string) (*pb.GetAllDomainInternalRsp_DATA, error) { + var rsp *pb.GetAllDomainInternalRsp + var err error + for i := 0; i < 2; i++ { + conn, err1 := GetGrpcConnManager().GetConn(config.GetConfig().ConsulAddr, "mop-domain-manager", "tag="+config.GetConfig().ConsulTag) + if err1 != nil { + err = err1 + continue + } + c := pb.NewMopDomainManagerClient(conn) + var req pb.GetAllDomainInternalReq + req.AppId = appId + rsp, err = c.GetAllDomainInternal(ctx, &req) + if err != nil { + log.Errorf("err=%s", err.Error()) + continue + } else { + err = nil + break + } + } + + if err != nil { + return nil, err + } + + if rsp.Result.Httpcode != 200 { + return nil, errors.New(rsp.Result.Error) + } + + return rsp.Data, nil +} + +func GetDomainInfoV2(ctx context.Context, organId string) (*pb.GetAllDomainInternalV2Rsp_DATA, error) { + var rsp *pb.GetAllDomainInternalV2Rsp + var err error + for i := 0; i < 2; i++ { + conn, err1 := GetGrpcConnManager().GetConn(config.GetConfig().ConsulAddr, "mop-domain-manager", "tag="+config.GetConfig().ConsulTag) + if err1 != nil { + err = err1 + continue + } + c := pb.NewMopDomainManagerClient(conn) + var req pb.GetAllDomainInternalV2Req + req.OrganId = organId + rsp, err = c.GetAllDomainInternalV2(ctx, &req) + if err != nil { + log.Errorf("err=%s", err.Error()) + continue + } else { + err = nil + break + } + } + + if err != nil { + return nil, err + } + + if rsp.Result.Httpcode != 200 { + return nil, errors.New(rsp.Result.Error) + } + + return rsp.Data, nil +} diff --git a/infrastructure/client/grpc/mop_purchasing_rights_manager.go b/infrastructure/client/grpc/mop_purchasing_rights_manager.go new file mode 100644 index 0000000..f9a15c1 --- /dev/null +++ b/infrastructure/client/grpc/mop_purchasing_rights_manager.go @@ -0,0 +1,42 @@ +package grpc + +import ( + "context" + "errors" + "finclip-app-manager/infrastructure/config" + pb "finclip-app-manager/infrastructure/protobuf/golang" +) + +func PurchasingGetIdStatus(ctx context.Context, id string) (int, error) { + rsp := &pb.QueryBusinessStatusRsp{} + var err error + for i := 0; i < 2; i++ { + conn, err1 := GetGrpcConnManager().GetConn(config.GetConfig().ConsulAddr, "mop-purchasing-rights-manager", "tag="+config.GetConfig().ConsulTag) + if err1 != nil { + err = err1 + continue + } + c := pb.NewMopPurchasingRightsManagerClient(conn) + req := pb.QueryBusinessStatusReq{} + req.BusinessId = id + rsp, err = c.QueryBusinessStatus(ctx, &req) + if err != nil { + log.Errorf("PurchasingGetIdStatus err=%s", err.Error()) + continue + } else { + err = nil + break + } + } + + if err != nil { + return 0, err + } + + if rsp.Result.Httpcode != 200 { + log.Errorf("PurchasingGetIdStatus status code err:%+v", rsp) + return 0, errors.New(rsp.Result.Error) + } + log.Debugf("PurchasingGetIdStatus rsp:%+v", rsp) + return int(rsp.Data.Status), nil +} diff --git a/infrastructure/client/grpc/public.go b/infrastructure/client/grpc/public.go new file mode 100644 index 0000000..7599fad --- /dev/null +++ b/infrastructure/client/grpc/public.go @@ -0,0 +1,7 @@ +package grpc + +import "finclip-app-manager/infrastructure/logger" + +var ( + log = logger.GetLogger() +) diff --git a/infrastructure/client/httpcall/account.go b/infrastructure/client/httpcall/account.go new file mode 100644 index 0000000..dfe0d33 --- /dev/null +++ b/infrastructure/client/httpcall/account.go @@ -0,0 +1,386 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "fmt" + "gopkg.in/mgo.v2/bson" + "net/http" +) + +type GroupIDData struct { + GroupID string `json:"groupId"` + GroupName string `json:"groupName"` + ReviewStatus int `json:"reviewStatus"` + SocialCreditCode string `json:"socialCreditCode"` + AdminAccountId string `json:"AdminAccountId"` +} + +type GetGroupIDResponse struct { + ErrInfo + Data GroupIDData `json:"data"` +} + +func (c *Client) GetGroupInfoByUserId(ctx context.Context, userId string) (*GroupIDData, error) { + url := config.GetConfig().AccountProviderURL + userId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetGroupInfoByUserId err:%s", err.Error()) + return nil, err + } + result := GetGroupIDResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetGroupInfoByUserId err:%s", err.Error()) + return nil, err + } + log.Infof("GetGroupInfoByUserId rsp:%+v", result) + if result.Errcode != "OK" { + log.Errorf("GetGroupInfoByUserId result errcode err:%+v", result) + return nil, errors.New("errcode invalid") + } + return &result.Data, nil +} + +func (c *Client) GetGroupInfoByGroupId(ctx context.Context, groupId string) (*GroupIDData, error) { + urlPrefix := config.Cfg.GroupInfoProviderURL + url := urlPrefix + groupId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetGroupInfoByGroupId err:%s", err.Error()) + return nil, err + } + result := GetGroupIDResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetGroupInfoByGroupId err:%s", err.Error()) + return nil, err + } + log.Infof("GetGroupInfoByGroupId rsp:%+v", result) + if result.Errcode != "OK" { + log.Errorf("GetGroupInfoByGroupId result errcode err:%+v", result) + return nil, errors.New("errcode invalid") + } + return &result.Data, nil +} + +type AccountInfoData struct { + Account string `json:"account"` + Name string `json:"name"` + Identity string `json:"identity"` + Phone string `json:"phone"` + Email string `json:"email"` + OrganId string `json:"organId"` +} + +type GetAccountInfoResponse struct { + ErrInfo + Data AccountInfoData `json:"data"` +} + +func (c *Client) GetAccountInfo(ctx context.Context, accountId string) (*AccountInfoData, error) { + url := config.Cfg.AccountInfoURL + h := c.getNewDefaultReqHeader() + h["X-Consumer-Custom-ID"] = accountId + rsp, err := c.Request(ctx).SetHeaders(h).Get(url) + if err != nil { + log.Errorf("GetAccountInfo err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetAccountInfo http status err:%+v", rsp.Body()) + return nil, errors.New("http status err") + } + result := GetAccountInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetAccountInfo unmarshal err:%s,rsp:%s", err.Error(), rsp.Body()) + return nil, err + } + log.Infof("GetAccountInfo rsp:%+v", result) + return &result.Data, nil +} + +func (c *Client) GetAccountInfoByAccount(ctx context.Context, account string) (*AccountInfoData, error) { + url := fmt.Sprintf(config.Cfg.AccountSearchURL+"?account=%s", account) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetAccountInfoByAccount err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetAccountInfoByAccount http code not ok,rsp:%s", rsp.String()) + return nil, errors.New(ErrHttpCode) + } + resp := GetAccountInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal response to GetAccountInfoResponse, error: %v", err) + return nil, err + } + return &resp.Data, nil +} + +//获取运营端账号信息 +type AdminAccountInfo struct { + Account string `json:"account"` + Name string `json:"name"` +} + +type AdminAccountInfoData struct { + Info AdminAccountInfo `json:"info"` +} +type GetAdminAccountInfoResponse struct { + ErrInfo + Data AdminAccountInfoData `json:"data"` +} + +func (c *Client) GetAdminAccountInfo(ctx context.Context, accountId string) (*AdminAccountInfo, error) { + url := config.Cfg.AdminAccountInfoUrl + accountId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetAdminAccountInfo fetch err:%s", err.Error()) + return nil, err + } else if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetAdminAccountInfo StatusCode err,body:%s", string(rsp.Body())) + return nil, errors.New("http status err") + } + resp := GetAdminAccountInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal response to GetAdminAccountInfo Response, error: %v", err) + return nil, err + } + return &resp.Data.Info, nil +} + +type AddLimitInfoReq struct { + Type string `json:"type"` + OrganId string `json:"organId"` + AddNum int `json:"addNum"` +} +type AddLimitInfoRsp struct { + ErrInfo + Data map[string]interface{} `json:"data"` +} + +func (c *Client) AddLimitInfo(ctx context.Context, n *AddLimitInfoReq) (int, *AddLimitInfoRsp, error) { + url := config.Cfg.AddLimitInfoURL + log.Infof("AddLimitInfo info:%+v,url:%s", n, url) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(n).Post(url) + if err != nil { + log.Errorf("AddLimitInfo request err:%s", err.Error()) + return http.StatusInternalServerError, nil, err + } + resp := &AddLimitInfoRsp{} + if rsp.StatusCode() != http.StatusOK { + log.Errorf("AddLimitInfo status code no ok,rsp:%s", rsp.Body()) + return rsp.StatusCode(), nil, errors.New("status code err") + } + return http.StatusOK, resp, nil +} + +type RoleData struct { + IsOK bool `json:"isOK"` +} + +type RoleResponse struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data RoleData `json:"data"` +} + +func (c *Client) HasRole(ctx context.Context, userID string) (bool, *RoleResponse, error) { + url := fmt.Sprintf(config.Cfg.GetRoleURL+"%s", userID) + rsp, err := c.Request(ctx).Get(url) + if err != nil { + log.Errorf("HasRole err:%s", err.Error()) + return false, nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("HasRole http code err,rsp:%+v", rsp.String()) + return false, nil, errors.New(ErrHttpCode) + } + resp := RoleResponse{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal roleResponse: %v\n", err) + return false, nil, errors.New(ErrSystemCall) + } + if resp.Data.IsOK { + return true, nil, nil + } + return false, &resp, nil +} + +type OrganListItem struct { + ID bson.ObjectId `json:"id,omitempty" ` //唯一id + Name string `json:"name" ` //企业名称 + Account string `json:"account" ` //企业账户 + AccountStatus int `json:"accountStatus"` //企业状态 1-审核中 2-未认证 3-已认证 4-已过期 5-已冻结 + SocialCreditCode string `json:"socialCreditCode"` //社会统一信用代码 + LicenseNetdiskId string `json:"licenseNetdiskId"` //资格证书 + OrganRoleType string `json:"organRoleType"` + AuthorizationNetdiskId string `json:"authorizationNetdiskId"` //授权书 + ExpireDate int64 `json:"expireDate"` //过期时间 动态生成 + OrganId string `json:organId` + DelayTime int64 `json:"delayTime" bson:"delayTime"` //延期时间 + CreateTime int64 `json:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime"` //更新时间 +} + +type OrganListData struct { + Total int `json:"total"` + List []*OrganListItem `json:"list"` +} + +type OrganListResp struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data OrganListData `json:"data"` +} + +func (c *Client) GetOrganList(ctx context.Context) ([]*OrganListItem, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + url := fmt.Sprintf("%s?page=%d&num=%d", config.Cfg.OrganListURL, 1, 1000) + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetOrganList err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetOrganList http code err,rsp:%+v", rsp.String()) + return nil, errors.New(ErrHttpCode) + } + resp := OrganListResp{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal OrganListResp: %v\n", err) + return nil, errors.New(ErrSystemCall) + } + if resp.Errcode != utility.OK { + log.Errorf("GetOrganList errCode:%s", resp.Errcode) + return nil, errors.New(ErrSystemCall) + } + return resp.Data.List, nil +} + +type BindLimitInfo struct { + LimitNum int `bson:"limitNum"` + HasUseNum int `bson:"hasUseNum"` + UpMember string `bson:"upMember"` + UpTimestamp int64 `bson:"upTimestamp"` + CreateBinding int `bson:"createBinding"` +} + +type BindLimitResp struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data BindLimitInfo `json:"data"` +} + +func (c *Client) GetBindLimitInfo(ctx context.Context, accountId string) (*BindLimitInfo, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "X-Consumer-Custom-ID": accountId, + } + url := config.Cfg.BindLimitURL + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetBindLimitInfo err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetBindLimitInfo http code err,rsp:%+v", rsp.String()) + return nil, errors.New(ErrHttpCode) + } + resp := BindLimitResp{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal GetBindLimitInfo: %v\n", err) + return nil, errors.New(ErrSystemCall) + } + if resp.Errcode != utility.OK { + log.Errorf("GetBindLimitInfo errCode:%s", resp.Errcode) + return nil, errors.New(ErrSystemCall) + } + return &resp.Data, nil +} + +type IsAdminRsp struct { + IsAdmin bool `json:"isAdmin"` + OrganId string `json:"organId"` +} + +type GetIsOrganAdminResp struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data IsAdminRsp `json:"data"` +} + +func (c *Client) GetIsOrganAdmin(ctx context.Context, phone string) (*IsAdminRsp, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + url := fmt.Sprintf("%s?phone=%s", config.Cfg.GetIsOrganAdminURL, phone) + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetIsOrganAdmin err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetIsOrganAdmin http code err,rsp:%+v", rsp.String()) + return nil, errors.New(ErrHttpCode) + } + resp := GetIsOrganAdminResp{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal GetIsOrganAdmin: %v\n", err) + return nil, errors.New(ErrSystemCall) + } + if resp.Errcode != utility.OK { + log.Errorf("GetIsOrganAdmin errCode:%s", resp.Errcode) + return nil, errors.New(ErrSystemCall) + } + return &resp.Data, nil +} + +type IsCreatorRsp struct { + IsCreator bool `json:"isCreator"` + OrganId string `json:"organId"` +} + +type GetIsOrganCreatorResp struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data IsCreatorRsp `json:"data"` +} + +func (c *Client) GetIsOrganCreator(ctx context.Context, phone string) (*IsCreatorRsp, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + url := fmt.Sprintf("%s?phone=%s", config.Cfg.GetIsOrganCreatorURL, phone) + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetIsOrganCreator err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetIsOrganCreator http code err,rsp:%+v", rsp.String()) + return nil, errors.New(ErrHttpCode) + } + resp := GetIsOrganCreatorResp{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal GetIsOrganCreator: %v\n", err) + return nil, errors.New(ErrSystemCall) + } + if resp.Errcode != utility.OK { + log.Errorf("GetIsOrganCreator errCode:%s", resp.Errcode) + return nil, errors.New(ErrSystemCall) + } + return &resp.Data, nil +} diff --git a/infrastructure/client/httpcall/app_ext_manage.go b/infrastructure/client/httpcall/app_ext_manage.go new file mode 100644 index 0000000..4262f6b --- /dev/null +++ b/infrastructure/client/httpcall/app_ext_manage.go @@ -0,0 +1,347 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" +) + +type WechatInfo struct { + Id uint `json:"id" bson:"_id" gorm:"primary_key;column:id" sql:"auto_increment;primary_key;unique"` + WechatInfoId string `json:"wechat_info_id" bson:"wechat_info_id" gorm:"column:wechat_info_id;type:varchar(40);NOT NULL;comment:'小程序id'"` + AppId string `json:"app_id" bson:"app_id" gorm:"column:app_id;type:varchar(40);NOT NULL;comment:'小程序id'"` //小程序id + GroupId string `json:"group_id" bson:"group_id" gorm:"column:group_id;type:varchar(40);NOT NULL;comment:'group_id'"` //小程序id + WechatAppSecret string `json:"wechat_app_secret" bson:"wechat_app_secret" gorm:"column:wechat_app_secret;type:varchar(40);NOT NULL;comment:'wechat_app_secret'"` + WechatAppId string `json:"wechat_app_id" bson:"wechat_app_id" gorm:"column:wechat_app_id;type:varchar(40);NOT NULL;comment:'wechat_app_id'"` + WechatPath string `json:"wechat_path" bson:"wechat_path" gorm:"column:wechat_path;type:varchar(128);NOT NULL;comment:'wechat_path'"` + WechatSize string `json:"wechat_size" bson:"wechat_size" gorm:"column:wechat_size;type:varchar(40);NOT NULL;comment:'wechat_size'"` + QrcodeUrl string `json:"qrcode_url" bson:"qrcode_url" gorm:"column:qrcode_url;type:varchar(128);NOT NULL;comment:'qrcode_url'"` + QrcodeDownloadUrl string `json:"qrcode_download_url" bson:"qrcode_download_url" gorm:"column:qrcode_download_url;type:varchar(128);NOT NULL;comment:'group_id'"` + Created int64 `json:"created" bson:"created" gorm:"column:created;type:BIGINT(16);NOT NULL;comment:'创建时间'"` //创建时间 + Updated int64 `json:"updated" bson:"updated" gorm:"column:updated;type:BIGINT(16);default:0;comment:'更新时间'"` +} + +type GetWechatInfoResponse struct { + ErrInfo + Data WechatInfo `json:"data"` +} + +func (c *Client) GetWeChatInfo(ctx context.Context, appId string) (*WechatInfo, error) { + url := config.GetConfig().WechatInfoURL + appId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + return nil, err + } + result := GetWechatInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + return nil, err + } + log.Infof("GetWeChatInfo rsp:%+v", result) + if result.Errcode != "OK" { + log.Errorf("GetWeChatInfo result errcode err:%+v", result) + return nil, errors.New("errcode invalid") + } + return &result.Data, nil +} + +type WechatLoginInfo struct { + WechatOriginId string `json:"wechatOriginId"` + ProfileUrl string `json:"profileUrl"` + PhoneUrl string `json:"phoneUrl"` +} + +type GetWechatLoginInfoResponse struct { + ErrInfo + Data proto.WechatLoginInfo `json:"data"` +} + +func (c *Client) GetWeChatLoginInfo(ctx context.Context, appId string) (*proto.WechatLoginInfo, error) { + url := config.GetConfig().WechatLoginInfoURL + appId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetWeChatLoginInfo err:%s", err.Error()) + return nil, err + } + result := GetWechatLoginInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetWeChatLoginInfo err:%s", err.Error()) + return nil, err + } + log.Infof("GetWeChatLoginInfo rsp:%+v", result) + if result.Errcode != "OK" { + log.Errorf("GetWeChatLoginInfo result errcode err:%+v", result) + return nil, errors.New("errcode invalid") + } + return &result.Data, nil +} + +func (c *Client) TouchWechatInfo(ctx context.Context, appId string) error { + url := config.GetConfig().TouchWechatInfoURL + appId + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Post(url) + if err != nil { + log.Errorf("TouchWechatInfo err:%s", err.Error()) + return err + } + result := UpsertWeChatInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("TouchWechatInfo err:%s", err.Error()) + return err + } + log.Infof("TouchWechatInfo rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("TouchWechatInfo result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +type UpdateWechatInfoReq struct { + AppId string `json:"appId"` + WechatAppSecret string `json:"wechatAppSecret"` + WechatAppId string `json:"wechatAppId"` + WechatPath string `json:"wechatPath"` + WechatSize string `json:"wechatSize"` +} + +type UpsertWeChatInfoResponse struct { + ErrInfo +} + +func (c *Client) UpsertWeChatInfo(ctx context.Context, req UpdateWechatInfoReq) (string, error) { + url := config.GetConfig().UpsertWeChatInfoURL + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("UpsertWeChatInfo err:%s", err.Error()) + return utility.FS_SERVER_ERR, err + } + result := UpsertWeChatInfoResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + return utility.FS_SERVER_ERR, err + } + log.Infof("UpsertWeChatInfo rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("UpsertWeChatInfo result errcode err:%+v", rsp) + return result.Errcode, errors.New("errcode invalid") + } + return utility.OK, nil +} + +func (c *Client) DeleteWechatQrcode(ctx context.Context, req apiproto.DeleteWechatInfoReq) error { + url := config.GetConfig().DeleteWechatQrcodeURL + body, _ := json.Marshal(req) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("UpsertWeChatInfo err:%s", err.Error()) + return err + } + //result := GetWechatInfoResponse{} + /*if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + return err + }*/ + log.Infof("DeleteWechatQrcode rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("DeleteWechatQrcode result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +type ResetHintDotRecordReq struct { + Id string `json:"id"` + Type string `json:"type"` +} + +func (c *Client) TrialQrReset(ctx context.Context, Id string) error { + url := config.GetConfig().HintDotResetURL + req := ResetHintDotRecordReq{ + Id: Id, + Type: "trialApp", + } + + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("TrialQrReset err:%+v,status code:%+v", err, rsp) + return err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("TrialQrReset status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return nil + } + log.Infof("TrialQrReset rsp:%+v", rsp.String()) + return nil +} + +type IsReadRecordReq struct { + Id string `json:"id"` + Type string `json:"type"` + AccountId string `json:"accountId"` +} + +type IsReadRecordRsp struct { + ErrInfo + Data IsReadRsp `json:"data"` +} +type IsReadRsp struct { + IsRead bool `json:"isRead"` +} + +func (c *Client) IsTrialHasRead(ctx context.Context, Id, accountId string) (bool, error) { + ///read_dot/is_read + url := config.GetConfig().IsTrialHasReadURL + req := IsReadRecordReq{ + Id: Id, + Type: "trialApp", + AccountId: accountId, + } + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("IsTrialHasRead err:%+v,status code:%+v", err, rsp) + return false, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("IsTrialHasRead status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return false, nil + } + + result := IsReadRecordRsp{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("IsTrialHasRead err:%s", err.Error()) + return false, err + } + log.Infof("IsTrialHasRead result:%+v", result) + return result.Data.IsRead, nil +} + +func (c *Client) ReadTrialQr(ctx context.Context, Id, accountId string) error { + url := config.GetConfig().ReadTrialQrURL + req := IsReadRecordReq{ + Id: Id, + Type: "trialApp", + AccountId: accountId, + } + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + + if err != nil { + log.Errorf("ReadTrialQr err:%+v,status code:%+v", err, rsp) + return err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("ReadTrialQr status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return nil + } + log.Infof("ReadTrialQr rsp:%+v", rsp.String()) + return nil +} + +///read_dot/is_show_hint + +type IsShowHintReq struct { + AppId string `json:"appId"` + AccountId string `json:"accountId"` +} +type IsShowHintRsp struct { + IsShow bool `json:"isShow"` +} +type GetIsShowHintResponse struct { + ErrInfo + Data IsShowHintRsp `json:"data"` +} + +func (c *Client) IsShowHint(ctx context.Context, appId, accountId string) (bool, error) { + url := config.GetConfig().IsShowHintURL + req := IsShowHintReq{ + AppId: appId, + AccountId: accountId, + } + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("ReadTrialQr err:%+v,status code:%+v", err, rsp) + return false, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("ReadTrialQr status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return false, nil + } + log.Infof("ReadTrialQr rsp:%+v", rsp.String()) + result := GetIsShowHintResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("IsTrialHasRead err:%s", err.Error()) + return false, err + } + log.Infof("IsTrialHasRead rsp:%+v", rsp.String()) + return result.Data.IsShow, nil +} + +type ReadWechatHintoReq struct { + AppId string `json:"appId"` + DeveloperId string `json:"developerId"` +} + +func (c *Client) ReadWechatHint(ctx context.Context, req ReadWechatHintoReq) error { + url := config.GetConfig().ReadWechatHintURL + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("ReadWechatHint err:%s", err.Error()) + return err + } + //result := GetWechatInfoResponse{} + /*if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetWeChatInfo err:%s", err.Error()) + return err + }*/ + log.Infof("ReadWechatHint rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("ReadWechatHint result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +type GetAppByQrcodeRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data string `json:"data"` +} + +func (c *Client) GetAppByWechat(ctx context.Context, qrcode string) (string, error) { + url := config.GetConfig().GetAppByWechatURL + "?qrcode=" + qrcode + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("ReadWechatHint err:%s", err.Error()) + return "", err + } + + rspInfo := GetAppByQrcodeRsp{} + err = json.Unmarshal(rsp.Body(), &rspInfo) + if err != nil { + log.Errorf("GetAppByQrcode bind json err:%s", err.Error()) + return "", err + } + + log.Infof("GetAppByQrcode rsp struct:%+v", rspInfo) + + return rspInfo.Data, nil +} diff --git a/infrastructure/client/httpcall/appletBuildManage.go b/infrastructure/client/httpcall/appletBuildManage.go new file mode 100644 index 0000000..9e4b563 --- /dev/null +++ b/infrastructure/client/httpcall/appletBuildManage.go @@ -0,0 +1,146 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" +) + +type GetSdkVerIsEncryptedRspData struct { + Encrypted bool `json:"encrypted"` +} +type GetSdkVerIsEncryptedRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data GetSdkVerIsEncryptedRspData `json:"data"` +} + +func (c *Client) GetSdkVerIsEncrypted(ctx context.Context, sdkVer string) (bool, error) { + url := config.GetConfig().AppletBuildManageHost + config.GetConfig().SdkVerJudgeUrl + "?sdkVersion=" + sdkVer + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetSdkVerIsEncrypted client req err:%s", err.Error()) + return false, err + } + if rsp.StatusCode() != 200 { + log.Errorf("GetSdkVerIsEncrypted rsp code err:%s", rsp.String()) + return false, errors.New("GetSdkVerIsEncrypted rsp code no 200") + } + log.Infof("GetSdkVerIsEncrypted info:%s", rsp.String()) + resp := GetSdkVerIsEncryptedRsp{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) + return false, err + } + return resp.Data.Encrypted, nil +} + +type BuildInfo struct { + Id string `json:"id" gorm:"primary_key;column:id" sql:"primary_key;unique" bson:"id"` + AppId string `json:"appId" gorm:"column:app_id;type:varchar(64);comment:'App id'" bson:"appId"` + UserId string `json:"userId" gorm:"column:user_id;type:varchar(64);default:0;comment:'用户id'" bson:"userId"` //用户id + Filename string `json:"filename" gorm:"column:file_name;type:varchar(64);default:'';comment:'文件名'" bson:"filename"` //文件名 + FileUrl string `json:"fileUrl" gorm:"column:file_url;type:varchar(128);default:'';comment:'文件地址'" bson:"fileUrl"` //文件地址 + Content string `json:"content" gorm:"column:content;type:varchar(10240);default:'';comment:''" bson:"content"` //content + Version string `json:"version" gorm:"column:version;type:varchar(64);default:'';comment:'版本'" bson:"version"` //版本 + VersionRemark string `json:"versionRemark" gorm:"column:version_remark;type:varchar(256);default:'';comment:'VersionRemark'" bson:"versionRemark"` //VersionRemark + OrganId string `json:"organId" gorm:"column:organ_id;type:varchar(64);default:'';comment:'机构id'" bson:"organId"` //机构id + Username string `json:"username" gorm:"column:user_name;type:varchar(64);default:'';comment:'用户名'" bson:"username"` //用户名 + CreateTime int64 `json:"createTime" gorm:"column:create_time;type:BIGINT(16);default:0;comment:'创建时间'" bson:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime" gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'" bson:"updateTime"` //更新时间 + EncryptedUrl string `json:"encryptedUrl" gorm:"column:encrypted_url;type:varchar(128);default:'';comment:'文件加密地址'" bson:"encryptedUrl"` + Status bool `json:"status" gorm:"column:encrypted_url;type:varchar(128);default:'';comment:'文件加密地址'" bson:"status"` + Packages []Package `json:"packages" bson:"packages"` + EncryptPackage []Package `json:"encryptPackage" bson:"encryptPackage"` + Cmd string `json:"cmd" gorm:"column:cmd;type:varchar(64);default:'';comment:'编译上传类型'" bson:"cmd"` //cmd:为空默认编译上传 create:不编译直接上传 directUploadSource: 直接上传源文件 +} +type Package struct { + Root string `json:"root" bson:"root"` + Name string `json:"name" bson:"name"` + Pages []string `json:"pages" bson:"pages"` + Independent bool `json:"independent" bson:"independent"` + Filename string `json:"filename" bson:"filename"` + FileUrl string `json:"fileUrl" bson:"fileUrl"` + FileMd5 string `json:"fileMd5" bson:"fileMd5"` +} + +type GetAppletInfoByIdRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + InfoData GetAppletInfoData `json:"data"` +} + +type GetAppletInfoData struct { + Data []BuildInfo `json:"datas` + TotalElement int `json:"totalElement"` + TotalPage int `json:"totalPage"` + Size int `json:"size"` + Page int `json:"page"` +} + +func (c *Client) GetAppletInfo(ctx context.Context, appId, organId string) (*[]BuildInfo, error) { + url := config.GetConfig().AppletBuildManageHost + config.GetConfig().GetAppletInfoUrl + "?appId=" + appId + "&organId=" + organId + "&userId=&page=0&size=0" + log.Infof("GetAppletInfo url:%s", url) + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetAppletInfo client req err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != 200 { + log.Errorf("GetAppletInfo rsp code err:%s", rsp.String()) + return nil, errors.New("GetAppletInfo rsp code no 200") + } + log.Infof("GetAppletInfoById info:%s", rsp.String()) + resp := GetAppletInfoByIdRsp{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal : %v\n", err) + return nil, err + } + return &resp.InfoData.Data, nil +} + +type GetAppletByIdRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + InfoData BuildInfo `json:"data"` +} + +func (c *Client) GetAppletInfoById(ctx context.Context, Id string) (*BuildInfo, error) { + url := config.GetConfig().AppletBuildManageHost + config.GetConfig().GetAppletInfoByIdUrl + "?appletInfoId=" + Id + log.Infof("GetAppletInfoById url:%s", url) + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil { + log.Errorf("GetAppletInfo client req err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != 200 { + log.Errorf("GetAppletInfo rsp code err:%s", rsp.String()) + return nil, errors.New("GetAppletInfo rsp code no 200") + } + log.Infof("GetAppletInfoById info:%s", rsp.String()) + resp := GetAppletByIdRsp{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal : %v\n", err) + return nil, err + } + return &resp.InfoData, nil +} diff --git a/infrastructure/client/httpcall/appletEcol.go b/infrastructure/client/httpcall/appletEcol.go new file mode 100644 index 0000000..c239ded --- /dev/null +++ b/infrastructure/client/httpcall/appletEcol.go @@ -0,0 +1,261 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + + "finclip-app-manager/infrastructure/config" +) + +const ( + NotifyResultSuccess = "success" + NotifyResultFail = "fail" +) + +const ( + StOrganApproved = 3 //审核通过状态 + StOrganUnApproved = 5 //已冻结 + StOrganPersonalReviewing = 6 //个人账号升级企业账号审核中 + StOrganPersonalUnPass = 7 //个人账号升级企业账号被拒绝 +) + +const ( + ORGAN_STATUS_NORMAL = 1 //正常 + ORGAN_STATUS_FREEZE = 2 //已冻结 + ORGAN_STATUS_DELAY = 3 //已延期 +) + +//func JudgeGroupStatusValid(status int) (valid bool) { +// valid = true +// if status != StOrganApproved && +// status != StOrganPersonalReviewing && +// status != StOrganPersonalUnPass { +// valid = false +// } +// return +//} +// +//const ( +// TypeNotificationApproval = 1000 +//) +// +//const ( +// TabNotificationSystem = "system" +//) +// +//type RoleData struct { +// IsOK bool `json:"isOK"` +//} +// +//type RoleResponse struct { +// Errcode string `json:"errcode"` +// Error string `json:"error"` +// Data RoleData `json:"data"` +//} +// +//type NotificationContent struct { +// Title string `json:"title"` +// Msg string `json:"msg"` +// Reason string `json:"reason"` +// Result string `json:"result"` +//} +// +//type NotificationRequest struct { +// OrganTraceID string `json:"organTraceId"` +// Tab string `json:"tab"` +// Type int `json:"type"` +// Content NotificationContent `json:"content"` +//} +// +//type AppletEcol struct { +// ClientBase +//} +// +//func NewAppletEcol() *AppletEcol { +// return &AppletEcol{ +// ClientBase: ClientBase{ +// Service: "Applets-ecol", +// }, +// } +//} +// +//func (c *Client) GetDomainInfo(ctx context.Context, appID string) (*DomainResponseData, error) { +// url := config.Cfg.MOPDomainURL +// if url == "" { +// log.Errorf(ErrEmptyURL) +// return nil, errors.New(ErrEmptyURL) +// } else if url[len(url)-1] == '/' { +// url = url + appID +// } else { +// url = url + "/" + appID +// } +// base := ClientBase{} +// base.URL = url +// base.Method = "GET" +// base.RequestHeader = make(map[string]string) +// //zipkin上报 +// /*{ +// spanId := c.Request.Header.Get("Zipkin-Span-Id") +// value := c.GetString("zipkin_trace_span_id_" + spanId) +// a.RequestHeader["Zipkin-Span-Context"] = value +// }*/ +// if err := base.Fetch(ctx); err != nil { +// log.Errorf(err.Error()) +// return nil, err +// } else if base.StatusCode != http.StatusOK { +// log.Errorf(err.Error()) +// return nil, errors.New(ErrHttpCode) +// } +// resp := DomainResponse{} +// if err := json.Unmarshal(base.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) +// return nil, err +// } +// return &resp.Data, nil +//} +// +func (c *Client) GetDomainInfoByOrganId(ctx context.Context, organId string) (*DomainResponseData, error) { + url := config.Cfg.MOPDomainURLV2 + "?organId=" + organId + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetDomainInfoByOrganId err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetDomainInfoByOrganId status code err:%v,rsp:%s", rsp.StatusCode(), rsp.Body()) + return nil, errors.New("status code err") + } + resp := DomainResponse{} + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) + return nil, err + } + return &resp.Data, nil +} + +// +//func (c *Client) HasRole(ctx context.Context, userID string) (bool, *RoleResponse, error) { +// url := config.Cfg.GetRoleURL +// if url == "" { +// log.Errorf(ErrEmptyURL) +// return false, nil, errors.New(ErrEmptyURL) +// } +// if url[len(url)-1] == '/' { +// url = url + userID +// } else { +// url = url + "/" + userID +// } +// base := ClientBase{} +// +// base.URL = url +// base.Method = "GET" +// err := base.Fetch(ctx) +// if err != nil { +// log.Errorf(err.Error()) +// return false, nil, err +// } else if base.StatusCode != http.StatusOK { +// log.Errorf(err.Error()) +// return false, nil, errors.New(ErrHttpCode) +// } +// resp := RoleResponse{} +// if err := json.Unmarshal(base.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal roleResponse: %v\n", err) +// return false, nil, errors.New(ErrSystemCall) +// } +// if resp.Data.IsOK { +// return true, nil, nil +// } +// return false, &resp, nil +//} +// +//func (c *Client) GetDeveloperInfo(ctx context.Context, developId string) (*DeveloperData, error) { +// var headers = map[string]string{ +// "Accept": "application/json, text/plain, */*", +// "Content-Type": "application/json", +// "url-call": "internal", +// } +// urlPrefix := config.Cfg.PersonInfoProviderURL +// url := urlPrefix + developId +// log.Infof("GetDeveloperInfo url:%s", url) +// +// rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) +// +// if err != nil { +// log.Errorf("GetDeveloperInfo fetch err:%s", err.Error()) +// return nil, err +// } +// if rsp.StatusCode() != http.StatusOK { +// log.Errorf("GetDeveloperInfo StatusCode err,body:%s", rsp.String()) +// return nil, errors.New(ErrHttpCode) +// } +// resp := GetDevelopResponse{} +// if err := json.Unmarshal(rsp.Body(), &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetDeveloperInfo, error: %v\n", err) +// return nil, err +// } +// +// log.Infof("GetDeveloperInfo rsp:%+v", resp) +// +// return &resp.Data, nil +//} + +func (c *Client) UatOrganStatusIsValid(status int) bool { + return status == StOrganApproved || + status == StOrganPersonalReviewing || + status == StOrganPersonalUnPass || + status == StOrganUnApproved +} + +func (c *Client) OrganStatusIsValid(status int) bool { + return status == StOrganApproved || + status == StOrganPersonalReviewing || + status == StOrganPersonalUnPass +} + +func (c *Client) JudgeGroupStatusValid(status int) (valid bool) { + valid = true + if status != StOrganApproved && + status != StOrganPersonalReviewing && + status != StOrganPersonalUnPass { + valid = false + } + return +} + +type CheckEnterpriseIsExpiredRsp struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data struct { + IsExpired bool `json:"isExpired"` + } `json:"data"` +} + +func (c *Client) CheckEnterpriseIsExpired(ctx context.Context, userId string) (bool, error) { + url := fmt.Sprintf(config.Cfg.CheckOrganIsExpiredUrl+"?userId=%s", userId) + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + rspData := CheckEnterpriseIsExpiredRsp{} + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + + if err != nil { + log.Errorf("CheckEnterpriseIsExpired request err:%s", err.Error()) + return false, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("CheckEnterpriseIsExpired status code err,code:%d", rsp.StatusCode()) + return false, errors.New("status code err") + } + err = json.Unmarshal(rsp.Body(), &rspData) + if err != nil { + log.Errorf("CheckEnterpriseIsExpired json unmarshal err:%s", err.Error()) + return false, err + } + log.Debugf("enterprise is expired rsp:%+v", rspData) + return rspData.Data.IsExpired, nil +} diff --git a/infrastructure/client/httpcall/base.go b/infrastructure/client/httpcall/base.go new file mode 100644 index 0000000..a109b18 --- /dev/null +++ b/infrastructure/client/httpcall/base.go @@ -0,0 +1,123 @@ +package httpcall + +// +//import ( +// "bytes" +// "context" +// "gitlab.finogeeks.club/finclip-backend/apm" +// "io/ioutil" +// "net" +// "net/http" +// "time" +//) +// +//const ( +// FakeStatusCode = 666 +//) +// +//type ClientBase struct { +// RequestHeader map[string]string +// Method string +// URL string +// RequestBody []byte +// StatusCode int +// ResponseBody []byte +// Service string +// NotLogRequestBody bool +// NotLogResponseBody bool +//} +// +//var defaultClient = ClientBase{ +// RequestHeader: map[string]string{ +// "Accept": "application/json, text/plain, */*", +// "Content-Type": "application/json", +// "url-call": "internal", +// }, +// Method: "GET", +//} +// +//func (b *ClientBase) Fetch(ctx context.Context) error { +// if b.Method == "" { +// b.Method = defaultClient.Method +// } +// if b.RequestHeader == nil { +// b.RequestHeader = defaultClient.RequestHeader +// } +// client := &http.Client{ +// Transport: &http.Transport{ +// Dial: (&net.Dialer{ +// Timeout: 30 * time.Second, +// KeepAlive: 30 * time.Second, +// }).Dial, +// TLSHandshakeTimeout: 10 * time.Second, +// ResponseHeaderTimeout: 10 * time.Second, +// ExpectContinueTimeout: 1 * time.Second, +// DisableKeepAlives: true, +// }, +// Timeout: 30 * time.Second, +// } +// req, err := http.NewRequest(b.Method, b.URL, bytes.NewReader(b.RequestBody)) +// if err != nil { +// return err +// } +// for k, v := range b.RequestHeader { +// req.Header.Set(k, v) +// } +// //b.LogRequest() +// span := apm.ApmClient().CreateHttpExitSpan(ctx, req, req.URL.Host, req.URL.Path) +// defer span.End() +// resp, err := client.Do(req) +// if err != nil { +// return err +// } +// defer resp.Body.Close() +// body, err := ioutil.ReadAll(resp.Body) +// if err != nil { +// // Used for log. +// b.StatusCode = FakeStatusCode +// b.ResponseBody = nil +// return err +// } +// b.StatusCode = resp.StatusCode +// b.ResponseBody = body +// return nil +//} +// +////func (b *ClientBase) LogRequest() { +//// kv := log.KeysAndValues{ +//// "Service", b.Service, +//// "Method", b.Method, +//// "URL", b.URL, +//// "Request Header", b.RequestHeader, +//// } +//// if !b.NotLogRequestBody { +//// kv = append(kv, "Request Body", string(b.RequestBody)) +//// } +//// log.Infow("Ready to fetch", kv) +////} +//// +////func (b *ClientBase) LogError(err error) { +//// kv := log.KeysAndValues{ +//// "Service", b.Service, +//// "Method", b.Method, +//// "URL", b.URL, +//// "Request Header", b.RequestHeader, +//// "Status Code", b.StatusCode, +//// } +//// if !b.NotLogRequestBody { +//// kv = append(kv, "Request Body", string(b.RequestBody)) +//// } +//// if !b.NotLogResponseBody { +//// kv = append(kv, "Response Body", string(b.ResponseBody)) +//// } +//// if err == nil { +//// log.Errorw("Unexpected status code", kv) +//// } else { +//// kv = append(kv, "err", err) +//// log.Errorw("Fetch error", kv) +//// } +////} +// +//func (b *ClientBase) AddHeader(k string, v string) { +// b.RequestHeader[k] = v +//} diff --git a/infrastructure/client/httpcall/client.go b/infrastructure/client/httpcall/client.go new file mode 100644 index 0000000..aad28aa --- /dev/null +++ b/infrastructure/client/httpcall/client.go @@ -0,0 +1,85 @@ +package httpcall + +import ( + "context" + "finclip-app-manager/infrastructure/logger" + "github.com/go-resty/resty/v2" + "gitlab.finogeeks.club/finclip-backend/apm" + "net" + "net/http" + "time" +) + +const ( + ErrConnection = "Connection failed" + ErrHttpCode = "Unexpected http response code" + ErrResponseFormat = "Invalid response format" + ErrSystemCall = "System call error" + ErrEmptyURL = "Empty URL" +) + +var ( + log = logger.GetLogger() + defaultReqHeader = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + restyClient = resty.NewWithClient(&http.Client{ + Transport: createTransport(nil), + }) +) + +type ErrInfo struct { + Errcode string `json:"errcode"` + Error string `json:"error"` +} + +type Client struct{} + +func NewClient() *Client { + return &Client{} +} + +func (c *Client) Request(ctx context.Context) *resty.Request { + return restyClient.R().SetContext(ctx) +} + +func (c *Client) getNewDefaultReqHeader() map[string]string { + newReqHeader := make(map[string]string) + for k, v := range defaultReqHeader { + newReqHeader[k] = v + } + return newReqHeader +} + +func createTransport(localAddr net.Addr) http.RoundTripper { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + if localAddr != nil { + dialer.LocalAddr = localAddr + } + return &apmRetryTransport{&http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer.DialContext, + MaxIdleConns: 200, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + MaxIdleConnsPerHost: 200, + }} +} + +type apmRetryTransport struct { + *http.Transport +} + +func (transport *apmRetryTransport) RoundTrip(request *http.Request) (*http.Response, error) { + eSpan := apm.ApmClient().CreateHttpExitSpan(request.Context(), request, request.URL.Host, request.URL.Path) + defer eSpan.End() + + resp, err := transport.Transport.RoundTrip(request) + return resp, err +} diff --git a/infrastructure/client/httpcall/client_test.go b/infrastructure/client/httpcall/client_test.go new file mode 100644 index 0000000..912d627 --- /dev/null +++ b/infrastructure/client/httpcall/client_test.go @@ -0,0 +1,7 @@ +package httpcall + +import "testing" + +func TestUploadFile(t *testing.T) { + +} diff --git a/infrastructure/client/httpcall/control_manager.go b/infrastructure/client/httpcall/control_manager.go new file mode 100644 index 0000000..7ad404b --- /dev/null +++ b/infrastructure/client/httpcall/control_manager.go @@ -0,0 +1,58 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "fmt" +) + +type GetAppTagConfigRsp struct { + Data MopPrivateConfigData `json:"data"` + Errcode string `json:"errcode"` + Error string `json:"error"` +} + +type MopPrivateConfigData struct { + Id string `json:"id" bson:"_id"` + PlatformName string `json:"platformName"` //平台名称 + BackstageLogoUrl string `json:"backstageLogoUrl"` //后台logo + IndexWithPic string `json:"indexWithPic"` //登陆与注册页面 + CopyrightNotice string `json:"copyrightNotice"` //版权提示 + AppClass []CModel `json:"appClass"` //小程序分类 + AppTag []CModel `json:"appTag"` //小程序标签 + CreateTime int64 `json:"createTime" bson:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"updateTime"` //更新时间 + Cas int64 `json:"cas" bson:"cas"` //防冲突 + AppDowanloadLink string `json:"appDowanloadLink"` //app下载链接 +} + +type CModel struct { + Key string `json:"key"` + Name string `json:"name"` +} + +func (c *Client) GetAppTagConfigInfo(ctx context.Context) (*GetAppTagConfigRsp, error) { + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + } + url := fmt.Sprintf(config.GetConfig().ConfigManagerHost + config.GetConfig().GetAppTagConfigUrl) + + rspInfo := GetAppTagConfigRsp{} + + rsp, err := c.Request(ctx).SetHeaders(headers).Get(url) + if err != nil || rsp.StatusCode() != 200 { + fmt.Println("rsp body", rsp.String()) + return nil, errors.New("GetAppTagConfigInfo error") + } + + err = json.Unmarshal(rsp.Body(), &rspInfo) + if err != nil { + log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) + return nil, err + } + fmt.Println("rsp body", rsp.String()) + return &rspInfo, nil +} diff --git a/infrastructure/client/httpcall/data_counter.go b/infrastructure/client/httpcall/data_counter.go new file mode 100644 index 0000000..4897219 --- /dev/null +++ b/infrastructure/client/httpcall/data_counter.go @@ -0,0 +1,157 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utils" + "fmt" + "github.com/bitly/go-simplejson" + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "gitlab.finogeeks.club/finclip-backend/apm" + "io/ioutil" + "net/http" + "strings" + "time" +) + +type AddOperateLogReq struct { + Id string `json:"id"` + CreateTime int64 `json:"createTime"` + Operator string `json:"operator"` + IP string `json:"IP"` + Content string `json:"content"` + Url string `json:"url"` + OrganId string `json:"organId"` + Header interface{} `json:"header"` + Body interface{} `json:"body"` + Query interface{} `json:"query"` + Extra interface{} `json:"extra"` +} + +func (client *Client) AddOperateLog(c *gin.Context, organId, content string, extra interface{}, oper string) error { + traceX := apm.ApmClient().TraceContextFromGin(c) + url := config.GetConfig().DataCounterHost + "/api/v1/mop/finclip-data-counter/oper/log/add" + + var data AddOperateLogReq + data.Id = uuid.NewV4().String() + data.CreateTime = time.Now().UnixNano() / 1000000 + data.Operator = oper + if data.Operator == "" { + account, err := utils.DesEcbDecrypt(c.GetHeader("user-account")) + if err != nil || account == "" { + data.Operator = c.GetHeader("user-account") + } else { + data.Operator = account + } + } + data.IP = c.Request.Header.Get("X-Real-Ip") + + if data.IP == "" { + ip := strings.Split(c.Request.RemoteAddr, ":") + fmt.Println("ip", ip) + if len(ip) != 0 { + data.IP = ip[0] + } + } + data.Content = content + data.Url = c.Request.RequestURI + data.OrganId = organId + data.Header = c.Request.Header + body, _ := ioutil.ReadAll(c.Request.Body) + data.Body, _ = simplejson.NewJson(body) + data.Extra = extra + fmt.Println("data", data) + jsonBytes, _ := json.Marshal(data) + + rsp, err := client.Request(traceX).SetHeaders(client.getNewDefaultReqHeader()).SetBody(jsonBytes).Post(url) + if err != nil { + log.Errorf("AddOperateLog err:%s", err.Error()) + return err + } + log.Infof("AddOperateLog rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("AddOperateLog result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +type GenOperateDataV2Req struct { + OrganId string + Content string + Extra interface{} + Oper string + AccountId string + IsDev bool +} + +func (client *Client) AddOperateLogV2(c *gin.Context, req GenOperateDataV2Req) error { + traceX := apm.ApmClient().TraceContextFromGin(c) + url := config.GetConfig().DataCounterHost + "/api/v1/mop/finclip-data-counter/oper/log/add" + + var data AddOperateLogReq + data.Id = uuid.NewV4().String() + data.CreateTime = time.Now().UnixNano() / 1000000 + if req.AccountId != "" { + account, err := getAccountById(traceX, req.AccountId, req.IsDev) + if err == nil { + data.Operator = account + } + } + if data.Operator == "" { + data.Operator = req.Oper + if data.Operator == "" { + account, err := utils.DesEcbDecrypt(c.GetHeader("user-account")) + if err != nil || account == "" { + data.Operator = c.GetHeader("user-account") + } else { + data.Operator = account + } + //data.Operator = c.GetHeader("user-account") + } + } + data.IP = c.Request.Header.Get("X-Real-Ip") + if data.IP == "" { + ip := strings.Split(c.Request.RemoteAddr, ":") + if len(ip) != 0 { + data.IP = ip[0] + } + } + data.Content = req.Content + data.Url = c.Request.RequestURI + data.OrganId = req.OrganId + data.Header = c.Request.Header + body, _ := ioutil.ReadAll(c.Request.Body) + data.Body, _ = simplejson.NewJson(body) + data.Extra = req.Extra + jsonBytes, _ := json.Marshal(data) + + rsp, err := client.Request(traceX).SetHeaders(client.getNewDefaultReqHeader()).SetBody(jsonBytes).Post(url) + if err != nil { + log.Errorf("AddOperateLog err:%s", err.Error()) + return err + } + log.Infof("AddOperateLog rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("AddOperateLog result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +func getAccountById(ctx context.Context, id string, isDev bool) (string, error) { + if isDev { + accountInfo, err := NewClient().GetAccountInfo(ctx, id) + if accountInfo != nil { + return accountInfo.Account, err + } + } + accountInfo, err := NewClient().GetAdminAccountInfo(ctx, id) + if accountInfo == nil { + return "", err + } + return accountInfo.Account, err +} \ No newline at end of file diff --git a/infrastructure/client/httpcall/domain.go b/infrastructure/client/httpcall/domain.go new file mode 100644 index 0000000..244476a --- /dev/null +++ b/infrastructure/client/httpcall/domain.go @@ -0,0 +1,76 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" +) + +type DomainResponseData struct { + Service struct { + Request []string `json:"request"` + Socket []string `json:"socket"` + Download []string `json:"download"` + Upload []string `json:"upload"` + } `json:"service"` + Business struct { + Domains []string `json:"domains"` + } `json:"business"` + Whitelist struct { + Domains []string `json:"domains"` + } `json:"whitelist"` + Blacklist struct { + Domains []string `json:"domains"` + } `json:"blacklist"` + NeedCrt bool `json:"needCrt"` +} +type DomainResponse struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data DomainResponseData `json:"data"` +} + +func (c *Client) GetAppDomain(ctx context.Context, appId string) (*DomainResponseData, error) { + url := config.GetConfig().MOPDomainURL + appId + log.Infof("GetAppDomain url:%s", url) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetAppDomain client req err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != 200 { + log.Errorf("GetAppDomain rsp code err:%s", rsp.String()) + return nil, errors.New("GetAppDomain rsp code no 200") + } + log.Infof("GetAppDomain info:%s", rsp.String()) + resp := DomainResponse{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) + return nil, err + } + return &resp.Data, nil +} + +func (c *Client) GetAppDomainByOrganId(ctx context.Context, organId string) (*DomainResponseData, error) { + url := config.GetConfig().MOPDomainURLV2 + "?organId=" + organId + log.Infof("GetAppDomain url:%s", url) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("GetAppDomain client req err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != 200 { + log.Errorf("GetAppDomain rsp code err:%s", rsp.String()) + return nil, errors.New("GetAppDomain rsp code no 200") + } + log.Infof("GetAppDomain info:%s", rsp.String()) + resp := DomainResponse{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal DomainResponse: %v\n", err) + return nil, err + } + return &resp.Data, nil +} diff --git a/infrastructure/client/httpcall/license.go b/infrastructure/client/httpcall/license.go new file mode 100644 index 0000000..18ac1cb --- /dev/null +++ b/infrastructure/client/httpcall/license.go @@ -0,0 +1,82 @@ +package httpcall + +import ( + "context" + "errors" +) + +type CommonConfigData struct { + Error string `json:"error"` + Errcode string `json:"errcode"` + Data struct { + OrganName string `json:"organName"` + } `json:"data"` +} + +var commonConfig CommonConfigData + +func (c *Client) getCommonConfig(ctx context.Context) error { + var h = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + url := "http://mop-private-init-server:8080/api/v1/mop/mop-private-init-server/common/config" + + rsp, err := c.Request(ctx).SetHeaders(h).SetResult(&commonConfig).Get(url) + if err != nil || rsp.StatusCode() != 200 { + return errors.New("mop-private-init-server err") + } + return nil +} + +type LicenseData struct { + OrganName string `json:"organName"` //企业名称 + AppCount int `json:"appCount"` //可创建的小程序数量上限 + CooAppCount int `json:"cooAppCount"` //应用的数量 + BundleIdCount int `json:"bundleIdCount"` //bundleId数量 + ReviewOrganCount int `json:"reviewOrganCount"` //可认证通过的企业数量 + ExpireTime int64 `json:"expireTime"` //服务有效期 + CreateOperAdminByInitServer bool `json:"createOperAdminByInitServer"` //init服务是否创建运营端管理账号 + OpenAPM bool `json:"openAPM"` //是否打开APM上报 + OpenAppSearch bool `json:"openAppSearch"` + OpenApiManage bool `json:"openApiManage"` + IsWindows bool `json:"isWindows"` + IsMac bool `json:"isMac"` + IsLinux bool `json:"isLinux"` + IsIOS bool `json:"isIOS"` + IsAndroid bool `json:"isAndroid"` + IsConfiguration bool `json:"isConfiguration"` + IsApiCover bool `json:"isApiCover"` + Clients []string `json:"clients"` + DeviceNum int `json:"deviceNum"` +} + +type GetLicenseRsp struct { + Data LicenseData `json:"data"` + Errcode string `json:"errcode"` + Errmsg string `json:"error"` +} + +func (c *Client) GetLicense(ctx context.Context) (*LicenseData, error) { + if commonConfig.Data.OrganName == "" { + c.getCommonConfig(ctx) + } + var h = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + "Organ-Name": commonConfig.Data.OrganName, //私有化部署的时候,需要修改机构名称 + } + url := "http://mop-license-checker:8080/api/v1/mop/mop-license-checker/license" + var licenseInfo GetLicenseRsp + rsp, err := c.Request(ctx).SetHeaders(h).SetResult(&licenseInfo).Get(url) + if err != nil { + return nil, err + } + if rsp.StatusCode() != 200 { + log.Errorf("get license info status code err:%+v,rsp:%+v", rsp.StatusCode(), rsp.String()) + return nil, errors.New("status code error") + } + return &licenseInfo.Data, nil +} diff --git a/infrastructure/client/httpcall/mop_sms_server.go b/infrastructure/client/httpcall/mop_sms_server.go new file mode 100644 index 0000000..9c8f714 --- /dev/null +++ b/infrastructure/client/httpcall/mop_sms_server.go @@ -0,0 +1,172 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" +) + +const ( + THIRD_ENV_ZHAOS = "zhaos" + // 运营端-审核管理,同意/驳回小程序审核申请 + SMS_APP_PUBLISH_APPROVE = "APP_PUBLISH_APPROVE" + SMS_APP_PUBLISH_REJECT = "APP_PUBLISH_REJECT" + SMS_APP_PUBLISH_IMMED = "APP_PUBLISH_IMMED" + SMS_APP_PUBLISH_SUCC = "APP_PUBLISH_SUCC" + SMS_ZHAOS_APP_PUBLISH_APPROVE = "ZHAOS_APP_PUBLISH_APPROVE" + SMS_ZHAOS_APP_PUBLISH_REJECT = "ZHAOS_APP_PUBLISH_REJECT" + SMS_ZHAOS_APP_PUBLISH_IMMED = "ZHAOS_APP_PUBLISH_IMMED" + SMS_ZHAOS_APP_PUBLISH_SUCC = "ZHAOS_APP_PUBLISH_SUCC" + // 运营端-小程序关联管理,同意/驳回小程序关联审核申请 + SMS_LINK_AUDIT_APPLY = "LINK_AUDIT_APPLY" + SMS_LINK_AUDIT_REJECT = "LINK_AUDIT_REJECT" +) + +type SendSmsNotifyReq struct { + Type string `json:"type"` + Phone string `json:"phone"` + Params string `json:"params"` +} + +type SendSmsNotifyRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data map[string]interface{} `json:"data"` +} + +func validateEnvAndType(env, smsType string) bool { + if smsType == SMS_LINK_AUDIT_APPLY && env != config.ENV_FDEP { + return false + } + if smsType == SMS_LINK_AUDIT_REJECT && env != config.ENV_FDEP { + return false + } + if env != config.ENV_FDEP && env != config.ENV_UAT { + return false + } + return true +} + +func (c *Client) SendSmsNotify(ctx context.Context, smsType, phone, params string) error { + if !validateEnvAndType(config.GetConfig().PublishEnv, smsType) { + return nil + } + var req SendSmsNotifyReq + req.Type = smsType + req.Phone = phone + req.Params = params + body, _ := json.Marshal(req) + + url := config.GetConfig().SmsServerHost + "/api/v1/mop/sms-server/notify" + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("send sms notify err:" + err.Error()) + return err + } + + if rsp.StatusCode() != 200 { + log.Errorf("send sms notify status err:" + rsp.String()) + return errors.New("status err") + } + + var smsRsp SendSmsNotifyRsp + err = json.Unmarshal(rsp.Body(), &smsRsp) + if err != nil { + log.Errorf("json.Unmarshal error:" + err.Error()) + return err + } + log.Debugf("send sms notify rsp:%+v", rsp.String()) + return nil +} + +type SendThirdSmsReq struct { + Type string `json:"type"` + Phone string `json:"phone"` + Params string `json:"params"` +} + +type SendThirdSmsRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data map[string]interface{} `json:"data"` +} + +func (c *Client) SendThirdSms(ctx context.Context, smsType, phone, params string) error { + if !validateEnvAndType(config.GetConfig().PublishEnv, smsType) { + return nil + } + var req SendThirdSmsReq + req.Type = smsType + req.Phone = phone + req.Params = params + body, _ := json.Marshal(req) + + url := config.GetConfig().SmsGateWayUrl + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("send third sms err:" + err.Error()) + return err + } + + if rsp.StatusCode() != 200 { + log.Errorf("send third sms status err:" + rsp.String()) + return errors.New("status err") + } + + var smsRsp SendThirdSmsRsp + err = json.Unmarshal(rsp.Body(), &smsRsp) + if err != nil { + log.Errorf("send third sms json.Unmarshal error:" + err.Error()) + return err + } + log.Debugf("send third sms rsp:%+v", rsp.String()) + return nil +} + +type SendDelaySmsReq struct { + SmsType string `json:"smsType"` + Phone string `json:"phone"` + AppId string `json:"appId"` + AppName string `json:"appName"` + Sequence int `json:"sequence"` +} + +type SendDelaySmsRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data map[string]interface{} `json:"data"` +} + +func (c *Client) SendDelaySms(ctx context.Context, smsType, phone string, appId, appName string, sequence int) error { + if !validateEnvAndType(config.GetConfig().PublishEnv, smsType) { + return nil + } + var req SendDelaySmsReq + req.SmsType = smsType + req.Phone = phone + req.AppId = appId + req.AppName = appName + req.Sequence = sequence + body, _ := json.Marshal(req) + url := config.GetConfig().AuditDelaySmsURL + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Post(url) + if err != nil { + log.Errorf("send sms notify err:" + err.Error()) + return err + } + + if rsp.StatusCode() != 200 { + log.Errorf("send delay sms status err:" + rsp.String()) + return errors.New("status err") + } + + var smsRsp SendDelaySmsRsp + err = json.Unmarshal(rsp.Body(), &smsRsp) + if err != nil { + log.Errorf("json.Unmarshal error:" + err.Error()) + return err + } + log.Debugf("send delay sms rsp:%+v", rsp.String()) + return nil +} diff --git a/infrastructure/client/httpcall/netdisk.go b/infrastructure/client/httpcall/netdisk.go new file mode 100644 index 0000000..47fce22 --- /dev/null +++ b/infrastructure/client/httpcall/netdisk.go @@ -0,0 +1,97 @@ +package httpcall + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "fmt" + "io" + "mime/multipart" + "net/http" +) + +const ( + FormDataKey = "file" + ConsumerCustomID = "finstore" +) + +type netdiskResponse struct { + Location string `json:"location"` + NetdiskID string `json:"netdiskID"` + ResourceID string `json:"resourceID"` +} + +func (c *Client) Download(ctx context.Context, path string) ([]byte, error) { + url := path + rsp, err := c.Request(ctx).Get(url) + if err != nil { + log.Errorf("netdisk download err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("netdisk download status code err,code:%d", rsp.StatusCode()) + return nil, errors.New("download http code err") + } + return rsp.Body(), nil +} + +func (c *Client) DownloadByNetdiskId(ctx context.Context, netdiskId string) ([]byte, error) { + url := fmt.Sprintf("%s%s%s", config.GetConfig().NetdiskHost, config.GetConfig().NetdiskInternalDownloadUrl, netdiskId) + rsp, err := c.Request(ctx).Get(url) + if err != nil { + log.Errorf("netdisk download err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("netdisk download status code err,code:%d", rsp.StatusCode()) + return nil, errors.New("download http code err") + } + return rsp.Body(), nil +} + +func (c *Client) Upload(ctx context.Context, name string, inFile io.Reader, useCdn bool) (string, error) { + url := config.GetConfig().NetdiskHost + config.GetConfig().NetdiskUploadURL + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + headers := map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": writer.FormDataContentType(), + "X-Consumer-Custom-ID": ConsumerCustomID, + "url-call": "internal", + } + rsp, err := c.Request(ctx). + SetFileReader(FormDataKey, name, inFile). + SetContentLength(true). + SetHeaders(headers). + Post(url) + if err != nil { + log.Errorf("netdisk upload request err:", err.Error()) + return "", err + } + if rsp.StatusCode() != http.StatusOK { + netdiskRsp := ErrInfo{} + err = json.Unmarshal(rsp.Body(), &netdiskRsp) + if err != nil { + log.Errorf("Failed to unmarshal unmarshal netdiskResponse: %v", err) + return "", err + } + log.Errorf("netdisk upload rsp http status code err,code:", rsp.StatusCode()) + return "", errors.New(netdiskRsp.Error) + } + netdiskRsp := netdiskResponse{} + err = json.Unmarshal(rsp.Body(), &netdiskRsp) + if err != nil { + log.Errorf("Failed to unmarshal unmarshal netdiskResponse: %v", err) + return "", err + } + return c.genDownloadUrl(netdiskRsp, useCdn), nil +} + +func (c *Client) genDownloadUrl(rsp netdiskResponse, useCdn bool) string { + if useCdn && rsp.Location != "" { + return rsp.Location + } + return config.GetConfig().EntryURL + config.GetConfig().NetdiskDownloadURLPrefix + rsp.NetdiskID +} diff --git a/infrastructure/client/httpcall/notify_spider.go b/infrastructure/client/httpcall/notify_spider.go new file mode 100644 index 0000000..2c3a7dc --- /dev/null +++ b/infrastructure/client/httpcall/notify_spider.go @@ -0,0 +1,176 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "fmt" + "net/http" +) + +const ( + BIND_SDK = "bind" + UNBIND_SDK = "unbind" + STATE_UPDATE = "state" + UP_STATE = 1 + DOWN_STATE = 0 +) + +type SpiderResp struct { +} + +type SdkKeyUpdate struct { + AppId string `json:"appId"` + SdkKey string `json:"sdkKey"` +} + +type UpdateForbiddenSdkKeys struct { + AddSdkKeys []SdkKeyUpdate `json:"sdkKeys"` + RemoveSdkKeys []SdkKeyUpdate `json:"removeSdkKeys"` +} + +type StateUpdate struct { + AppId string `json:"appId"` + State int `json:"state"` +} + +type NotifySpiderUpdate struct { + Type string `json:"type"` + SdkKeys []SdkKeyUpdate `json:"sdkKeys"` + State StateUpdate `json:"state"` +} + +type AddNotifyReq struct { + OrganId string `json:"organTraceId"` + Tab string `json:"tab"` + Type int `json:"type"` + Content interface{} `json:"content"` + Id string `json:"id"` +} + +type AddNotifyResponse struct { + ErrInfo +} + +func (c *Client) AddNotify(ctx context.Context, req *AddNotifyReq) error { + url := config.GetConfig().AddNotifyURL + body, _ := json.Marshal(req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(body).Put(url) + if err != nil { + log.Errorf("TouchWechatInfo err:%s", err.Error()) + return err + } + + result := AddNotifyResponse{} + if err = json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("TouchWechatInfo err:%s", err.Error()) + return err + } + log.Infof("TouchWechatInfo rsp:%+v", rsp) + if rsp.StatusCode() != http.StatusOK { + log.Errorf("TouchWechatInfo result errcode err:%+v", rsp) + return errors.New("errcode invalid") + } + return nil +} + +func (c *Client) Notify(ctx context.Context, req *NotifySpiderUpdate) (*SpiderResp, error) { + url := config.GetConfig().SpiderHost + config.GetConfig().SpiderNotifyPath + log.Infof("notify spider url:%s", url) + log.Infof("notify spider req:%s", utility.InterfaceToJsonString(req)) + spiderResp := &SpiderResp{} + payload, _ := json.Marshal(req) + resp, err := c.Request(ctx).SetResult(&spiderResp). + SetHeader("X-Consumer-Custom-ID", "notify-spider"). + SetBody(payload). + Post(url) + if err != nil || resp.StatusCode() != http.StatusOK { + if err != nil { + return nil, err + } else { + return nil, errors.New(fmt.Sprintf("notify spider code:%d", http.StatusOK)) + } + } + return spiderResp, nil +} + +func (c *Client) UpdateBundleForbiddenInfo(ctx context.Context, req *UpdateForbiddenSdkKeys) (*SpiderResp, error) { + url := config.GetConfig().SpiderHost + config.GetConfig().SpiderUpdateBundleForbiddenURL + log.Infof("notify spider url:%s", url) + log.Infof("notify spider req:%s", utility.InterfaceToJsonString(req)) + spiderResp := &SpiderResp{} + payload, _ := json.Marshal(req) + resp, err := c.Request(ctx).SetResult(&spiderResp). + SetHeader("X-Consumer-Custom-ID", "notify-spider"). + SetBody(payload). + Post(url) + if err != nil || resp.StatusCode() != http.StatusOK { + if err != nil { + return nil, err + } else { + return nil, errors.New(fmt.Sprintf("notify spider code:%d", http.StatusOK)) + } + } + return spiderResp, nil +} + +type SpiderPubReq struct { + AppId string `json:"appId"` + AppName string `json:"appName"` + AppDesc string `json:"appDesc"` + OrganName string `json:"organName"` + SdkKeys []string `json:"sdkKeys"` + Resource string `json:"resource"` + AppTag string `json:"appTag"` + AppClass string `json:"appClass"` +} + +func (c *Client) PubAppNotifySearchApp(ctx context.Context, req *SpiderPubReq) (*SpiderResp, error) { + spiderResp := &SpiderResp{} + payload, _ := json.Marshal(req) + _, err := c.Request(ctx).SetResult(&spiderResp). + SetHeader("X-Consumer-Custom-ID", "notify-spider"). + SetBody(payload). + Post(config.GetConfig().SpiderHost + config.GetConfig().SpiderPubAppNotifyURL) + if err != nil { + return nil, err + } + return spiderResp, nil +} + +//预览服务 +func (c *Client) PubAppNotifyToMiniprogram(ctx context.Context, req *entity.AppVersion) (*SpiderResp, error) { + spiderResp := &SpiderResp{} + //payload, _ := json.Marshal(req) + //fmt.Println("payload", payload) + fmt.Println("req", utility.InterfaceToJsonString(req)) + _, err := c.Request(ctx).SetResult(&spiderResp). + //SetHeader("X-Consumer-Custom-ID", "notify-spider"). + SetBody(req). + Post(config.GetConfig().MiniProgramSearchURL) + if err != nil { + fmt.Println("err:", err.Error()) + return nil, err + } + return spiderResp, nil +} + +func (c *Client) UpdateHistoryAppMsg(ctx context.Context) error { + //traceCtx := apm.ApmClient().TraceContextFromGin(c) + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "X-Consumer-Custom-ID": "notify-spider", + "url-call": "internal", + } + url := config.GetConfig().SpiderHost + config.GetConfig().SpiderUpdateAppMsg + rsp, err := c.Request(ctx).SetHeaders(headers).SetResult(&commonConfig).Get(url) + if err != nil || rsp.StatusCode() != 200 { + return errors.New("UpdateHistoryAppMsg err") + } + return nil +} diff --git a/infrastructure/client/httpcall/provider.go b/infrastructure/client/httpcall/provider.go new file mode 100644 index 0000000..61aab2b --- /dev/null +++ b/infrastructure/client/httpcall/provider.go @@ -0,0 +1,303 @@ +package httpcall + +// +//import ( +// "context" +// "encoding/json" +// "errors" +// "finclip-app-manager/infrastructure/config" +// "net/http" +// +// "github.com/gin-gonic/gin" +//) +// +//const ( +// Opcreate = "create" +//) +// +//const ( +// ObjectTypeApp = "app" +//) +// +//type Notification struct { +// ObjectType string `json:"objectType"` +// ObjectID string `json:"objectId"` +// Operator string `json:"operator"` +// Operation string `json:"operation"` +// Timestamp int64 `json:"timestamp"` +// CustomData map[string]interface{} `json:"customData"` +//} +// +//type NotifyResponse struct { +// Errcode string `json:"errcode"` +// Error string `json:"error"` +// Data map[string]interface{} `json:"data"` +//} +// +//type DeveloperData struct { +// AccountId string `json:"accountId" bson:"accountId"` //mysql改造使用 +// Type int `json:"type" bson:"type"` //类型,1:个人账号,2:企业账号(已经提交企业资料申请) +// OrganTraceId string `json:"organTraceId" bson:"organTraceId"` //企业绑定id +// Name string `json:"name" bson:"name"` //姓名 +// Email string `json:"email" bson:"email"` //邮箱 +// Account string `json:"account" bson:"account"` //账号 +// Status int `json:"status" bson:"status"` //1--正常 2--已冻结 3--已延期 +//} +// +//const ( +// ORGAN_ACCOUNT_TYPE_PERSON = 1 +// ORGAN_ACCOUNT_TYPE_BUSINESS = 2 +//) +// +//const ( +// ORGAN_STATUS_NORMAL = 1 //正常 +// ORGAN_STATUS_FREEZE = 2 //已冻结 +// ORGAN_STATUS_DELAY = 3 //已延期 +//) +// +//type GetDevelopResponse struct { +// Data DeveloperData `json:"data"` +//} +// +//type Provider struct { +// ClientBase +//} +// +//func NewProvider() *Provider { +// return &Provider{ +// ClientBase: ClientBase{ +// Service: "Provider", +// }, +// } +//} +// +//func (p *Provider) GetGroupID(ctx context.Context, c *gin.Context, url string) (string, error) { +// if url == "" { +// log.Errorf("GetGroupID url empty!") +// return "", errors.New(ErrEmptyURL) +// } +// p.Method = "GET" +// p.URL = url +// p.RequestHeader = make(map[string]string) +// //zipkin上报 +// if c != nil { +// spanId := c.Request.Header.Get("Zipkin-Span-Id") +// value := c.GetString("zipkin_trace_span_id_" + spanId) +// p.RequestHeader["Zipkin-Span-Context"] = value +// } +// log.Infof("GetGroupID url:%s", url) +// err := p.Fetch(ctx) +// if err != nil { +// log.Errorf("GetGroupID fetch err:%s", err.Error()) +// return "", err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("GetGroupID StatusCode err,body:%s", string(p.ResponseBody)) +// return "", errors.New(ErrHttpCode) +// } +// resp := GetGroupIDResponse{} +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetGroupIDResponse: %v\n", err) +// return "", err +// } +// return resp.Data.GroupID, nil +//} +// +//func (p *Provider) GetGroupInfoByUserId(ctx context.Context, url string) (*GroupIDData, error) { +// if url == "" { +// log.Errorf(ErrEmptyURL) +// return nil, errors.New(ErrEmptyURL) +// } +// p.Method = "GET" +// p.URL = url +// p.RequestHeader = make(map[string]string) +// log.Infof("GetGroupInfoByUserId url:%s", url) +// err := p.Fetch(ctx) +// if err != nil { +// log.Errorf("GetGroupInfoByUserId fetch err:%s", err.Error()) +// return nil, err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("GetGroupInfoByUserId StatusCode err,body:%s", string(p.ResponseBody)) +// return nil, errors.New(ErrHttpCode) +// } +// resp := GetGroupIDResponse{} +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetGroupIDResponse, error: %v\n", err) +// return nil, err +// } +// return &resp.Data, nil +//} +// +//func (p *Provider) Notify(ctx context.Context, c *gin.Context, n *Notification) (int, *NotifyResponse, error) { +// resp := &NotifyResponse{} +// url := config.Cfg.NotificationProviderURL +// if url == "" { +// log.Errorf("Notify url empty!") +// return http.StatusInternalServerError, nil, errors.New(ErrEmptyURL) +// } +// log.Infof("Notify url:%s", url) +// data, err := json.Marshal(n) +// if err != nil { +// log.Errorf("Failed to marshal notification: %v\n", err) +// return http.StatusInternalServerError, resp, errors.New(ErrSystemCall) +// } +// p.Method = "POST" +// p.RequestBody = data +// p.URL = url +// p.RequestHeader = map[string]string{ +// "Accept": "application/json, text/plain, */*", +// "Content-Type": "application/json", +// "url-call": "internal", +// } +// //zipkin上报 +// { +// spanId := c.Request.Header.Get("Zipkin-Span-Id") +// value := c.GetString("zipkin_trace_span_id_" + spanId) +// p.RequestHeader["Zipkin-Span-Context"] = value +// } +// err = p.Fetch(ctx) +// if err != nil { +// log.Errorf("Notify fetch err:%s", err.Error()) +// return http.StatusInternalServerError, resp, err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("Notify StatusCode err,body:%s", string(p.ResponseBody)) +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal to NotifyResponse: %v", err) +// return http.StatusInternalServerError, resp, err +// } +// return p.StatusCode, resp, errors.New(ErrHttpCode) +// } +// return http.StatusOK, resp, nil +//} +// +//func (p *Provider) AddLimitInfo(ctx context.Context, c *gin.Context, n *AddLimitInfoReq) (int, *AddLimitInfoRsp, error) { +// resp := &AddLimitInfoRsp{} +// url := config.Cfg.AddLimitInfoURL +// if url == "" { +// log.Errorf("Notify url empty!") +// return http.StatusInternalServerError, nil, errors.New(ErrEmptyURL) +// } +// data, err := json.Marshal(n) +// if err != nil { +// log.Errorf("Failed to marshal notification: %v\n", err) +// return http.StatusInternalServerError, resp, errors.New(ErrSystemCall) +// } +// p.Method = "POST" +// p.RequestBody = data +// p.URL = url +// p.RequestHeader = map[string]string{ +// "Accept": "application/json, text/plain, */*", +// "Content-Type": "application/json", +// "url-call": "internal", +// } +// //zipkin上报 +// { +// spanId := c.Request.Header.Get("Zipkin-Span-Id") +// value := c.GetString("zipkin_trace_span_id_" + spanId) +// p.RequestHeader["Zipkin-Span-Context"] = value +// } +// log.Infof("AddLimitInfo info:%+v,url:%s", n, url) +// err = p.Fetch(ctx) +// if err != nil { +// log.Errorf("AddLimitInfo fetch err:%s", err.Error()) +// return http.StatusInternalServerError, resp, err +// } else if p.StatusCode != http.StatusOK { +// log.Debugln("Notify StatusCode err,body:%s", string(p.ResponseBody)) +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal to NotifyResponse: %v\n", err) +// return http.StatusInternalServerError, resp, err +// } +// return p.StatusCode, resp, errors.New(ErrHttpCode) +// } +// return http.StatusOK, resp, nil +//} +// +//func (p *Provider) GetAccountInfo(ctx context.Context, c *gin.Context, url string, accountId string) (*AccountInfoData, error) { +// if url == "" { +// log.Errorf("GetAccountInfo url empty!") +// return nil, errors.New(ErrEmptyURL) +// } +// p.Method = "GET" +// p.URL = url +// p.RequestHeader = make(map[string]string) +// p.RequestHeader["X-Consumer-Custom-ID"] = accountId +// p.RequestHeader["Content-Type"] = "application/json" +// p.RequestHeader["url-call"] = "internal" +// //zipkin上报 +// log.Infof("GetAccountInfo url:%s", url) +// err := p.Fetch(ctx) +// if err != nil { +// log.Errorf("GetAccountInfo fetch err:%s", err.Error()) +// //p.LogError(err) +// return nil, err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("Notify StatusCode err,body:%s", string(p.ResponseBody)) +// //p.LogError(err) +// return nil, errors.New(ErrHttpCode) +// } +// resp := GetAccountInfoResponse{} +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetAccountInfoResponse, error: %v\n", err) +// return nil, err +// } +// return &resp.Data, nil +//} +// +//func (p *Provider) GetAdminAccountInfo(ctx context.Context, c *gin.Context, url string) (*AdminAccountInfo, error) { +// if url == "" { +// log.Errorf("GetAdminAccountInfo url empty!") +// return nil, errors.New(ErrEmptyURL) +// } +// p.Method = "GET" +// p.URL = url +// p.RequestHeader = make(map[string]string) +// //zipkin上报 +// { +// spanId := c.Request.Header.Get("Zipkin-Span-Id") +// value := c.GetString("zipkin_trace_span_id_" + spanId) +// p.RequestHeader["Zipkin-Span-Context"] = value +// } +// err := p.Fetch(ctx) +// if err != nil { +// log.Errorf("GetAdminAccountInfo fetch err:%s", err.Error()) +// return nil, err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("GetAdminAccountInfo StatusCode err,body:%s", string(p.ResponseBody)) +// return nil, errors.New(ErrHttpCode) +// } +// resp := GetAdminAccountInfoResponse{} +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetAdminAccountInfo Response, error: %v\n", err) +// return nil, err +// } +// return &resp.Data.Info, nil +//} +// +//func (p *Provider) SearchAccountInfo(ctx context.Context, c *gin.Context, url string, account string) (*AccountInfoData, error) { +// if url == "" { +// log.Errorf("GetAccountInfo url empty!") +// return nil, errors.New(ErrEmptyURL) +// } +// p.Method = "GET" +// p.URL = url + "?account=" + account +// p.RequestHeader = make(map[string]string) +// p.RequestHeader["Content-Type"] = "application/json" +// p.RequestHeader["url-call"] = "internal" +// //zipkin上报 +// log.Infof("GetAccountInfo url:%s", url) +// err := p.Fetch(ctx) +// if err != nil { +// log.Errorf("GetAccountInfo fetch err:%s", err.Error()) +// //p.LogError(err) +// return nil, err +// } else if p.StatusCode != http.StatusOK { +// log.Errorf("Notify StatusCode err,body:%s", string(p.ResponseBody)) +// //p.LogError(err) +// return nil, errors.New(ErrHttpCode) +// } +// resp := GetAccountInfoResponse{} +// if err := json.Unmarshal(p.ResponseBody, &resp); err != nil { +// log.Errorf("Failed to unmarshal response to GetAccountInfoResponse, error: %v\n", err) +// return nil, err +// } +// return &resp.Data, nil +//} diff --git a/infrastructure/client/httpcall/purchasing_rights.go b/infrastructure/client/httpcall/purchasing_rights.go new file mode 100644 index 0000000..78c8501 --- /dev/null +++ b/infrastructure/client/httpcall/purchasing_rights.go @@ -0,0 +1,138 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "fmt" + "net/http" +) + +//创建小程序、应用申请权限 +const ( + PAY_ADD_TYPE_APP = 1 + PAY_ADD_TYPE_BINDING = 2 + + PAY_ID_STATUS_NO_USE = 1 + PAY_ID_STATUS_USING = 2 + PAY_ID_STATUS_EXPIRE = 3 +) + +type PayAddLimitReq struct { + Type int `json:"type"` + AccountId string `json:"accountId"` + BusinessId string `json:"businessId"` + BusinessName string `json:"businessName"` +} +type PayAddLimitRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data struct { + RightId string `json:"rightId"` + EndTime int64 `json:"endTime"` + } `json:"data"` +} + +func (c *Client) PayAddLimit(ctx context.Context, req *PayAddLimitReq) (*PayAddLimitRsp, int, error) { + url := config.GetConfig().PayAddLimitHost + config.GetConfig().PayAddLimitURL + + log.Infof("PayAddLimit url:%s,req:%+v", url, req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(req).Post(url) + if err != nil { + log.Errorf("PayAddLimit err:%+v,status code:%+v", err, rsp) + return nil, http.StatusInternalServerError, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("PayAddLimit status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return nil, rsp.StatusCode(), nil + } + rspInfo := PayAddLimitRsp{} + if err := json.Unmarshal(rsp.Body(), &rspInfo); err != nil { + log.Errorf("PayAddLimit json unmarshal err:%+v,rsp body:%+v", err, rsp.String()) + return nil, rsp.StatusCode(), err + } + log.Infof("PayAddLimit rsp:%+v", rsp.String()) + return &rspInfo, rsp.StatusCode(), nil +} + +func (c *Client) PayUpdateLimit(ctx context.Context, req *PayAddLimitReq) (*PayAddLimitRsp, int, error) { + url := config.GetConfig().PayAddLimitHost + config.GetConfig().PayUpdateLimitURL + + log.Infof("PayAddLimit url:%s,req:%+v", url, req) + + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(req).Post(url) + if err != nil { + log.Errorf("PayAddLimit err:%+v,status code:%+v", err, rsp) + return nil, http.StatusInternalServerError, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("PayAddLimit status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return nil, rsp.StatusCode(), nil + } + rspInfo := PayAddLimitRsp{} + if err := json.Unmarshal(rsp.Body(), &rspInfo); err != nil { + log.Errorf("PayAddLimit json unmarshal err:%+v,rsp body:%+v", err, rsp.String()) + return nil, rsp.StatusCode(), err + } + log.Infof("PayAddLimit rsp:%+v", rsp.String()) + return &rspInfo, rsp.StatusCode(), nil +} + +type PayCheckIdStatusRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data struct { + Status int `json:"status"` + } `json:"data"` +} + +func (c *Client) PayCheckIdStatus(ctx context.Context, id string) (int, int, error) { + url := fmt.Sprintf(config.GetConfig().PayAddLimitHost+config.GetConfig().PayCheckIdStatusURL+"?businessId=%s", id) + log.Infof("PayCheckIdStatus url:%s", url) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil { + log.Errorf("PayCheckIdStatus err:%+v,status code:%+v", err, rsp) + return 0, http.StatusInternalServerError, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("PayCheckIdStatus status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return 0, rsp.StatusCode(), errors.New("PayCheckIdStatus status code no ok") + } + rspInfo := PayCheckIdStatusRsp{} + if err := json.Unmarshal(rsp.Body(), &rspInfo); err != nil { + log.Errorf("PayCheckIdStatus json unmarshal err:%+v,rsp body:%+v", err, rsp.String()) + return 0, rsp.StatusCode(), err + } + log.Infof("PayCheckIdStatus rsp:%+v", rsp.String()) + return rspInfo.Data.Status, rsp.StatusCode(), nil +} + +type PayFixOldDataReq struct { + OrganId string `json:"organId"` + Type int `json:"type"` + BusinessId string `json:"businessId"` + BusinessName string `json:"businessName"` + CreateTime int64 `json:"createTime"` +} + +func (c *Client) PayFixOldData(ctx context.Context, req *PayFixOldDataReq) (int, error) { + url := fmt.Sprintf(config.GetConfig().PayAddLimitHost + config.GetConfig().PayFixOldDataURL) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetBody(req).Post(url) + if err != nil { + log.Errorf("PayFixOldData err:%+v,status code:%+v", err, rsp) + return http.StatusInternalServerError, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("PayFixOldData status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return rsp.StatusCode(), errors.New("PayCheckIdStatus status code no ok") + } + rspInfo := PayCheckIdStatusRsp{} + if err := json.Unmarshal(rsp.Body(), &rspInfo); err != nil { + log.Errorf("PayFixOldData json unmarshal err:%+v,rsp body:%+v", err, rsp.String()) + return rsp.StatusCode(), err + } + //log.Infof("PayFixOldData rsp:%+v", rsp.String()) + return rsp.StatusCode(), nil +} diff --git a/infrastructure/client/httpcall/rule_engine.go b/infrastructure/client/httpcall/rule_engine.go new file mode 100644 index 0000000..25fbd80 --- /dev/null +++ b/infrastructure/client/httpcall/rule_engine.go @@ -0,0 +1,97 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utility" + "net/http" +) + +type PubNotifyRuleEngineReq struct { + AppId string `json:"appId"` + Version int `json:"version"` + PubStatus string `json:"pubStatus"` + IsDev bool `json:"isDev"` + Exp map[string]interface{} `json:"exp"` +} + +func (c *Client) PubNotifyRuleEngine(ctx context.Context, appId string, version int, accountId string, isDev bool) error { + url := config.GetConfig().RuleEngineHost + config.GetConfig().PubNotifyRuleEngineURL + req := PubNotifyRuleEngineReq{ + AppId: appId, + Version: version, + IsDev: isDev, + } + + h := c.getNewDefaultReqHeader() + h["X-Consumer-Custom-ID"] = accountId + log.Errorf("PubNotifyRuleEngine req:%+v,header:%+v", req, h) + rsp, err := c.Request(ctx).SetHeaders(h).SetBody(req).Patch(url) + if err != nil { + log.Errorf("PubNotifyRuleEngine fetch err:%s", err.Error()) + return err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("PubNotifyRuleEngine StatusCode err,body:%s", rsp.Body()) + return errors.New(ErrHttpCode) + } + log.Errorf("PubNotifyRuleEngine StatusCode err,body:%s", rsp.Body()) + resp := make(map[string]interface{}) + if err = json.Unmarshal(rsp.Body(), &resp); err != nil { + log.Errorf("PubNotifyRuleEngine Failed to unmarshal response to GetGroupIDResponse: %v\n", err) + return err + } + return nil +} + +type GetAuthByUserIdAndGroupsReq struct { + UserId string `json:"userId"` + Groups []string `json:"groups"` + Type string `json:"type"` +} +type GetAuthByUserIdAndGroupsRspData struct { + AuthList map[string]GetAuthByUserIdAndGroupsRspDataItem `json:"authList"` + HasAuth bool `json:"hasAuth"` +} +type GetAuthByUserIdAndGroupsRspDataItem struct { + Dev bool `json:"dev"` + Trial bool `json:"trial"` +} +type GetAuthByUserIdAndGroupsRsp struct { + Data GetAuthByUserIdAndGroupsRspData `json:"data"` + Errcode string `json:"errcode"` + Error string `json:"error"` +} + +func (c *Client) GetAuthByUserIdAndGroups(ctx context.Context, t, userId string, groups []string) (*GetAuthByUserIdAndGroupsRspData, error) { + url := config.GetConfig().RuleEngineHost + config.GetConfig().GetUserAuthURL + req := GetAuthByUserIdAndGroupsReq{ + UserId: userId, + Groups: groups, + Type: t, + } + h := c.getNewDefaultReqHeader() + rsp, err := c.Request(ctx).SetHeaders(h).SetBody(req).Post(url) + if err != nil { + log.Errorf("GetAuthByUserIdAndGroups request err:%s", err.Error()) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("GetAuthByUserIdAndGroups code err,code:%v", rsp.StatusCode()) + return nil, errors.New("http code err") + } + + result := GetAuthByUserIdAndGroupsRsp{} + if err := json.Unmarshal(rsp.Body(), &result); err != nil { + log.Errorf("GetAuthByUserIdAndGroups bind err:%s", err.Error()) + return nil, err + } + + if result.Errcode != utility.OK { + log.Errorf("GetAuthByUserIdAndGroups errcode err,rsp:%v", result) + return nil, errors.New("errcode err") + } + return &result.Data, nil +} diff --git a/infrastructure/client/httpcall/sdk_manager.go b/infrastructure/client/httpcall/sdk_manager.go new file mode 100644 index 0000000..e4cc739 --- /dev/null +++ b/infrastructure/client/httpcall/sdk_manager.go @@ -0,0 +1,50 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity/proto" + "finclip-app-manager/infrastructure/config" +) + +type GetApiListRsp struct { + Errcode string `json:"errcode"` + Error string `json:"error"` + Data []proto.ApiInfoRspData `json:"data"` +} + +// +//type ApiInfoRspData struct { +// ApiName string `json:"apiName"` +// Url string `json:"url"` +//} + +func (c *Client) GetApiList(ctx context.Context, organId string) ([]proto.ApiInfoRspData, error) { + if config.GetConfig().PublishEnv != config.ENV_FDEP { + return nil, nil + } + if config.GetConfig().SdkManagerHost == "" || config.GetConfig().SdkManagerApiInfo == "" { + return nil, nil + } + url := config.GetConfig().SdkManagerHost + config.GetConfig().SdkManagerApiInfo + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).SetQueryParam("organId", organId).Get(url) + if err != nil { + log.Errorf("SdkManagerClient GetApiList err:" + err.Error()) + return nil, err + } + + if rsp.StatusCode() != 200 { + log.Errorf("SdkManagerClient GetApiList status err:" + rsp.String()) + return nil, errors.New("status err") + } + + var smsRsp GetApiListRsp + err = json.Unmarshal(rsp.Body(), &smsRsp) + if err != nil { + log.Errorf("json.Unmarshal error:" + err.Error()) + return nil, err + } + log.Debugf("SdkManagerClient GetApiList rsp:%+v", rsp.String()) + return smsRsp.Data, nil +} diff --git a/infrastructure/client/httpcall/security_audit.go b/infrastructure/client/httpcall/security_audit.go new file mode 100644 index 0000000..0cbe62e --- /dev/null +++ b/infrastructure/client/httpcall/security_audit.go @@ -0,0 +1,46 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "fmt" +) + +type GetAuditDataInfoByBuildInfoIdRsp struct { + Data AuditDataInfoByBuildInfoIdRsp `json:"data"` + Errcode string `json:"errcode"` + Errmsg string `json:"error"` +} + +type AuditDataInfoByBuildInfoIdRsp struct { + AuditId string `json:"auditId"` + BuildInfoId string `json:"buildInfoId"` + AppID string `json:"appId"` + Version string `json:"version"` + Status int `json:"status"` + OperOpinion int `json:"operOpinion"` + Approver string `json:"approver"` //审批人 +} + +type GetAuditDataInfoByBuildInfoIdReq struct { + BuildInfoId string `json:"buildInfoId" form:"buildInfoId"` +} + +func (c *Client) GetAuditDataInfoByBuildInfoId(ctx context.Context, buildInfoId string) (*GetAuditDataInfoByBuildInfoIdRsp, error) { + rspInfo := GetAuditDataInfoByBuildInfoIdRsp{} + + url := fmt.Sprintf(config.GetConfig().GetAuditDataInfoByBuildInfoIdUrl+"?buildInfoId=%s", buildInfoId) + rsp, err := c.Request(ctx).SetHeaders(c.getNewDefaultReqHeader()).Get(url) + if err != nil || rsp.StatusCode() != 200 { + log.Errorf("GetAppletVerByAppId rsp body", rsp.String()) + return nil, errors.New("GetAppletVerByAppId error") + } + err = json.Unmarshal(rsp.Body(), &rspInfo) + if err != nil { + log.Errorf("GetAppletVerByAppId unmarshal rsp error:%s,rspbody:%+v", err, rsp) + return nil, err + } + return &rspInfo, nil +} diff --git a/infrastructure/client/httpcall/swan.go b/infrastructure/client/httpcall/swan.go new file mode 100644 index 0000000..e2bc42a --- /dev/null +++ b/infrastructure/client/httpcall/swan.go @@ -0,0 +1,125 @@ +package httpcall + +import ( + "context" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/json" + "errors" + "finclip-app-manager/infrastructure/config" + "fmt" + "reflect" + "sort" + "time" +) + +func (c *Client) swanSign(body map[string]interface{}) (map[string]interface{}, map[string]string) { + cfg := config.GetConfig() + appKey := cfg.SwanAppKey + appSecret := cfg.SwanAppSecret + ts := time.Now().Add(1 * time.Minute).Format("2006-01-02T15:04:05.000") + nonce := fmt.Sprintf("ts123%d", time.Now().Nanosecond()) + publics := map[string]string{"ts": ts, "key": appKey, "nonce": nonce, "sigVer": "1"} + body["ts"] = ts + body["key"] = appKey + body["nonce"] = nonce + body["sigVer"] = "1" + paramList := make([]string, 0) + for k := range body { + paramList = append(paramList, k) + } + sort.Strings(paramList) + var str string + for i := 0; i < len(paramList); i++ { + name := paramList[i] + v := body[name] + if v != nil && v != "" { + tpe := reflect.TypeOf(v) + var value string + switch tpe.Kind() { + case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map: + jsonByte, _ := json.Marshal(v) + value = string(jsonByte) + default: + value = fmt.Sprintf("%v", v) + } + if i == len(paramList)-1 { + str += name + "=" + value + } else { + str += name + "=" + value + "&" + } + publics[name] = value + } + } + log.Debugln("swanSign : " + str) + h := hmac.New(sha1.New, []byte(appSecret)) + h.Write([]byte(str)) + sig := base64.StdEncoding.EncodeToString(h.Sum(nil)) + body["sig"] = sig + publics["sig"] = sig + return body, publics +} + +func (c *Client) SwanReport(traceCtx context.Context, phone, signal string) error { + cfg := config.GetConfig() + if !cfg.SwanReportEnable { + return nil + } + if !config.GetConfig().IsUatEnv() { + return nil + } + var headers = c.getNewDefaultReqHeader() + url := cfg.SwanHost + "/api/v1/open/swan/game-engine/event/signal" + params := map[string]interface{}{ + "userId": phone, + "signal": signal, + "persona": []string{"FinClip C端用户"}, + "timeStamp": time.Now().UnixNano() / 1e6, + } + body, publics := c.swanSign(params) + rsp, err := c.Request(traceCtx).SetHeaders(headers).SetQueryParams(publics).SetBody(body).Post(url) + if err != nil { + log.Errorln("SwanReport status err:" + err.Error()) + return err + } + if rsp.StatusCode() != 200 { + log.Errorln("SwanReport status err:" + rsp.String()) + return errors.New("status err") + } + log.Infof("SwanReport body %s" + rsp.String()) + return nil +} + +func (c *Client) SwanRegister(ctx context.Context, phone string) error { + cfg := config.GetConfig() + if !cfg.SwanReportEnable { + return nil + } + if !config.GetConfig().IsUatEnv() { + return nil + } + var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", + "url-call": "internal", + } + url := cfg.SwanHost + "/api/v1/open/swan/game-user/user" + params := map[string]interface{}{ + "userId": phone, + "account": phone, + "groups": []string{"xxx"}, + } + body, publics := c.swanSign(params) + rsp, err := c.Request(ctx).SetHeaders(headers).SetQueryParams(publics).SetBody(body).Post(url) + if err != nil { + log.Errorln("SwanRegister status err:" + err.Error()) + return err + } + if rsp.StatusCode() != 200 { + log.Errorln("SwanRegister status err:" + rsp.String()) + return errors.New("status err") + } + log.Infof("SwanRegister body %s" + rsp.String()) + return nil +} diff --git a/infrastructure/client/httpcall/wechat.go b/infrastructure/client/httpcall/wechat.go new file mode 100644 index 0000000..ef165f9 --- /dev/null +++ b/infrastructure/client/httpcall/wechat.go @@ -0,0 +1,62 @@ +package httpcall + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity/proto/apiproto" + "fmt" + "net/http" +) + +func (c *Client) GetWechatQrcode(ctx context.Context, req apiproto.UpdateWechatInfoReq, token string) ([]byte, error) { + url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%s", token) + body := map[string]interface{}{ + "path": req.WechatPath, + "width": 430, + } + rsp, err := c.Request(ctx).SetBody(body).Post(url) + if err != nil { + log.Errorf("getWechatQrcode err:%+v,status code:%+v", err, rsp) + return nil, err + } + if rsp.StatusCode() != http.StatusOK { + log.Errorf("getWechatQrcode status code no 200 :%+v,boyd:%+v", rsp.StatusCode(), rsp.String()) + return nil, errors.New("getWechatQrcode status code no ok") + } + if rsp.Header().Get("Content-Type") != "image/jpeg" { + log.Errorf("getWechatQrcode Content-Type not jpeg :%+v, body: %s", rsp.Header().Get("Content-Type"), string(rsp.Body())) + return nil, errors.New("getWechatQrcode Content-Type no ok") + } + log.Infof("getWechatQrcode rsp:%+v", rsp.Header()) + return rsp.Body(), nil +} + +type WechatAccessToeknRsp struct { + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` +} + +func (c *Client) GetAccessToken(ctx context.Context, req apiproto.UpdateWechatInfoReq) (string, error) { + url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", req.WechatAppId, req.WechatAppSecret) + rsp, err := c.Request(ctx).Get(url) + if err != nil { + log.Errorf("getAccessToken client req err:%s", err.Error()) + return "", err + } + if rsp.StatusCode() != 200 { + log.Errorf("getAccessToken rsp code err:%s", rsp.String()) + return "", errors.New("getAccessToken rsp code no 200") + } + resp := WechatAccessToeknRsp{} + err = json.Unmarshal(rsp.Body(), &resp) + if err != nil { + log.Errorf("Failed to unmarshal WechatAccessToeknRsp: %v\n", err) + return "", err + } + log.Infof("getAccessToken resp:%+v", resp) + if resp.AccessToken == "" { + return "", fmt.Errorf("getAccessToken fail check appId") + } + return resp.AccessToken, nil +} diff --git a/infrastructure/config/conf/bindingWhiteList.json b/infrastructure/config/conf/bindingWhiteList.json new file mode 100644 index 0000000..0acd876 --- /dev/null +++ b/infrastructure/config/conf/bindingWhiteList.json @@ -0,0 +1,102 @@ +{ + "desc":"binding_white_list", + "sdkList": [ + { + "bundleId" : "com.finogeeks.carplatform", + "remark" : "车企demo", + "SDKKey" : "22LyZEib0gLTQdU3MUauAYcpLjGld32UWyTnQ7cGMh3ycI4PWQyoTu5YBgTkmYxY", + "SDKID" : "30a6e4b189937ff2" + }, + { + "bundleId" : "com.finogeeks.finchat.oa", + "remark" : "OA的iOS bundleID", + "SDKKey" : "22LyZEib0gLTQdU3MUauAUKmAe4GJDMWBdlG9ipVB9sA", + "SDKID" : "919248e19a6c7fd3" + }, + { + "bundleId" : "com.finogeeks.finochatapp", + "remark" : "安卓开发sdk的demo bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQpfYyACROIyPtZXijuos2QA", + "SDKID" : "154a4a31a57e75cb" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "凡泰助手的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finchat.finappletdemo", + "remark" : "开发SDK的demo工程bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAVPOLhZBSOE5uMbSuLrpVrv+lVDWAeSZUhzPOBiQcOPhAA==", + "SDKID" : "705b46f78820c7a8" + }, + { + "bundleId" : "com.finogeeks.lib.applet.sample", + "remark" : "安卓开发sdk的demo bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAT1KJ5SuVt4Xl2XfybIPXKvfz4XcNUNDJF/A1WAiK9fKAA==", + "SDKID" : "42ac8b95d32b95e7" + }, + { + "bundleId" : "com.finogeeks.mop.finoverify", + "remark" : "验证助手bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAZGIR1jREF1OAFxmqycAS6AA", + "SDKID" : "b2f3d5bd38b0bfa5" + }, + { + "bundleId" : "com.finogeeks.testdemo", + "remark" : "云测demo", + "SDKKey" : "22LyZEib0gLTQdU3MUauAZvUIVniJTNgy7Vz/30fl44=", + "SDKID" : "2691f2761a47bef3" + } + ], + "bindingList": [ + { + "bindingId" : "5de86bff59e83a000122331d", + "name" : "凡泰助手", + "bundleInfos" : [ + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "ios & andrion", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + } + ], + "createdInfo" : { + "createdBy" : "admin", + "createdAt" : 1575513087120 + }, + "groupId" : "", + "groupName" : "", + "cooperateStatus" : { + "value" : "Valid", + "reason" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateValidStatus" : { + "reson" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateInvalidStatus" : { + "reson" : "", + "lastUpdated" : 1575963166875, + "modifiedBy" : "admin" + }, + "appInfos" : [] + } + ] +} \ No newline at end of file diff --git a/infrastructure/config/conf/bindingWhiteListHcc.json b/infrastructure/config/conf/bindingWhiteListHcc.json new file mode 100644 index 0000000..4b90915 --- /dev/null +++ b/infrastructure/config/conf/bindingWhiteListHcc.json @@ -0,0 +1,96 @@ +{ + "desc":"binding_white_list", + "sdkList": [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "ba25e3ceb1b266e9" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "c2e49235198a2ff3" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "e63c05eb5d588c0c" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "凡泰助手的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "bindingList": [ + { + "bindingId" : "62b01b6ffe8ff70001bad2f1", + "name" : "中国移动云盘", + "bundleInfos" : [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "ba25e3ceb1b266e9" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "c2e49235198a2ff3" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "e63c05eb5d588c0c" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "ios & andrion", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "createdInfo" : { + "createdBy" : "admin", + "createdAt" : 1575513087120 + }, + "groupId" : "", + "groupName" : "", + "cooperateStatus" : { + "value" : "Valid", + "reason" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateValidStatus" : { + "reson" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateInvalidStatus" : { + "reson" : "", + "lastUpdated" : 1575963166875, + "modifiedBy" : "admin" + }, + "appInfos" : [] + } + ] +} \ No newline at end of file diff --git a/infrastructure/config/conf/bindingWhiteListHccDev.json b/infrastructure/config/conf/bindingWhiteListHccDev.json new file mode 100644 index 0000000..ef07014 --- /dev/null +++ b/infrastructure/config/conf/bindingWhiteListHccDev.json @@ -0,0 +1,96 @@ +{ + "desc":"binding_white_list", + "sdkList": [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "ba25e3ceb1b266e9" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "c2e49235198a2ff3" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "e63c05eb5d588c0c" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "凡泰助手的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "bindingList": [ + { + "bindingId" : "62b01b6ffe8ff70001bad2f1", + "name" : "中国移动云盘", + "bundleInfos" : [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "ba25e3ceb1b266e9" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "c2e49235198a2ff3" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "e63c05eb5d588c0c" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "ios & andrion", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "createdInfo" : { + "createdBy" : "admin", + "createdAt" : 1575513087120 + }, + "groupId" : "", + "groupName" : "", + "cooperateStatus" : { + "value" : "Valid", + "reason" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateValidStatus" : { + "reson" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateInvalidStatus" : { + "reson" : "", + "lastUpdated" : 1575963166875, + "modifiedBy" : "admin" + }, + "appInfos" : [] + } + ] +} diff --git a/infrastructure/config/conf/bindingWhiteListHccUat.json b/infrastructure/config/conf/bindingWhiteListHccUat.json new file mode 100644 index 0000000..e3966a1 --- /dev/null +++ b/infrastructure/config/conf/bindingWhiteListHccUat.json @@ -0,0 +1,96 @@ +{ + "desc":"binding_white_list", + "sdkList": [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "54fca6b7f886152c" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "b7f6cd38483cea21" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "759364049347023f" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "凡泰助手的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "bindingList": [ + { + "bindingId" : "62b01b6ffe8ff70001bad2f1", + "name" : "中国移动云盘", + "bundleInfos" : [ + { + "bundleId" : "com.chinamobile.mcloud", + "remark" : "andrion", + "SDKKey" : "19vnOmJ3XbJtNK6u5p4AzpkHHjrMHvbfrEmCIsVxKfGgA4x+JWh7hhNS5aO52BFs", + "SDKID" : "54fca6b7f886152c" + }, + { + "bundleId" : "cn.10086.mobileClouds", + "remark" : "ios", + "SDKKey" : "COu+pUkwBoHIFo5f4LsuZOxZKodqxKwhJoPspbVsBds=", + "SDKID" : "b7f6cd38483cea21" + }, + { + "bundleId" : "com.cmic.mcloudV2", + "remark" : "ios", + "SDKKey" : "znOV2LvktuaQa3u5C92gToAR83kwDWakavf9ECGoXhY=", + "SDKID" : "759364049347023f" + }, + { + "bundleId" : "com.finogeeks.mop.finosprite", + "remark" : "凡泰助手新的的bundleId", + "SDKKey" : "22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk=", + "SDKID" : "ae55433be2f62915" + }, + { + "bundleId" : "com.finogeeks.finosprite", + "remark" : "ios & andrion", + "SDKKey" : "22LyZEib0gLTQdU3MUauAfJ/xujwNfM6OvvEqQyH4igA", + "SDKID" : "703b9026be3d6bc5" + } + ], + "createdInfo" : { + "createdBy" : "admin", + "createdAt" : 1575513087120 + }, + "groupId" : "", + "groupName" : "", + "cooperateStatus" : { + "value" : "Valid", + "reason" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateValidStatus" : { + "reson" : "", + "lastUpdated" : 1575963171824, + "modifiedBy" : "admin" + }, + "cooperateInvalidStatus" : { + "reson" : "", + "lastUpdated" : 1575963166875, + "modifiedBy" : "admin" + }, + "appInfos" : [] + } + ] +} \ No newline at end of file diff --git a/infrastructure/config/config.go b/infrastructure/config/config.go new file mode 100644 index 0000000..1d977b5 --- /dev/null +++ b/infrastructure/config/config.go @@ -0,0 +1,279 @@ +package config + +import ( + "encoding/json" + "fmt" + + "github.com/caarlos0/env/v6" + "gitlab.finogeeks.club/finclip-backend/apm" + "gitlab.finogeeks.club/finclip-backend/rmconf" +) + +const ( + ENV_FDEP = "mop-fdep" + ENV_UAT = "mop-uat" + ENV_PRIVATE = "mop-private" + ENV_COMMUNITY = "mop-community" +) + +var Cfg *Config + +func init() { + Cfg = new(Config) + if err := env.Parse(Cfg); err != nil { + fmt.Printf("%+v\n", err) + panic(err) + } + if Cfg.ConsulHttpIp != "" { + Cfg.ConsulAddr = Cfg.ConsulHttpIp + ":" + Cfg.ConsulPort + } else { + Cfg.ConsulAddr = "" + } + if Cfg.RemoteConfAddr != "" && Cfg.ConsulKVConfigPath != "" { + err := rmconf.StartConsulConfig(Cfg, Cfg.ConsulKVConfigPath, Cfg.ServerName, Cfg.RemoteConfAddr) + if err != nil { + fmt.Printf("StartConsulConfig error %+v\n", err) + panic(err) + } + } + b, _ := json.MarshalIndent(Cfg, "", " ") + fmt.Println("config:", string(b)) + apm.BuildApmClient(apm.CreateBuild(Cfg.SkyWalkingUrl, Cfg.ServerName, Cfg.SkyWalkingPartitions, Cfg.SkyWalkingEnable)) +} + +func GetConfig() *Config { + return Cfg +} + +func IsPrivateEnv() bool { + return Cfg.PublishEnv == "mop-private" +} + +type Config struct { + HttpPort string `env:"HTTP_PORT" envDefault:"8080"` + GrpcPort string `env:"GRPC_PORT" envDefault:"9090"` + ConsulAddr string `env:"CONSUL_ADDR" envDefault:""` + ConsulHttpIp string `env:"CONSUL_HTTP_IP" envDefault:""` + ConsulPort string `env:"CONSUL_PORT" envDefault:"8500"` + ConsulTag string `env:"CONSUL_TAG" envDefault:"mop-finstore"` + DebugLog bool `env:"DEBUG_LOG" envDefault:"true"` //是否打开debug模式 + TraceLog bool `env:"TRACE_LOG" envDefault:"false"` //是否打开trace模式 + Mode string `env:"MODE" envDefault:""` + LogMode string `env:"LOG_MODE" envDefault:"debug"` + OpenLogColor bool `env:"OPEN_LOG_COLOR" envDefault:"false"` + ReqType string `env:"REQ_TYPE" envDefault:"http"` + MongoURL string `env:"MONGO_URL" envDefault:""` + MongoMode string `env:"MONGO_MODE" envDefault:"strong"` + NetdiskHost string `env:"NETDISK_HOST" envDefault:"http://netdisk:9999"` + NetdiskInternalDownloadUrl string `env:"NETDISK_INTERNAL_DOWNLOAD_URL" envDefault:"/api/v1/netdisk/download/"` //内网下载 + NetdiskDownloadURLPrefix string `env:"NETDISK_DOWNLOAD_URL_PREFIX" envDefault:"/api/v1/netdisk/download/"` + NetdiskUploadURL string `env:"NETDISK_UPLOAD_URL" envDefault:"/api/v1/netdisk/upload/mop?type=file&content={}"` + + EntryURL string `env:"ENTRY_URL" envDefault:""` + OpenPurchAuth bool `env:"OPEN_PURCH_AUTH" envDefault:"false"` + OpenFixOld bool `env:"OPEN_FIX_OLD" envDefault:"false"` + ContactServer string `env:"CONTACT_SERVER" envDefault:""` + DBName string `env:"DB_NAME" envDefault:"finstore-backend"` + LogLevel string `env:"LOG_LEVEL" envDefault:"info"` + LogFile string `env:"LOG_FILE" envDefault:""` + LogBTLevel string `env:"LOG_BT_LEVEL" envDefault:"error"` + LogBTEnabled bool `env:"LOG_BT_ENABLED" envDefault:"true"` + LogJSONFormat bool `env:"LOG_JSON_FORMAT" envDefault:"false"` + LogMaxSize int `env:"LOG_MAX_SIZE" envDefault:"100"` + LogMaxAge int `env:"LOG_MAX_AGE" envDefault:"0"` + LogMaxBackups int `env:"LOG_MAX_BACKUPS" envDefault:"10"` + LogLocalTime bool `env:"LOG_LOCAL_TIME" envDefault:"true"` + LogCompress bool `env:"LOG_COMPRESS" envDefault:"false"` + + IsPrivate bool `env:"IS_PRIVATE" envDefault:"true"` + CheckMarket bool `env:"CHECK_MARKET" envDefault:"false"` + SpecifyAppID bool `env:"SPECIFY_APPID" envDefault:""` + HomeServerURL string `env:"HOMESERVER_URL" envDefault:""` + Domain string `env:"DOMAIN" envDefault:""` + MessageLimit int `env:"MESSAGE_LIMIT" envDefault:"500"` + KeycloakHost string `env:"KEYCLOAK_HOST" envDefault:""` + KeycloakClientID string `env:"KEYCLOAK_CLIENT_ID" envDefault:""` + KeycloakClientSecret string `env:"KEYCLOAK_CLIENT_SECRET" envDefault:""` + KeycloakUsername string `env:"KEYCLOAK_USERNAME" envDefault:""` + KeycloakPassword string `env:"KEYCLOAK_USERNAME" envDefault:""` + KeycloakRealm string `env:"KEYCLOAK_REALM" envDefault:""` + IAMEnabled bool `env:"IAM_ENABLED" envDefault:"false"` + IndustryContactHost string `env:"INDUSTRY_CONTACT_HOST" envDefault:""` + BotCenterHost string `env:"BOT_CENTER_HOST" envDefault:""` + AccountProviderURL string `env:"ACCOUNT_PROVIDER_URL" envDefault:""` + GroupInfoProviderURL string `env:"GROUP_INFO_PROVIDER_URL" envDefault:""` + PersonInfoProviderURL string `env:"PERSON_INFO_PROVIDER_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/person/info/"` + AccountInfoURL string `env:"ACCOUNT_INFO_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/account/info/"` + AccountSearchURL string `env:"ACCOUNT_SEARCH_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/account/search/"` + AdminAccountInfoUrl string `env:"ADMIN_ACCOUNT_INFO_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/operation/worker/detail/"` + NotificationProviderURL string `env:"NOTIFICATION_PROVIDER_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/business/info/"` + AddLimitInfoURL string `env:"Add_LIMIT_INFO_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/operation/limit/add"` //调用账号模块申请权限 + PayAddLimitHost string `env:"PAY_Add_LIMIT_HOST" envDefault:"http://mop-purchasing-rights-manager:8080"` + PayAddLimitURL string `env:"PAY_Add_LIMIT_URL" envDefault:"/api/v1/mop/mop-purchasing-rights-manager/rights/apply"` //调用支付模块申请权限 + PayUpdateLimitURL string `env:"PAY_UPDATE_LIMIT_URL" envDefault:"/api/v1/mop/mop-purchasing-rights-manager/rights/update"` //调用支付模块更新权限 + + PayCheckIdStatusURL string `env:"PAY_CHECK_STATUS_URL" envDefault:"/api/v1/mop/mop-purchasing-rights-manager/rights/business/status"` + PayFixOldDataURL string `env:"PAY_FIX_DATA_URL" envDefault:"/api/v1/mop/mop-purchasing-rights-manager/history/rights/process"` + GetRoleURL string `env:"GET_ROLE_URL" envDefault:""` + NotificationURL string `env:"NOTIFICATION_URL" envDefault:""` + SDKVersion string `env:"SDK_VERSION" envDefault:"3"` + MOPDomainURL string `env:"MOP_DOMAIN_URL" envDefault:""` + MOPDomainURLV2 string `env:"MOP_DOMAIN_URL_v2" envDefault:"http://mop-domain-manager:8080/api/v1/mop/applets-ecol-domain/oper/internal/all"` + IsMOP bool `env:"IS_MOP" envDefault:"true"` + KafkaVersion string `env:"KAFKA_VERSION" envDefault:"2.3.0"` + KafkaAddr string `env:"KAFKA_ADDR" envDefault:"kafka-service.kafka:9093"` + KafkaUser string `env:"KAFKA_USER" envDefault:""` + KafkaPwd string `env:"KAFKA_PWD" envDefault:""` + KafkaMechanism string `env:"KAFKA_MECHANISM" envDefault:"PLAIN"` + KafkaDataLogTopic string `env:"OPERATE_LOG_TOPIC" envDefault:"mop_operation_log"` + KafkaNotifyTopic string `env:"NOTIFY_DATA_TOPIC" envDefault:"mop_notify_data_topic"` + KafkaTamTopic string `env:"TAM_DATA_TOPIC" envDefault:"mop_topic_tam_report_msg"` + DBMode string `env:"DB_MODE" envDefault:"mongo"` //数据库模式 + MysqlUrl string `env:"MYSQL_URL" envDefault:"root:finoTest@tcp(mysql.mysql:3306)/finclip_common?charset=utf8mb4"` + DriverName string `env:"DRIVER_NAME" envDefault:"mysql"` + + OpenKafkaLog bool `env:"OPEN_KAFKA_LOG" envDefault:"false"` //日志是否输入kafka + LogTopic string `env:"LOG_TOPIC" envDefault:"elk-log"` //日志输入kafka的topic + RedisAddr string `env:"REDIS_ADDR" envDefault:""` + RedisPassword string `env:"REDIS_PASSWORD" envDefault:""` + RedisMode string `env:"REDIS_MODE" envDefault:"single"` + RedisExpireTime int `env:"REDIS_EXPIRE_TIME" envDefault:"600"` + RedisTrialExpireTime int `env:"REDIS_TRIAL_EXPIRE_TIME" envDefault:"300"` + QRcodeExpireTime int `env:"QRCODE_EXPIRE_TIME" envDefault:"21600"` //临时二维码过期时间,单位:s + ReviewQRcodeExpireTime int `env:"REVIEW_QRCODE_EXPIRE_TIME" envDefault:"180"` //审核二维码过期时间,单位:s + QRcodeUri string `env:"QRCODE_URI" envDefault:"/api/v1/mop/runtime/applet/"` + QRcodeUriV2 string `env:"QRCODE_URI_V2" envDefault:"/api/v2/mop/runtime/applet/"` + AppSecretSalt string `env:"APP_SECRET_SALT" envDefault:""` + AppSecretExpireTime int `env:"APP_SECRET_EXPIRE_TIME" envDefault:"600"` + AppCheckWhiteSig string `env:"APP_CHECK_WHITE_SIG" envDefault:""` + ZipKinUrl string `env:"ZIPKIN_URL" envDefault:""` + ZipKinSToS bool `env:"ZIPKIN_STOS" envDefault:"false"` //是否依赖其他服务,涉及跟踪span的依赖关系,废弃 + ServerName string `env:"SERVER_NAME" envDefault:"mop-app-manage-svr"` + PublishEnv string `env:"PUB_ENV" envDefault:"mop-uat"` + RuleEngineHost string `env:"RULE_ENGINE_HOST" envDefault:"http://mop-rule-engine-svr:8080"` + PubNotifyRuleEngineURL string `env:"PUB_NOTIFY_RULE" envDefault:"/api/v1/mop/rule-engine/internal/pub-notify"` + GetUserAuthURL string `env:"GET_USER_AUTH_URL" envDefault:"/api/v1/mop/rule-engine/internal/groups/user-auth"` + EncryType string `env:"ENCRY_TYPE" envDefault:"MD5"` + RedisSentinelAddr string `env:"REDIS_SENTINEL_ADDR" envDefault:"redis://redis-cluster-redis-cluster-sentinel.redis-cluster:26379/"` + RedisMasterName string `env:"REDIS_MASTER_NAME" envDefault:"mymaster"` + RedisDatabase int `env:"REDIS_INDEX" envDefault:"0"` + RedisSentinelPassword string `env:"REDIS_SENTINEL_PASSWORD" envDefault:""` + AppMemCount int `env:"APP_MEM_COUNT" envDefault:"4096"` + SkyWalkingUrl string `env:"SKYWALKING_URL" envDefault:"127.0.0.1:11800"` + SkyWalkingEnable bool `env:"SKYWALKING_ENABLE" envDefault:"false"` + SkyWalkingPartitions uint32 `env:"SKYWALKING_PARTITIONS" envDefault:"1"` + AppletBuildManageHost string `env:"APPLET_BUILD_MANAGE_HOST" envDefault:"http://mop-applet-build-manager:8080"` + SdkVerJudgeUrl string `env:"SDKVER_JUDGE_URL" envDefault:"/api/v1/mop/mop-applet-build-manager/builds/encrypted/check"` + GetAppletInfoUrl string `env:"GetAPPLET_INFO_URL" envDefault:"/api/v1/mop/mop-applet-build-manager/builds"` + GetAppletInfoByIdUrl string `env:"GetAPPLET_INFO_BY_ID_URL" envDefault:"/api/v1/mop/mop-applet-build-manager/build-info/by-id"` + + OpenCdn bool `env:"OPEN_CDN" envDefault:"false"` + CheckOrganIsExpiredUrl string `env:"CHECK_ORGAN_EXPIRED_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/operation/is-expired/organ"` + + //阿里云配置 + AliyunKeyId string `env:"ALIYUN_KEY_ID" envDefault:"LTAI4GJpmYfsnuH76uJvPbvC"` + AliyunKeySecret string `env:"ALIYUN_KEY_SECRET" envDefault:"oZ8ROGP6DjzyteRcGvUqKLpPEUZTNV"` + AliyunRegionId string `env:"ALIYUN_REGION_ID" envDefault:"cn-hangzhou"` + DnsIp string `env:"DNS_IP" envDefault:""` //默认ip + UnicomDnsIp string `env:"UNICOM_DNS_IP" envDefault:""` //联通ip + TelecomDnsIp string `env:"TELECOM_DNS_IP" envDefault:""` //电信ipip + MobileDnsIp string `env:"MOBILE_DNS_IP" envDefault:""` //移动ip + AliyunMainDomain string `env:"ALIYUN_MAIN_DOMAIN" envDefault:""` //阿里云主域名 + AliyunMainDomainPrefix string `env:"ALIYUN_MAIN_DOMAIN_PREFIX" envDefault:""` //阿里云主域名前缀 + AliyunMainDomainSuffix string `env:"ALIYUN_MAIN_DOMAIN_SUFFIX" envDefault:""` //阿里云主域名后缀 + + RemoteConfAddr string `env:"REMOTE_CONF_ADDR" envDefault:""` + ConsulKVConfigPath string `env:"CONSUL_KV_CONFIG_PATH" envDefault:""` // kv path, 拼接得到public和服务配置的key + + ApiServer string `env:"API_SERVER" envDefault:""` + ApmServer string `env:"APM_SERVER" envDefault:""` + + AuthExpireInterval int `env:"AUTH_EXPIRE_INTERVAL" envDefault:"1"` + + SmsServerHost string `env:"SMS_SERVER_HOST" envDefault:"http://mop-sms-server:8080"` + // 下面两个环境变量也是定义api管控的开关, 注意app-manager-svr与rule-engine-server同步修改 + SdkManagerHost string `env:"SMS_MANAGER_HOST" envDefault:"http://mop-sdk-manager:8080"` + SdkManagerApiInfo string `env:"SMS_MANAGER_API_INFO" envDefault:""` // /api/v1/mop/mop-sdk-manager/organ/sdkApi/organInfo + + SpiderHost string `env:"SPIDER_HOST" envDefault:"http://mop-app-spider:8080"` + SpiderNotifyPath string `env:"SPIDER_NOTIFY_URL" envDefault:"/api/v1/mop/app-spider/update-app"` + SpiderPubAppNotifyURL string `env:"SPIDER_PUB_APP_NOTIFY_URl" envDefault:"/api/v1/mop/app-spider/page-spider"` + SpiderUpdateAppMsg string `env:"SPIDER_UPDATE_APP_MSG" envDefault:"/api/v1/mop/app-spider/history-app"` + SpiderUpdateBundleForbiddenURL string `env:"SPIDER_UPDATE_BUNDLE_FORBIDDEN_URL" envDefault:"/api/v1/mop/app-spider/update-bind-forbidden"` + + AppStatusChangeInfoTopic string `env:"APP_STATUS_CHANGE_INFO_TOPIC" envDefault:"mop_app_status_change_topic"` + AppStatusChangeInfoChannel string `env:"APP_STATUS_CHANGE_INFO_CHANNEL" envDefault:"mop_app_status_change_channel"` + CheckAppVerLimit int `env:"CHECK_APP_VER_LIMIT" envDefault:"3"` + QRcodeGetAppVerInfoUrl string `env:"QRCODE_GET_APPVER_INFO_URL" envDefault:"/runtime/refresh/qrcode/"` + ManageAppDevCount int `env:"MANAGE_APP_DEV_COUNT" envDefault:"20"` + CodePackageNumLimit int `env:"CODE_PACKAGE_NUM_LIMIT" envDefault:"20"` + BuildDbName string `env:"BUILD_DB_NAME" envDefault:"applets_build"` + + //金易联 + SwanReportEnable bool `env:"SWAN_REPORT_ENABLE" envDefault:"false"` + SwanHost string `env:"SWAN_HOST" envDefault:"https://swan.finogeeks.club"` + SwanAppKey string `env:"SWAN_APP_KEY" envDefault:"V1eSG6lAg6PB4VhJ509AMgPR5OTw0JA"` + SwanAppSecret string `env:"SWAN_APP_SECRET" envDefault:"R0DWiCTJK7ZpHXKOqqZ3I5fyqFarDRE"` + + AppTagTypeList string `env:"APP_TAG_TYPE_LIST" envDefault:"证券开户,投顾行情,投教研报,生活服务,政务教育,资讯行情,电子商务,工业互联网,物联网,其他"` + ConfigManagerHost string `env:"CONFIG_MANAGER_HOST" envDefault:"http://mop-control-manager:8080"` + GetAppTagConfigUrl string `env:"GET_APP_TAG_CONFIG_URL" envDefault:"/api/v1/mop/mop-control-manager/mopHelper/config/info"` + UatDomainList []string `env:"UAT_DOMAIN_LIST" envDefault:"https://www.finclip.com,https://www.finclip.com,https://finclip.com,https://finclip.com/"` + + WechatInfoURL string `env:"WECHAT_INFO_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat/info/"` + UpsertWeChatInfoURL string `env:"UPSERT_WECHAT_INFO_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat/info"` + WechatLoginInfoURL string `env:"WECHAT_LOGIN_INFO_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat-login/"` + DataCounterHost string `env:"DATA_COUNTER_HOST" envDefault:"http://finclip-data-counter:8080"` + + TouchWechatInfoURL string `env:"TOUCH_WECHAT_INFO_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat/touch_info/"` + DeleteWechatQrcodeURL string `env:"DELETE_WECHAT_QRCODE_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat/qrcode/delete"` + + HintDotResetURL string `env:"HINT_DOT_RESET_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/read_dot/reset"` + IsTrialHasReadURL string `env:"IS_TRIAL_HAS_READ_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/read_dot/is_read"` + ReadTrialQrURL string `env:"READ_TRIAL_QR_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/read_dot/read_trial_qr"` + IsShowHintURL string `env:"IS_SHOW_HINT_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/read_dot/is_show_hint"` + ReadWechatHintURL string `env:"READ_WECHAT_HINT_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/wechat/read_hint"` + GetAppByWechatURL string `env:"GET_APP_BY_WECHAT_URL" envDefault:"http://finclip-app-ext-svr:8080/api/v1/mop/finclip-app-ext-svr/openapi/wechat/app"` + + AddNotifyURL string `env:"ADD_NOTIFY_URL" envDefault:"http://mop-notify:8080/api/v1/mop/applets-ecol-notify/add"` + AuditDelaySmsURL string `env:"AUDIT_DELAY_SMS_URL" envDefault:"http://mop-audit-manage-svr:8080/api/v1/mop/mop-audit-manage-svr/organ/delay-sms"` + + AddAvailableBundleNum int `env:"ADD_AVAILABLE_BUNDLE_NUM" envDefault:"2"` + AddALLBundleNum int `env:"ADD_ALL_BUNDLE_NUM" envDefault:"10"` + + IsHcc bool `env:"IS_HCC" envDefault:"false"` + HccEnv string `env:"HCC_ENV" envDefault:"uat"` + IsOpenAuditSecurity bool `env:"IS_OPEN_AUDIT_SECURITY" envDefault:"false"` + + OrganListURL string `env:"ORGAN_LIST_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/operation/organlist"` + BindLimitURL string `env:"BIND_LIMIT_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/limit/binding"` + MiniProgramSearchURL string `env:"MINI_PROGRAM_SEARCH_URL" envDefault:"http://mop-miniprogram-preview:8080/miniprogram/search"` + + ThirdEnv string `env:"THIRD_ENV" envDefault:""` + SmsGateWayUrl string `env:"SMS_GATEWAY_URL" envDefault:"http://mop-verify-code-gateway:8080/api/v1/mop/verifycode-server/phone/third/sms"` + MonitorPort string `env:"MONITOR_PORT" envDefault:"9092"` //监控端口 + OpenMonitor bool `env:"OPEN_MONITOR" envDefault:"false"` //是否打开监控 + GetAuditDataInfoByBuildInfoIdUrl string `env:"GET_AUDIT_DATA_INFO_BY_BUILD_INFO_ID_URL" envDefault:"http://finclip-security-audit:8080/api/v1/mop/finclip-security-audit/audit/info/by/build-info-id"` + GetIsOrganAdminURL string `env:"GET_IS_ORGAN_ADMIN_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/is-admin/by-phone"` + GetIsOrganCreatorURL string `env:"GET_IS_ORGAN_CREATOR_URL" envDefault:"http://mop-account-system:8080/api/v1/mop/applets-ecol-account/organ/is-creator/by-phone"` +} + +func (c *Config) IsPrivateEnv() bool { + return c.PublishEnv == ENV_PRIVATE +} + +func (c *Config) IsFdepEnv() bool { + return c.PublishEnv == ENV_FDEP +} +func (c *Config) IsUatEnv() bool { + return c.PublishEnv == ENV_UAT +} + +func (c *Config) IsCommunityEnv() bool { + return c.PublishEnv == ENV_COMMUNITY +} + +func (c *Config) EnableApiManage() bool { + // 如果填写SdkManagerApiInfo, 则认为当前环境开启了api管理 + return c.SdkManagerApiInfo != "" +} diff --git a/infrastructure/config/sdk_list.go b/infrastructure/config/sdk_list.go new file mode 100644 index 0000000..b7bdd2e --- /dev/null +++ b/infrastructure/config/sdk_list.go @@ -0,0 +1,68 @@ +package config + +import ( + "encoding/json" + "finclip-app-manager/domain/entity" + "fmt" + "os" +) + +type BundleInfoCfg struct { + BundleID string `json:"bundleId"` + Remark string `json:"remark"` + SDKKey string `json:"SDKKey"` + SDKID string `json:"SDKID"` +} + +type BindingWhiteListInfo struct { + Desc string `json:"desc"` + SDKList []BundleInfoCfg `json:"sdkList"` + BindingList []entity.Binding `json:"bindingList"` +} + +//创建白名单应用 +var WhiteSDKList []BundleInfoCfg +var WhiteSDKArry []string //SDKKey +var WhiteBundleIdArry []string //bundleId +var BindingWhiteList BindingWhiteListInfo + +func init() { + //私有化部署的版本隐藏应用凡泰助手 + filePtr, err := os.Open("./conf/bindingWhiteList.json") + if GetConfig().IsHcc { + if GetConfig().HccEnv == "dev" { + filePtr, err = os.Open("./conf/bindingWhiteListHccDev.json") + } else { + filePtr, err = os.Open("./conf/bindingWhiteListHccUat.json") + } + } + if err != nil { + fmt.Println("Open file failed [Err:%s]", err.Error()) + panic(err.Error()) + } + defer filePtr.Close() + // 创建json解码器 + decoder := json.NewDecoder(filePtr) + err = decoder.Decode(&BindingWhiteList) + if err != nil { + fmt.Println("Decoder failed", err.Error()) + panic(err.Error()) + } + WhiteSDKList = BindingWhiteList.SDKList + for _, v := range BindingWhiteList.SDKList { + WhiteSDKArry = append(WhiteSDKArry, v.SDKKey) + WhiteBundleIdArry = append(WhiteBundleIdArry, v.BundleID) + } + fmt.Println("[config/sdk_list.go:48] binding white list:", BindingWhiteList) + fmt.Println("[handler/sdk_list.go:49] sdk-key list:", WhiteSDKArry) + fmt.Println("[handler/sdk_list.go:50] bundle-id list:", WhiteBundleIdArry) +} + +func WhiteListGetSDKKeyAndId(bundleId string) (string, string) { + for _, v := range WhiteSDKList { + if v.BundleID == bundleId { + return v.SDKKey, v.SDKID + } + } + return "", "" +} diff --git a/infrastructure/consul/consul.go b/infrastructure/consul/consul.go new file mode 100644 index 0000000..7318291 --- /dev/null +++ b/infrastructure/consul/consul.go @@ -0,0 +1,220 @@ +package consul + +import ( + "encoding/json" + "finclip-app-manager/infrastructure/config" + "fmt" + "net" + "net/http" + "strconv" + "time" + + consulapi "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/api/watch" + uuid "github.com/satori/go.uuid" +) + +var ( + mopConsul *MopConsul +) + +type MopConsul struct { + CheckPort string + NodeId string + ConsulClient *consulapi.Client + IsRegSucc bool + IsStop bool +} + +func InitConsul() { + mopConsul = NewMopConsul() + mopConsul.Init() +} + +func GetConsulInstance() *MopConsul { + return mopConsul +} + +func NewMopConsul() *MopConsul { + var m MopConsul + + m.CheckPort = "9091" + m.NodeId = uuid.NewV4().String() + m.IsRegSucc = false + m.IsStop = false + + var err error + cfg := consulapi.DefaultConfig() + cfg.Address = config.GetConfig().ConsulAddr + m.ConsulClient, err = consulapi.NewClient(cfg) + if err != nil { + panic(err) + } + + return &m +} + +func (m *MopConsul) Init() { + m.InitCheck() //初始化check接口 + + time.Sleep(1 * time.Second) + m.RegisterServer() //注册服务 + go m.WatchService() //服务是否发生change + go m.SyncServiceHealth(60) //主动拉取健康状态 +} + +func (m *MopConsul) InitCheck() { + http.HandleFunc("/"+m.NodeId+"/check", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("success")) + }) + + go http.ListenAndServe(":"+m.CheckPort, nil) +} + +func (m *MopConsul) GetLocalIP() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "" + } + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String() + } + } + } + return "" +} + +func (m *MopConsul) RegisterServer() { + if m.IsStop { + return + } + registration := new(consulapi.AgentServiceRegistration) + registration.ID = m.NodeId + registration.Name = config.GetConfig().ServerName + registration.Port, _ = strconv.Atoi(config.GetConfig().GrpcPort) + registration.Tags = []string{config.GetConfig().ConsulTag} + registration.Address = m.GetLocalIP() + fmt.Println("localIP=" + registration.Address) + registration.Check = &consulapi.AgentServiceCheck{ + CheckID: m.NodeId, + HTTP: "http://" + registration.Address + ":" + m.CheckPort + "/" + m.NodeId + "/check", + Timeout: "5s", + Interval: "30s", + DeregisterCriticalServiceAfter: "35s", //check失败后35秒删除本服务 + } + + err := m.ConsulClient.Agent().ServiceRegister(registration) + if err != nil { + fmt.Errorf("ServiceRegister err:" + err.Error()) + if m.IsRegSucc == false { + panic(err) + } + } + + m.IsRegSucc = true + fmt.Println("Consul RegisterServer success") +} + +func (m *MopConsul) DisRegisterServer() { + m.IsStop = true + err := m.ConsulClient.Agent().ServiceDeregister(m.NodeId) + if err != nil { + fmt.Errorf("ServiceDeregister service:%s err:%s\n", m.NodeId, err.Error()) + } else { + fmt.Printf("ServiceDeregister service:%s succ\n", m.NodeId) + } +} + +func (m *MopConsul) WatchService() { + var notifyCh = make(chan struct{}) + + watchContent := `{"type":"service", "service":"` + config.GetConfig().ServerName + `", "tag":"` + config.GetConfig().ConsulTag + `"}` + plan := m.WatchParse(watchContent) + plan.Handler = func(idx uint64, raw interface{}) { + fmt.Println("service change...") + if raw == nil { + return // ignore + } + fmt.Println("do something...") + notifyCh <- struct{}{} + } + + go func() { + if err := plan.Run(config.GetConfig().ConsulAddr); err != nil { + panic(err) + } + }() + defer plan.Stop() + + for { + select { + case <-notifyCh: + m.RegisterAgain() + } + } +} + +func (m *MopConsul) SyncServiceHealth(gap int) { + for { + if m.IsStop { + break + } + time.Sleep(time.Duration(gap) * time.Second) + isHealth := false + services, _, err := m.ConsulClient.Health().Service(config.GetConfig().ServerName, config.GetConfig().ConsulTag, true, &consulapi.QueryOptions{WaitIndex: 0}) + if err != nil { + fmt.Errorf("error retrieving instances from Consul: %s", err.Error()) + } + + for _, s := range services { + if s.Service.ID == m.NodeId { + isHealth = true + break + } + } + + if !isHealth { + m.RegisterServer() + } + } +} + +func (m *MopConsul) WatchParse(q string) *watch.Plan { + var params map[string]interface{} + if err := json.Unmarshal([]byte(q), ¶ms); err != nil { + fmt.Errorf("Unmarshal err:" + err.Error()) + return nil + } + + plan, err := watch.Parse(params) + if err != nil { + panic(err) + } + + return plan +} + +func (m *MopConsul) RegisterAgain() { + if !m.CheckServiceIsOK() { + m.RegisterServer() + } +} + +func (m *MopConsul) CheckServiceIsOK() bool { + services, _ := m.ConsulClient.Agent().Services() + + isOK := false + if len(services) > 0 { + if value, ok := services[m.NodeId]; ok { + if value.Service == config.GetConfig().ServerName { + if value.Weights.Passing == 1 { + isOK = true + } + } + } + } + + return isOK +} diff --git a/infrastructure/db/db.go b/infrastructure/db/db.go new file mode 100644 index 0000000..c5e8240 --- /dev/null +++ b/infrastructure/db/db.go @@ -0,0 +1,6 @@ +package db + +/** + * DDD: infrastructure-db。 + * 为领域层提供持久化机制(最底层的实现,接口声明在repository),domain并不关心使用什么存储 + **/ diff --git a/infrastructure/db/entity/mongo/app.go b/infrastructure/db/entity/mongo/app.go new file mode 100644 index 0000000..6d15b2f --- /dev/null +++ b/infrastructure/db/entity/mongo/app.go @@ -0,0 +1,175 @@ +package mongo + +//App 小程序元信息 +type App struct { + AppID string `json:"appId" bson:"appId"` //id + Name string `json:"name" bson:"name"` //名字 + Sequence int `json:"sequence" bson:"sequence"` //版本号 + AppClass string `json:"appClass" bson:"appClass"` //用途 现在改为分类 + AppTag []string `json:"appTag" bson:"appTag"` //标签 + AppType string `json:"appType" bson:"appType"` //应用类型--mop使用为了和应用市场区分开 + Status Status `json:"status" bson:"status"` //状态 + //todo 明确这是个啥 + ApplyStatus Status `json:"applyStatus" bson:"-"` // 关联审核状态 + PublishedStatus SpecificStatus `json:"publishedStatus" bson:"publishedStatus"` //上架 + UnpublishedStatus SpecificStatus `json:"unpublishedStatus" bson:"unpublishedStatus"` //下架 + ActionStatus SpecificStatus `json:"actionStatus" bson:"actionStatus"` //上下架 + DeveloperID string `json:"developerId" bson:"developerId"` //开发者id + GroupID string `json:"groupId" bson:"groupId"` //组id + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` + DetailDescription string `bson:"detailDescription" json:"detailDescription"` //小程序详细描述 + Version string `json:"version" bson:"version"` //应用版本 + CoreDescription string `json:"coreDescription" bson:"coreDescription"` //小程序简介 + Logo string `json:"logo" bson:"logo"` //图标 + Expire int64 `json:"expire" bson:"expire"` + IsRollback bool `json:"isRollback" bson:"isRollback"` // 是否回滚发布 + IsForbidden int `json:"isForbidden" bson:"isForbidden"` + PrivacySettingType int `json:"privacySettingType" bson:"privacySettingType"` + ProjectType int `json:"projectType" bson:"projectType"` +} + +type AppVersion struct { + AppID string `json:"appId" bson:"appId"` + Name string `json:"name" bson:"name"` + AppClass string `json:"appClass" bson:"appClass"` //用途 现在改为分类 + AppTag []string `json:"appTag" bson:"appTag"` //标签 + AppType string `json:"appType" bson:"appType"` + Status Status `json:"status" bson:"status"` + PublishingStatus SpecificStatus `json:"publishingStatus" bson:"publishingStatus"` //提交上架审核 + UnpublishingStatus SpecificStatus `json:"unpublishingStatus" bson:"unpublishingStatus"` //下架审核 + PublishingApprovalStatus SpecificStatus `json:"publishingApprovalStatus" bson:"publishingApprovalStatus"` //管理员审核上架记录 + UnpublishingApprovalStatus SpecificStatus `json:"unpublishingApprovalStatus" bson:"unpublishingApprovalStatus"` //管理员审核下架记录 + PublishedStatus SpecificStatus `json:"publishedStatus" bson:"publishedStatus"` //执行上架记录 + UnpublishedStatus UnpublishedStatus `json:"unpublishedStatus" bson:"unpublishedStatus"` //执行下架记录 + RequestStatus SpecificStatus `json:"requestStatus" bson:"requestStatus"` //合并开发者申请上下架状态 + ApprovalStatus SpecificStatus `json:"approvalStatus" bson:"approvalStatus"` //合并管理员申请上下架状态 + ActionStatus SpecificStatus `json:"actionStatus" bson:"actionStatus"` //执行上下架合并 + DeveloperID string `json:"developerId" bson:"developerId"` + GroupID string `json:"groupId" bson:"groupId"` + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"createdBy"` // 提交审核的用户 + CustomData CustomDataInfo `json:"customData" bson:"customData"` + Version string `json:"version" bson:"version"` + Sequence int `json:"sequence" bson:"sequence"` + CorporationID string `json:"corporationId" bson:"corporationId"` //与groupid类似 + CoreDescription string `json:"coreDescription" bson:"coreDescription"` //小程序简介 + Logo string `json:"logo" bson:"logo"` + TestInfo TestInfo `json:"testInfo" bson:"testInfo"` + NeedAutoPub bool `json:"needAutoPub" bson:"needAutoPub"` + IsRollback bool `json:"isRollback" bson:"isRollback"` //是否回滚 + InGrayRelease bool `json:"inGrayRelease" bson:"inGrayRelease"` //是否在灰度发布中 + Expire int64 `json:"expire" bson:"expire"` + AppBuildID string `json:"appBuildID" bson:"appBuildID"` +} + +//状态信息 +type Status struct { + Value string `json:"value" bson:"value"` + Reason string `json:"reason" bson:"reason"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` +} + +type SpecificStatus struct { + Reason string `json:"reason" bson:"reason"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` +} + +type UnpublishedStatus struct { + Reason string `json:"reason" bson:"reason"` + LastUpdated int64 `json:"lastUpdated" bson:"lastUpdated"` + ModifiedBy string `json:"modifiedBy" bson:"modifiedBy"` + Type string `json:"type" bson:"type"` +} + +type CustomDataSourceFile struct { + FileMd5 string `bson:"fileMd5" json:"fileMd5"` + Name string `bson:"name" json:"name"` + SourceFileUrl string `bson:"sourceFileUrl" json:"sourceFileUrl"` + UploadDate int64 `bson:"uploadDate" json:"uploadDate"` + Url string `bson:"url" json:"url"` + EncryptedUrl string `bson:"encryptedUrl" json:"encryptedUrl"` + EncryptedFileMd5 string `bson:"encryptedFileMd5" json:"encryptedFileMd5"` + EncryptedFileSha256 string `bson:"encryptedFileSha256" json:"encryptedFileSha256"` + BasicPackVer string `bson:"basicPackVer" json:"basicPackVer"` + Packages []Package `bson:"packages"` + EncryptPackages []Package `bson:"encryptPackages"` +} + +type Package struct { + Root string `json:"root" bson:"root"` + Name string `json:"name" bson:"name"` + Pages []string `json:"pages" bson:"pages"` + Independent bool `json:"independent" bson:"independent"` + Filename string `json:"filename" bson:"filename"` + FileUrl string `json:"fileUrl" bson:"fileUrl"` + FileMd5 string `json:"fileMd5" bson:"fileMd5"` +} + +type CustomDataInfo struct { + DetailDescription string `bson:"detailDescription" json:"detailDescription"` //小程序详细描述 + SourceFile []CustomDataSourceFile `bson:"sourceFile" json:"sourceFile"` + VersionDescription string `bson:"versionDescription" json:"versionDescription"` //小程序编译包版本描述 + Developer string `bson:"developer" json:"developer"` //开发者 +} + +type TestInfo struct { + Account string `json:"account" bson:"account"` + Password string `json:"password" bson:"password"` + Description string `json:"description" bson:"description"` + Images []string `json:"images" bson:"images"` +} + +type AppStartParams struct { + PathAndQuery string `json:"pathAndQuery" bson:"path_and_query"` +} + +type AppBuildInfo struct { + Id string `json:"id" bson:"id"` + BuildInfoId string `json:"buildInfoId" bson:"buildInfoId"` + Source string `json:"source" bson:"source"` // 该上传版本的状态: build:正常版本, trail:被设置为体验版 + AppID string `json:"appId" bson:"appId"` + GroupID string `json:"groupId" bson:"groupId"` + Created int64 `json:"created" bson:"created"` //创建该编译版本的时间 + UserId string `json:"userId" bson:"userId"` + CreatedBy string `json:"createdBy" bson:"createdBy"` //创建人 + + CustomData CustomDataInfo `json:"customData" bson:"customData"` + Version string `json:"version" bson:"version"` + VersionDescription string `json:"versionDescription" bson:"versionDescription"` //小程序编译包版本描述 + StartParams AppStartParams `json:"startParams" bson:"startParams"` + Status bool `json:"status" bson:"status"` +} + +/* +type AppBuildInfo struct { + Id string `bson:"id" gorm:"column:id;type:varchar(40)" sql:"primary_key;unique"` + BuildInfoId string `bson:"build_info_id" gorm:"column:build_info_id;type:varchar(128);comment:'编译id'"` + AppID string `bson:"app_id" bson:"appId" gorm:"column:id;type:varchar(40)"` + + Source string `bson:"source" gorm:"column:source;type:varchar(64);comment:'上传版本的状态'"` // 该上传版本的状态: build:正常版本, trail:被设置为体验版 + Version string `bson:"version" gorm:"column:version;type:varchar(128);comment:'版本号'"` + VersionDescription string `bson:"version_description" gorm:"column:version;type:varchar(1024);comment:'版本描述'"` //小程序编译包版本描述 + + GroupID string `bson:"group_id" gorm:"column:group_id;type:varchar(64);comment:'组id'"` + UserId string `bson:"user_id" gorm:"column:user_id;type:varchar(64);comment:'用户id'"` + CreatedBy string `bson:"created_by" gorm:"column:created_by;type:varchar(64);comment:'组id'"` + Status bool `bson:"status" gorm:"column:status;type:bool;comment:'status'"` + + FileMd5 string `bson:"file_md5" gorm:"column:file_md5;type:varchar(512);default:'';comment:'md5'"` + Name string `bson:"name" gorm:"column:name;type:varchar(256);default:'';comment:'包名'"` + Url string `bson:"url" gorm:"column:url;type:varchar(512);default:'';comment:'编译包下载地址'"` + EncryptedUrl string `bson:"encrypted_url" gorm:"column:encrypted_url;type:varchar(512);default:'';comment:'加密后下载地址'"` + EncryptedFileMd5 string `bson:"encrypted_file_md5" gorm:"column:encrypted_file_md5;type:varchar(512);default:'';comment:'加密包md5'"` + EncryptedFileSha256 string `bson:"encrypted_file_sha256" gorm:"column:encrypted_file_sha256;type:varchar(512);default:'';comment:'加密包sha256'"` + BasicPackVer string `bson:"basic_pack_ver" gorm:"column:basic_pack_ver;type:varchar(48);default:'';comment:'基础库版本'"` + Packages string `bson:"packages" gorm:"column:packages;type:TEXT;default:'';comment:'分包信息'"` + EncryptPackages string `bson:"encrypt_packages" gorm:"column:encrypt_packages;type:TEXT;default:'';comment:'加密分包信息'"` + PathAndQuery string `bson:"path_and_query" gorm:"column:path_and_query;type:varchar(64);comment:'小程序启动参数'"` + + CreateTime int64 `bson:"create_time" gorm:"column:create_time;type:BIGINT(16);NOT NULL;comment:'创建时间'"` + UpdateTime int64 `bson:"update_time" gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` +} +*/ diff --git a/infrastructure/db/entity/mongo/appver.go b/infrastructure/db/entity/mongo/appver.go new file mode 100644 index 0000000..af2a1bf --- /dev/null +++ b/infrastructure/db/entity/mongo/appver.go @@ -0,0 +1 @@ +package mongo diff --git a/infrastructure/db/entity/mongo/privacy_setting_info.go b/infrastructure/db/entity/mongo/privacy_setting_info.go new file mode 100644 index 0000000..24a43cd --- /dev/null +++ b/infrastructure/db/entity/mongo/privacy_setting_info.go @@ -0,0 +1,21 @@ +package mongo + +type PrivacySettingInfoMongo struct { + AppId string `json:"appId" bson:"app_id"` + CommitType int `json:"commitType" bson:"commit_type"` //提交类型 + UserMessageType string `json:"userMessageType" bson:"user_message_type"` //用户使用类型 + SdkMessage string `json:"sdkMessage" bson:"sdk_message"` //sdk信息 + ContactInfoPhone string `json:"contactInfoPhone" bson:"contact_info_phone"` //联系方式 + ContactInfoEmail string `json:"contactInfoEmail" bson:"contact_info_email"` //联系方式 + ContactInfoWeChat string `json:"contactInfoWeChat" bson:"contact_info_wechat"` //联系方式 + ContactInfoOther string `json:"contactInfoOther" bson:"contact_info_other"` //联系方式 + FixedStorageTime int `json:"fixedStorageTime" bson:"fixed_storage_time"` //固定存储时间 + IsShortestTime bool `json:"isShortestTime" bson:"is_shortest_time"` //是否是最短时间 + AdditionalDocName string `json:"additionalDocName" bson:"additional_doc_name"` //补充文档名称 + AdditionalDocNetDiskId string `json:"additionalDocNetDiskId" bson:"additional_doc_netdiskid"` //补充文档网盘id + AdditionalDocContent string `json:"additionalDocContent" bson:"additional_doc_content"` //补充文档网盘id + IsFirstSave bool `json:"isFirstSave" bson:"is_first_save"` //是否第一次保存 //是否第一次保存 + EffectiveTime int64 `json:"effectiveTime" bson:"effective_time"` //生效时间 + CreateTime int64 `json:"createTime" bson:"create_time"` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"update_time"` //更新时间 +} diff --git a/infrastructure/db/entity/sql/app.go b/infrastructure/db/entity/sql/app.go new file mode 100644 index 0000000..5d7166b --- /dev/null +++ b/infrastructure/db/entity/sql/app.go @@ -0,0 +1,179 @@ +package sql + +type App struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;unique;type:varchar(48);NOT NULL;comment:'小程序id'"` + AppClass string `gorm:"column:app_class;type:varchar(48);default:'';comment:'小程序分类'"` + AppTag string `gorm:"column:app_tag;type:varchar(2056);default:'';comment:'小程序分类'"` + AppType string `gorm:"column:app_type;type:varchar(128);default:'';comment:'小程序元类型'"` + Name string `gorm:"column:name;type:varchar(48);default:'';comment:'小程序名称'"` + Logo string `gorm:"column:logo;type:varchar(1024);default:'';comment:'小程序logo'"` + Desc string `gorm:"column:desc;type:varchar(1024);default:'';comment:'小程序简介'"` + DetailDesc string `gorm:"column:detail_desc;type:varchar(1024);default:'';comment:'小程序详细描述'"` + Class string `gorm:"column:class;type:varchar(128);comment:'小程序分类'"` + CreatedBy string `gorm:"column:created_by;type:varchar(128);default:'';comment:'小程序创建人'"` + DeveloperId string `gorm:"column:developer_id;type:varchar(48);NOT NULL;comment:'开发者id'"` + GroupId string `gorm:"column:group_id;type:varchar(48);NOT NULL;comment:'企业id'"` + IsRollback int `gorm:"column:is_rollback;type:BIGINT(16);default:0;comment:'是否回滚'"` //1:回滚 + Ext string `gorm:"column:ext;type:TEXT;NOT NULL;comment:'扩展字段'"` //例如:提交审核的测试信息可以放在这里 + StatusInfo AppStatusInfo `gorm:"foreignKey:app_id;references:app_id"` + IsForbidden int `gorm:"column:is_forbidden;type:BIGINT(16);default:0;comment:'是否禁用'"` //是否禁用 0:未禁用 1:禁用 + PrivacySettingType int `gorm:"column:privacy_setting_type;type:tinyint(1);default:0;comment:'是否设置隐私'"` + ProjectType int `gorm:"column:project_type;type:tinyint(1);default:0;comment:'项目类型'"` + Expire int64 `gorm:"column:expire;type:BIGINT(16);default:0;NOT NULL;comment:'小程序过期时间'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);default:0;NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;default:0;comment:'更新时间'"` +} + +func (App) TableName() string { + return "apps" +} + +type AppV2 struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;unique;type:varchar(48);NOT NULL;comment:'小程序id'"` + AppClass string `gorm:"column:app_class;type:varchar(48);default:'';comment:'小程序分类'"` + AppTag string `gorm:"column:app_tag;type:varchar(2056);default:'';comment:'小程序分类'"` + AppType string `gorm:"column:app_type;type:varchar(128);default:'';comment:'小程序元类型'"` + Name string `gorm:"column:name;type:varchar(48);default:'';comment:'小程序名称'"` + Logo string `gorm:"column:logo;type:varchar(1024);default:'';comment:'小程序logo'"` + Desc string `gorm:"column:desc;type:varchar(1024);default:'';comment:'小程序简介'"` + DetailDesc string `gorm:"column:detail_desc;type:varchar(1024);default:'';comment:'小程序详细描述'"` + Class string `gorm:"column:class;type:varchar(128);comment:'小程序分类'"` + CreatedBy string `gorm:"column:created_by;type:varchar(128);default:'';comment:'小程序创建人'"` + DeveloperId string `gorm:"column:developer_id;type:varchar(48);NOT NULL;comment:'开发者id'"` + GroupId string `gorm:"column:group_id;type:varchar(48);NOT NULL;comment:'企业id'"` + IsRollback int `gorm:"column:is_rollback;type:BIGINT(16);default:0;comment:'是否回滚'"` //1:回滚 + Ext string `gorm:"column:ext;type:TEXT;NOT NULL;comment:'扩展字段'"` //例如:提交审核的测试信息可以放在这里 + IsForbidden int `gorm:"column:is_forbidden;type:BIGINT(16);default:0;comment:'是否禁用'"` //是否禁用 0:未禁用 1:禁用 + PrivacySettingType int `gorm:"column:privacy_setting_type;type:tinyint(1);default:0;comment:'是否设置隐私'"` + ProjectType int `gorm:"column:project_type;type:tinyint(1);default:0;comment:'项目类型'"` + Expire int64 `gorm:"column:expire;type:BIGINT(16);default:0;NOT NULL;comment:'小程序过期时间'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);default:0;NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;default:0;comment:'更新时间'"` +} + +func (AppV2) TableName() string { + return "apps" +} + +type AppStatusInfo struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;type:varchar(48);unique;NOT NULL;comment:'小程序id'"` + StatusValue string `gorm:"column:status_value;type:varchar(64);default:'';comment:'当前小程序状态信息'"` + StatusReason string `gorm:"column:status_reason;type:varchar(1024);default:'';comment:'当前小程序状态原因'"` //审核被拒等 + StatusUpdateTime int64 `gorm:"column:status_update_time;type:BIGINT(16);default:0;comment:'当前小程序状态更新时间'"` + StatusUpdater string `gorm:"column:status_updater;type:varchar(128);default:'';comment:'当前小程序状态更新人'"` + PublishedReason string `gorm:"column:published_reason;type:varchar(1024);default:'';comment:'上架信息'"` + PublishedUpdateTime int64 `gorm:"column:published_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + PublishedUpdater string `gorm:"column:published_updater;type:varchar(128);default:'';comment:'更新人'"` + UnpublishedReason string `gorm:"column:unpublished_reason;type:varchar(1024);default:'';comment:'下架信息'"` + UnpublishedUpdateTime int64 `gorm:"column:unpublished_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + UnpublishedUpdater string `gorm:"column:unpublished_updater;type:varchar(128);default:'';comment:'更新人'"` + ActionReason string `gorm:"column:action_reason;type:varchar(1024);default:'';comment:'最近更新信息'"` + ActionUpdateTime int64 `gorm:"column:action_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + ActionUpdater string `gorm:"column:action_updater;type:varchar(128);default:'';comment:'更新人'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);default:0;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` +} + +func (AppStatusInfo) TableName() string { + return "app_status_infos" +} + +type AppVersion struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;uniqueIndex:appid_seq;type:varchar(48);NOT NULL;comment:'小程序id'"` + Sequence int `gorm:"column:sequence;uniqueIndex:appid_seq;type:BIGINT(16);default:0;comment:'小程序序列号'"` + Name string `gorm:"column:name;type:varchar(48);default:'';comment:'小程序名称'"` + Logo string `gorm:"column:logo;type:varchar(1024);default:'';comment:'小程序logo'"` + Version string `gorm:"column:version;type:varchar(48);default:'';comment:'版本号'"` + Desc string `gorm:"column:desc;type:varchar(1024);default:'';comment:'小程序简介'"` + DetailDesc string `gorm:"column:detail_desc;type:varchar(1024);default:'';comment:'小程序详细描述'"` + Class string `gorm:"column:class;type:varchar(128);comment:'小程序分类'"` + Tag string `gorm:"column:tag;type:varchar(1024);NOT NULL;comment:'小程序标签'"` //例子:"a,b" + AppType string `gorm:"column:app_type;type:varchar(128);default:'';comment:'小程序元类型'"` + DeveloperId string `gorm:"column:developer_id;type:varchar(48);NOT NULL;comment:'开发者id'"` + GroupId string `gorm:"column:group_id;type:varchar(48);NOT NULL;comment:'企业id'"` + AutoPub bool `gorm:"column:auto_pub;type:bool;default:0;comment:'是否审核通过之后自动上架'"` //1:自动上架 + InGrayRelease bool `gorm:"column:in_gray_release;type:bool;default:false;comment:'是否灰度中'"` //1:灰度中 + Ext string `gorm:"column:ext;type:TEXT;NOT NULL;comment:'扩展字段'"` //例如:提交审核的测试信息可以放在这里 + BuildInfoId string `gorm:"column:build_info_id;type:varchar(48);NOT NULL;comment:'编译信息id'"` + BuildInfo AppBuildInfo `gorm:"foreignKey:build_info_id;references:trace_id"` + StatusInfo AppVersionStatusInfo `gorm:"foreignKey:app_id,sequence;references:app_id,sequence"` + CreatedBy string `gorm:"column:created_by;type:varchar(128);default:'';comment:'小程序创建人'"` + IsRollback bool `gorm:"column:is_rollback;type:bool;default:false;comment:'是否回滚'"` + TestInfo string `gorm:"column:test_info;type:TEXT;comment:'测试信息'"` + ExpireTime int64 `gorm:"column:expire_time;type:BIGINT(16);default:0;NOT NULL;comment:'小程序过期时间'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);default:0;NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;default:0;comment:'更新时间'"` +} + +func (AppVersion) TableName() string { + return "app_versions" +} + +type AppVersionV2 struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;uniqueIndex:appid_seq;type:varchar(48);NOT NULL;comment:'小程序id'"` + Sequence int `gorm:"column:sequence;uniqueIndex:appid_seq;type:BIGINT(16);default:0;comment:'小程序序列号'"` + Name string `gorm:"column:name;type:varchar(48);default:'';comment:'小程序名称'"` + Logo string `gorm:"column:logo;type:varchar(1024);default:'';comment:'小程序logo'"` + Version string `gorm:"column:version;type:varchar(48);default:'';comment:'版本号'"` + Desc string `gorm:"column:desc;type:varchar(1024);default:'';comment:'小程序简介'"` + DetailDesc string `gorm:"column:detail_desc;type:varchar(1024);default:'';comment:'小程序详细描述'"` + Class string `gorm:"column:class;type:varchar(128);comment:'小程序分类'"` + Tag string `gorm:"column:tag;type:varchar(1024);NOT NULL;comment:'小程序标签'"` //例子:"a,b" + AppType string `gorm:"column:app_type;type:varchar(128);default:'';comment:'小程序元类型'"` + DeveloperId string `gorm:"column:developer_id;type:varchar(48);NOT NULL;comment:'开发者id'"` + GroupId string `gorm:"column:group_id;type:varchar(48);NOT NULL;comment:'企业id'"` + AutoPub bool `gorm:"column:auto_pub;type:bool;default:0;comment:'是否审核通过之后自动上架'"` //1:自动上架 + InGrayRelease bool `gorm:"column:in_gray_release;type:bool;default:false;comment:'是否灰度中'"` //1:灰度中 + Ext string `gorm:"column:ext;type:TEXT;NOT NULL;comment:'扩展字段'"` //例如:提交审核的测试信息可以放在这里 + BuildInfoId string `gorm:"column:build_info_id;type:varchar(48);NOT NULL;comment:'编译信息id'"` + CreatedBy string `gorm:"column:created_by;type:varchar(128);default:'';comment:'小程序创建人'"` + IsRollback bool `gorm:"column:is_rollback;type:bool;default:false;comment:'是否回滚'"` + TestInfo string `gorm:"column:test_info;type:TEXT;comment:'测试信息'"` + ExpireTime int64 `gorm:"column:expire_time;type:BIGINT(16);default:0;NOT NULL;comment:'小程序过期时间'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);default:0;NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;default:0;comment:'更新时间'"` +} + +func (AppVersionV2) TableName() string { + return "app_versions" +} + +type AppVersionStatusInfo struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;uniqueIndex:appid_seq;type:varchar(48);NOT NULL;comment:'小程序id'"` + Sequence int `gorm:"column:sequence;uniqueIndex:appid_seq;type:BIGINT(16);default:0;comment:'小程序序列号'"` + StatusValue string `gorm:"column:status_value;type:varchar(64);default:'';comment:'当前小程序状态信息'"` + StatusReason string `gorm:"column:status_reason;type:varchar(1024);default:'';comment:'当前小程序状态原因'"` //审核被拒等 + StatusUpdateTime int64 `gorm:"column:status_update_time;type:BIGINT(16);default:0;comment:'当前小程序状态更新时间'"` + StatusUpdater string `gorm:"column:status_updater;type:varchar(128);default:'';comment:'当前小程序状态更新人'"` + PublishingReason string `gorm:"column:publishing_reason;type:varchar(1024);default:'';comment:'小程序提交审核信息'"` + PublishingUpdateTime int64 `gorm:"column:publishing_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + PublishingUpdater string `gorm:"column:publishing_updater;type:varchar(128);default:'';comment:'更新人'"` + PublishedReason string `gorm:"column:published_reason;type:varchar(1024);default:'';comment:'上架信息'"` + PublishedUpdateTime int64 `gorm:"column:published_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + PublishedUpdater string `gorm:"column:published_updater;type:varchar(128);default:'';comment:'更新人'"` + UnpublishedReason string `gorm:"column:unpublished_reason;type:varchar(1024);default:'';comment:'下架信息'"` + UnpublishedUpdateTime int64 `gorm:"column:unpublished_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + UnpublishedUpdater string `gorm:"column:unpublished_updater;type:varchar(128);default:'';comment:'更新人'"` + UnpublishedType string `gorm:"column:unpublished_type;type:varchar(256);default:'';comment:'下架类型'"` + ApprovalReason string `gorm:"column:approval_reason;type:varchar(1024);default:'';comment:'审核信息'"` + ApprovalUpdateTime int64 `gorm:"column:approval_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + ApprovalUpdater string `gorm:"column:approval_updater;type:varchar(128);default:'';comment:'更新人'"` + ActionReason string `gorm:"column:action_reason;type:varchar(1024);default:'';comment:'最近更新信息'"` + ActionUpdateTime int64 `gorm:"column:action_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + ActionUpdater string `gorm:"column:action_updater;type:varchar(128);default:'';comment:'更新人'"` + PublishingApprovalReason string `gorm:"column:publishing_approval_reason;type:varchar(1024);default:'';comment:'审核通过信息'"` + PublishingApprovalUpdateTime int64 `gorm:"column:publishing_approval_update_time;type:BIGINT(16);default:0;comment:'更新时间'"` + PublishingApprovalUpdater string `gorm:"column:publishing_approval_updater;type:varchar(128);default:'';comment:'更新人'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` +} + +func (AppVersionStatusInfo) TableName() string { + return "app_version_status_infos" +} diff --git a/infrastructure/db/entity/sql/app_build_info.go b/infrastructure/db/entity/sql/app_build_info.go new file mode 100644 index 0000000..78f3170 --- /dev/null +++ b/infrastructure/db/entity/sql/app_build_info.go @@ -0,0 +1,59 @@ +package sql + +//AppStartParams 小程序启动参数 + +type AppBuildInfo struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + TraceId string `gorm:"column:trace_id;type:varchar(64);unique;comment:'唯一Id'"` + BuildInfoId string `gorm:"column:build_info_id;type:varchar(64);comment:'编译信息Id'"` + Source string `gorm:"column:source;type:varchar(64);comment:'上传版本的状态'"` // 该上传版本的状态: build:正常版本, trail:被设置为体验版 + AppId string `gorm:"column:app_id;type:varchar(64);comment:'小程序id'"` + GroupID string `gorm:"column:group_id;type:varchar(64);comment:'组id'"` + UserId string `gorm:"column:user_id;type:varchar(64);comment:'用户id'"` + CreatedBy string `gorm:"column:created_by;type:varchar(512);comment:'创建人'"` + Status bool `gorm:"column:status;type:bool;comment:'status';comment:'编译状态'"` //编译状态 + Version string `gorm:"column:version;type:varchar(64);comment:'上传版本号'"` + VersionDescription string `gorm:"column:version_description;type:varchar(2048);comment:'版本描述'"` + FileMd5 string `gorm:"column:file_md5;type:varchar(512);default:'';comment:'md5'"` + Name string `gorm:"column:name;type:varchar(256);default:'';comment:'包名'"` + SourceFileUrl string `gorm:"column:source_url;type:varchar(512);default:'';comment:'源码包下载地址'"` + Url string `gorm:"column:url;type:varchar(512);default:'';comment:'编译包下载地址'"` + EncryptedUrl string `gorm:"column:encrypted_url;type:varchar(512);default:'';comment:'加密后下载地址'"` + EncryptedFileMd5 string `gorm:"column:encrypted_file_md5;type:varchar(512);default:'';comment:'加密包md5'"` + EncryptedFileSha256 string `gorm:"column:encrypted_file_sha256;type:varchar(512);default:'';comment:'加密包sha256'"` + BasicPackVer string `gorm:"column:basic_pack_ver;type:varchar(48);default:'';comment:'基础库版本'"` + Packages string `gorm:"column:packages;type:TEXT;comment:'分包信息'"` + EncryptPackages string `gorm:"column:encrypt_packages;type:TEXT;comment:'加密分包信息'"` + PathAndQuery string `gorm:"column:path_and_query;type:varchar(256);comment:'启动页面path和query'"` + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);NOT NULL;comment:'创建时间'"` + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` +} + +func (AppBuildInfo) TableName() string { + return "app_build_infos" +} + +type BuildInfo struct { + Id string `json:"id" gorm:"primary_key;column:id;type:varchar(64);comment:'编译id'" sql:"primary_key" bson:"id"` + AppId string `json:"appId" gorm:"column:app_id;type:varchar(64);comment:'App id'" bson:"appId"` + UserId string `json:"userId" gorm:"column:user_id;type:varchar(64);default:0;comment:'用户id'" bson:"userId"` //用户id + Filename string `json:"filename" gorm:"column:file_name;type:varchar(64);default:'';comment:'文件名'" bson:"filename"` //文件名 + FileUrl string `json:"fileUrl" gorm:"column:file_url;type:varchar(128);default:'';comment:'文件地址'" bson:"fileUrl"` //文件地址 + Content string `json:"content" gorm:"column:content;type:text;comment:''" bson:"content"` //content + Version string `json:"version" gorm:"column:version;type:varchar(64);default:'';comment:'版本'" bson:"version"` //版本 + VersionRemark string `json:"versionRemark" gorm:"column:version_remark;type:varchar(256);default:'';comment:'VersionRemark'" bson:"versionRemark"` //VersionRemark + OrganId string `json:"organId" gorm:"column:organ_id;type:varchar(64);default:'';comment:'机构id'" bson:"organId"` //机构id + Username string `json:"username" gorm:"column:user_name;type:varchar(64);default:'';comment:'用户名'" bson:"username"` //用户名 + CreateTime int64 `json:"createTime" gorm:"column:create_time;type:BIGINT(16);default:0;comment:'创建时间'" bson:"createTime"` //创建时间 + UpdateTime int64 `json:"updateTime" gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'" bson:"updateTime"` //更新时间 + EncryptedUrl string `json:"encryptedUrl" gorm:"column:encrypted_url;type:varchar(128);default:'';comment:'文件加密地址'" bson:"encryptedUrl"` + Status string `json:"status" gorm:"column:status;type:varchar(64);default:'';comment:''" bson:"status"` + Packages string `bson:"packages" gorm:"column:packages;type:TEXT;NOT NULL;comment:'内容'"` + EncryptPackage string `bson:"encryptPackage" gorm:"column:encryptPackage;type:TEXT;NOT NULL;comment:'内容'"` + Cmd string `json:"cmd" gorm:"column:cmd;type:varchar(64);default:'';comment:'编译上传类型'" bson:"cmd"` //cmd:为空默认编译上传 create:不编译直接上传 directUploadSource: 直接上传源文件 + BuildStatus string `json:"buildStatus" gorm:"column:buildStatus;type:varchar(64);default:'';comment:'编译状态'" bson:"buildStatus"` //编译中(during),编译成功(success),编译失败(failed) +} + +func (BuildInfo) TableName() string { + return "build_info" +} diff --git a/infrastructure/db/entity/sql/privacy_setting_info.go b/infrastructure/db/entity/sql/privacy_setting_info.go new file mode 100644 index 0000000..68e4dcd --- /dev/null +++ b/infrastructure/db/entity/sql/privacy_setting_info.go @@ -0,0 +1,26 @@ +package sql + +type PrivacySettingInfo struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppId string `gorm:"column:app_id;type:varchar(64);comment:'小程序id'"` + CommitType int `gorm:"column:commit_type;type:tinyint(1);default:1;comment:'提交类型'"` //提交类型 + UserMessageType string `gorm:"column:user_message_type;type:TEXT;comment:'用户使用类型'"` //用户使用类型 + SdkMessage string `gorm:"column:sdk_message;type:TEXT;comment:'sdk信息'"` //sdk信息 + ContactInfoPhone string `gorm:"column:contact_info_phone;type:varchar(128);default:'';comment:'联系方式'"` //联系方式 + ContactInfoEmail string `gorm:"column:contact_info_email;type:varchar(128);default:'';comment:'联系方式'"` //联系方式 + ContactInfoWeChat string `gorm:"column:contact_info_wechat;type:varchar(128);default:'';comment:'联系方式'"` //联系方式 + ContactInfoOther string `gorm:"column:contact_info_other;type:varchar(128);default:'';comment:'联系方式'"` //联系方式 + FixedStorageTime int `gorm:"column:fixed_storage_time;type:BIGINT(16);default:0;comment:'固定存储时间'"` //固定存储时间 + IsShortestTime bool `gorm:"column:is_shortest_time;type:bool;default:false;comment:'是否是最短时间'"` //是否是最短时间 + AdditionalDocName string `gorm:"column:additional_doc_name;type:varchar(128);default:'';comment:'补充文档名称'"` //补充文档名称 + AdditionalDocNetDiskId string `gorm:"column:additional_doc_net_disk_id;type:varchar(64);default:'';comment:'补充文档网盘id'"` //补充文档网盘id + AdditionalDocContent string `gorm:"column:additional_doc_content;type:mediumtext;comment:'补充文档内容'"` //补充文档网盘id + IsFirstSave bool `gorm:"column:is_first_save;type:bool;default:false;comment:'是否第一次保存'"` //是否第一次保存 //是否第一次保存 + EffectiveTime int64 `gorm:"column:effective_time;type:BIGINT(16);default:0;comment:'生效时间'"` //生效时间 + CreateTime int64 `gorm:"column:create_time;type:BIGINT(16);NOT NULL;comment:'创建时间'"` //创建时间 + UpdateTime int64 `gorm:"column:update_time;type:BIGINT(16);default:0;comment:'更新时间'"` //更新时间 +} + +func (PrivacySettingInfo) TableName() string { + return "privacy_setting_info" +} diff --git a/infrastructure/db/repo/db_init.go b/infrastructure/db/repo/db_init.go new file mode 100644 index 0000000..180cdc9 --- /dev/null +++ b/infrastructure/db/repo/db_init.go @@ -0,0 +1,116 @@ +package impl + +import ( + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/db/repo/mongo" + "finclip-app-manager/infrastructure/db/repo/mysql" +) + +func InitAppRepo() repository.AppRepository { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.AppRepo{} + default: + return &mongo.AppRepo{} + } +} + +func InitBuildInfoRepo() repository.IAppBuildInfoRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.AppBuildInfoMysqlRepo{} + default: + return &mongo.AppBuildInfoMongoRepo{} + } +} + +func InitBindingRepo() repository.IBindingRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.BindingByMysqlRepo{} + default: + return &mongo.BindingByMongoRepo{} + } +} + +func InitBundleRepo() repository.IBundleRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.BundleByMysqlRepo{} + default: + return &mongo.BundleByMongoRepo{} + } +} + +func InitMenuInfoRepo() repository.IMenuInfoRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.MenuInfoByMysqlRepo{} + default: + return &mongo.MenuInfoByMongoRepo{} + } +} + +func InitQrCodeInfoRepo() repository.IQrCodeInfoRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.QrCodeInfoByMysqlRepo{} + default: + return &mongo.QrCodeInfoByMongoRepo{} + } +} + +func InitTypeConfigRepo() repository.ITypeConfigRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.TypeConfigByMysqlRepo{} + default: + return &mongo.TypeConfigByMongoRepo{} + } +} + +func InitLinkAuditRepo() repository.ILinkAuditRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.LinkAuditByMysqlRepo{} + default: + return &mongo.LinkAuditByMongoRepo{} + } +} + +func InitRedDotRepo() repository.IRedDotRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.RedDotByMysqlRepo{} + default: + return &mongo.RedDotByMongoRepo{} + } +} + +func InitAppTempInfoRepo() repository.IAppTempInfoRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.AppTempInfoByMysqlRepo{} + default: + return &mongo.AppTempInfoByMongoRepo{} + } +} + +func InitPrivacySettingRepo() repository.IPrivacySettingRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.PrivacySettingRepoMysqlRepo{} + default: + return &mongo.PrivacySettingRepoMongoRepo{} + } +} + +func InitAppOperConfigRepo() repository.IAppOperConfigRepo { + switch config.GetConfig().DBMode { + case "mysql": + return &mysql.AppOperConfigRepo{} + default: + return &mongo.AppOperConfigRepo{} + } +} diff --git a/infrastructure/db/repo/mongo/app.go b/infrastructure/db/repo/mongo/app.go new file mode 100644 index 0000000..56af2b4 --- /dev/null +++ b/infrastructure/db/repo/mongo/app.go @@ -0,0 +1,1055 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/infrastructure/db/entity/mongo" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + "time" + + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +type AppRepo struct { +} + +func NewAppRepo() *AppRepo { + return &AppRepo{} +} + +func (ar *AppRepo) AppCount(ctx context.Context, organId string) (int, error) { + match := bson.M{"isForbidden": 0} + if organId != "" { + match["organId"] = organId + } + return appTable.Count(ctx, match) +} + +func (ar *AppRepo) InsertApp(ctx context.Context, info entity.App) error { + mgoInfo := tr.CovertAppToMgo(&info) + return appTable.Insert(ctx, mgoInfo) +} + +func (ar *AppRepo) InsertAppVer(ctx context.Context, info entity.AppVersion) error { + mgoInfo := tr.CovertAppVerToMgo(&info) + return appVerTable.Insert(ctx, mgoInfo) +} + +func (ar *AppRepo) GetAppInfo(ctx context.Context, appId string) (entity.App, error) { + mgoInfo := mongo.App{} + err := appTable.GetOne(ctx, bson.M{"appId": appId}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.App{}, entity.NotFoundErr + } + log.Errorf("GetAppInfo err:%s", err.Error()) + return entity.App{}, err + } + return *tr.CovertAppToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) UpdateApp(ctx context.Context, info entity.App) error { + mgoInfo := tr.CovertAppToMgo(&info) + return appTable.UpSert(bson.M{"appId": info.AppID}, mgoInfo) +} + +func (ar *AppRepo) GetAppVerInfo(ctx context.Context, appId string, seq int) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + err := appVerTable.GetOne(ctx, bson.M{"appId": appId, "sequence": seq}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + log.Errorf("GetAppInfo err:%s", err.Error()) + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) GetOnlineAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + match := bson.M{"appId": appId, "status.value": entity.StPublished} + err := appVerTable.GetSortOne(ctx, match, []string{"-sequence"}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) SubmitApp(ctx context.Context, req entity.SubmitAppReq, expire int64, userId string) error { + nowMaxSeq := 0 + maxAppVerInfo, err := ar.GetMaxSeqAppVer(ctx, req.AppId) + if err == nil { + nowMaxSeq = maxAppVerInfo.Sequence + } else { + if err != entity.NotFoundErr { + return err + } + } + buildInfo, err := NewAppBuildInfoMongoRepo().GetInfoById(ctx, req.BuildId) + if NotFound(err) { + buildInfo, err = NewAppBuildInfoMongoRepo().GetInfoByBuildId(ctx, req.BuildId) + if err != nil { + return err + } + } + log.Debugln("SubmitApp buildInfo:%+v", buildInfo) + appInfo, err := ar.GetAppInfo(ctx, req.AppId) + if err != nil { + return err + } + now := utils.GetNowMs() + appVerInfo := mongo.AppVersion{ + AppID: appInfo.AppID, + Name: appInfo.Name, + AppClass: appInfo.AppClass, + AppTag: appInfo.AppTag, + AppType: entity.AppTypeApplet, + Status: mongo.Status{ + Reason: "", + Value: entity.StPublishing, + LastUpdated: now, + ModifiedBy: req.Account, + }, + PublishingStatus: mongo.SpecificStatus{ + Reason: "", + LastUpdated: now, + ModifiedBy: req.Account, + }, + UnpublishingStatus: mongo.SpecificStatus{}, + PublishingApprovalStatus: mongo.SpecificStatus{}, + UnpublishingApprovalStatus: mongo.SpecificStatus{}, + PublishedStatus: mongo.SpecificStatus{}, + UnpublishedStatus: mongo.UnpublishedStatus{}, + RequestStatus: mongo.SpecificStatus{}, + ApprovalStatus: mongo.SpecificStatus{}, + ActionStatus: mongo.SpecificStatus{ + Reason: "", + LastUpdated: now, + ModifiedBy: req.Account, + }, + DeveloperID: userId, + GroupID: appInfo.GroupID, + Created: now, + CreatedBy: req.Account, + CustomData: tr.CovertCustomDataToMgo(buildInfo.CustomData), + Version: buildInfo.Version, + Sequence: nowMaxSeq + 1, + CoreDescription: appInfo.CoreDescription, + Logo: appInfo.Logo, + TestInfo: tr.CovertTestInfoToMgo(req.TestInfo), + NeedAutoPub: req.NeedAutoPub, + InGrayRelease: false, + Expire: expire, + AppBuildID: req.BuildId, + } + appVerInfo.CustomData.DetailDescription = appInfo.CustomData.DetailDescription + + return appVerTable.Insert(ctx, appVerInfo) +} + +func (ar *AppRepo) WithdrawPubApp(ctx context.Context, appId string, seq int, account string) error { + params := map[string]interface{}{} + now := utils.GetNowMs() + params["status"] = mongo.Status{ + Value: entity.StPublishWithdrawed, + LastUpdated: now, + ModifiedBy: account, + } + filter := bson.M{ + "appId": appId, + "sequence": seq, + } + return appVerTable.UpdateOne(ctx, filter, bson.M{"$set": params}) +} + +func (ar *AppRepo) GetMaxSeqAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + match := bson.M{"appId": appId} + err := appVerTable.GetSortOne(ctx, match, []string{"-sequence"}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) GetLatestPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + match := bson.M{"appId": appId, "publishedStatus.lastUpdated": bson.M{"$ne": 0}} + err := appVerTable.GetSortOne(ctx, match, []string{"-publishedStatus.lastUpdated"}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) UpdateAppVerAppName(ctx context.Context, appId, appName string) error { + return nil +} + +func (ar *AppRepo) GetNowPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + match := bson.M{"appId": appId, "status.value": entity.StPublished} + err := appVerTable.GetSortOne(ctx, match, []string{"-status.lastUpdated"}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) GetLatestReviewAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + mgoInfo := mongo.AppVersion{} + //match := bson.M{"appId": appId, "status.value": bson.M{"$in": []string{entity.StPublishing, entity.StPublishWithdrawed, entity.StPublishApproved, entity.StPublishRejected, entity.StPublished, entity.StUnpublished}}} + match := bson.M{"appId": appId, "publishingStatus.lastUpdated": bson.M{"$ne": 0}} + err := appVerTable.GetSortOne(ctx, match, []string{"-sequence"}, &mgoInfo) + if err != nil { + if NotFound(err) { + return entity.AppVersion{}, entity.NotFoundErr + } + return entity.AppVersion{}, err + } + return *tr.CovertAppVerToEntity(&mgoInfo), nil +} + +func (ar *AppRepo) GetAllPermitGrayPubVers(ctx context.Context, appId string, maxSeq int) ([]entity.AppVersion, error) { + filter := bson.M{"appId": appId, "status.value": entity.StPublishApproved, "sequence": bson.M{"$gt": maxSeq}} + list := make([]mongo.AppVersion, 0) + _, err := appVerTable.GetAll(ctx, filter, []string{"-sequence"}, &list) + if err != nil { + return nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) PubApp(ctx context.Context, appId string, seq int, account string, isDev, isRollback bool) error { + //结束所有低版本的灰度 + err := appVerTable.UpdateAll(ctx, bson.M{"appId": appId, "sequence": bson.M{"$lte": seq}}, bson.M{"$set": bson.M{"inGrayRelease": false}}) + if err != nil { + return err + } + now := time.Now().UnixNano() / 1e6 + //下架之前上架的小程序版本 + oldAppVer, err := ar.GetNowPubAppVer(ctx, appId) + if err != nil && !NotFound(err) { + return err + } + if !NotFound(err) { + unpublishedStatus := mongo.UnpublishedStatus{ + LastUpdated: now, + ModifiedBy: account, + Type: entity.TypeUnpublishedDueToNewSeq, // Mark the type. + } + //if !isDev { + // unpublishedStatus.Type = entity.TypeUnpublishedByAdmin + //} + unPubUpInfo := map[string]interface{}{ + "unpublishedStatus": unpublishedStatus, + "status": mongo.Status{ + Value: entity.StUnpublished, + LastUpdated: now, + ModifiedBy: account, + }, + } + err = appVerTable.UpdateOne(ctx, bson.M{"appId": oldAppVer.AppID, "sequence": oldAppVer.Sequence}, bson.M{"$set": unPubUpInfo}) + if err != nil { + return err + } + } + //上架当前小程序版本 + upInfo := make(map[string]interface{}) + upInfo["status"] = mongo.Status{ + Value: entity.StPublished, + Reason: "", + LastUpdated: now, + ModifiedBy: account, + } + upInfo["publishedStatus"] = mongo.SpecificStatus{ + Reason: "", + LastUpdated: now, + ModifiedBy: account, + } + upInfo["actionStatus"] = mongo.SpecificStatus{ + LastUpdated: now, + ModifiedBy: account, + } + //修改小程序元数据信息 + err = appTable.UpdateOne(ctx, bson.M{"appId": appId}, bson.M{"$set": upInfo}) + if err != nil { + return err + } + upInfo["isRollback"] = isRollback + err = appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": upInfo}) + if err != nil { + return err + } + return nil +} + +func (ar *AppRepo) ListApps(ctx context.Context, groupId string, pageNo, pageSize int, searchText string, sortType, pullType string) (int, []entity.App, error) { + list := make([]mongo.App, 0) + sortList := make([]string, 0) + switch sortType { + case "-created": + sortList = append(sortList, "-created") //按创建时间倒序排序 + case "created": + sortList = append(sortList, "created") //按创建时间正序排序 + case "-expire": + sortList = append(sortList, "-expire") //按过期时间倒序排序 + case "expire": + sortList = append(sortList, "expire") //按过期时间正序排序 + default: + sortList = append(sortList, "-created") + + } + filter := bson.M{} + if groupId != "" { + filter["groupId"] = groupId + } + if searchText != "" { + r := bson.RegEx{Pattern: searchText, Options: "i"} + filter["$or"] = []bson.M{{"name": r}, {"appId": r}} + } + switch pullType { + case "published": + filter["status.value"] = entity.StPublished + } + total, err := appTable.GetSome(ctx, filter, sortList, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return total, result, err +} + +func (ar *AppRepo) ListAppVers(ctx context.Context, pageNo, pageSize int, searchText string, t string, groupId string) (int, []entity.AppVersion, error) { + filter := bson.M{} + filterList := make([]bson.M, 0) + if groupId != "" { + filterList = append(filterList, bson.M{ + "groupId": groupId, + }) + } + filterList = append(filterList, bson.M{ + "sequence": bson.M{"$ne": 0}, + }) + if searchText != "" { + r := bson.RegEx{Pattern: searchText, Options: "i"} + filterList = append(filterList, bson.M{"$or": []bson.M{ + {"name": r}, + {"appId": r}, + }}) + } + sortList := make([]string, 0) + sortList = append(sortList, "-publishingStatus.lastUpdated") + switch t { + case "pendingReview": //待审核 + filterList = append(filterList, bson.M{"status.value": bson.M{"$in": []string{entity.StPublishing, entity.StUnpublishing}}}) + case "reviewed": //已审核 + filterList = append(filterList, bson.M{"status.value": bson.M{"$nin": []string{entity.StPublishing, entity.StPublishWithdrawed}}}) + case "revoked": //已撤销 + //PublishWithdrawed + filterList = append(filterList, bson.M{"status.value": bson.M{"$in": []string{entity.StPublishWithdrawed}}}) + //default: + } + filter["$and"] = filterList + log.Debugln("filter:%v", filter) + list := make([]mongo.AppVersion, 0) + total, err := appVerTable.GetSome(ctx, filter, sortList, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) UnpubApp(ctx context.Context, appId string, seq int, account, reason string, isDev bool) error { + unpublishedType := "" + if isDev { + unpublishedType = entity.TypeUnpublishedByDev + } else { + unpublishedType = entity.TypeUnpublishedByAdmin + } + now := time.Now().UnixNano() / 1e6 + params := map[string]interface{}{} + params["status"] = mongo.Status{ + Value: entity.StUnpublished, + ModifiedBy: account, + LastUpdated: now, + Reason: reason, + } + params["unpublishedStatus"] = mongo.UnpublishedStatus{ + ModifiedBy: account, + LastUpdated: now, + Reason: reason, + Type: unpublishedType, + } + params["actionStatus"] = mongo.SpecificStatus{ + ModifiedBy: account, + LastUpdated: now, + Reason: reason, + } + err := appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": params}) + if err != nil { + return err + } + return appTable.UpdateOne(ctx, bson.M{"appId": appId}, bson.M{"$set": params}) +} + +func (ar *AppRepo) ApproveApp(ctx context.Context, appId string, seq int, account, reason string, isPass bool) error { + params := map[string]interface{}{} + now := utils.GetNowMs() + if isPass { + params["status"] = entity.Status{ + Value: entity.StPublishApproved, + LastUpdated: now, + ModifiedBy: account, + Reason: reason, + } + } else { + params["status"] = entity.Status{ + Value: entity.StPublishRejected, + LastUpdated: now, + ModifiedBy: account, + Reason: reason, + } + } + params["publishingApprovalStatus"] = mongo.SpecificStatus{ + LastUpdated: now, + ModifiedBy: account, + Reason: reason, + } + params["approvalStatus"] = mongo.SpecificStatus{ + LastUpdated: now, + ModifiedBy: account, + Reason: reason, + } + return appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": params}) +} + +func (ar *AppRepo) ListAppVersByAppId(ctx context.Context, appId string, pageNo, pageSize int) (int, []entity.AppVersion, error) { + filter := bson.M{ + "appId": appId, + "sequence": bson.M{"$ne": 0}, + "status.value": bson.M{"$ne": entity.StDeleted}, + } + list := make([]mongo.AppVersion, 0) + total, err := appVerTable.GetSome(ctx, filter, []string{"-sequence"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) GetAppReviews(ctx context.Context, req apiproto.AdminGetAppReviewsReq) (int, []entity.AppVersion, error) { + return 0, nil, nil +} + +func (ar *AppRepo) GetAllPublishedVerList(ctx context.Context, appId string) ([]entity.AppVersion, int, error) { + filter := bson.M{ + "appId": appId, + "status.value": entity.StPublished, + } + list := make([]mongo.AppVersion, 0) + total, err := appVerTable.GetAll(ctx, filter, []string{"-sequence"}, &list) + if err != nil { + return nil, 0, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, total, nil +} + +func (ar *AppRepo) GetPublishedAppList(ctx context.Context, pageNo, pageSize int, searchText string) ([]entity.AppVersion, int, error) { + filter := bson.M{ + "status.value": entity.StPublished, + } + if searchText != "" { + r := bson.RegEx{Pattern: searchText, Options: "i"} + filter["$or"] = []bson.M{ + {"name": r}, + {"appId": r}, + } + } + list := make([]mongo.AppVersion, 0) + total, err := appVerTable.GetSome(ctx, filter, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return nil, 0, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, total, nil +} + +func (ar *AppRepo) GetAllVers(ctx context.Context, appId string) ([]entity.AppVersion, int, error) { + filter := bson.M{ + "appId": appId, + } + list := make([]mongo.AppVersion, 0) + total, err := appVerTable.GetAll(ctx, filter, []string{"-sequence"}, &list) + if err != nil { + return nil, 0, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, total, nil +} + +func (ar *AppRepo) GetAppsByAppIds(ctx context.Context, appIds []string) ([]entity.App, error) { + list := make([]mongo.App, 0) + _, err := appTable.GetAllV2(ctx, bson.M{"appId": bson.M{"$in": appIds}}, []string{"-created"}, &list) + if err != nil { + return nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetAppsByGroupIds(ctx context.Context, groupIds []string) (int, []entity.App, error) { + list := make([]mongo.App, 0) + total, err := appTable.GetAllV2(ctx, bson.M{"groupId": bson.M{"$in": groupIds}}, []string{"-created"}, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) GetAppsToBinding(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) { + br := NewBindingByMongoRepo() + bindingInfo, err := br.GetBindingByBindingId(ctx, bindingId) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfo.AppInfos { + assAppIdList = append(assAppIdList, v.AppID) + } + filter := bson.M{"groupId": bindingInfo.GroupID, "appId": bson.M{"$nin": assAppIdList}} + if searchText != "" { + filter["name"] = bson.RegEx{ + Pattern: searchText, + Options: "i", + } + } + list := make([]mongo.App, 0) + total, err := appTable.GetSome(ctx, filter, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) GetLinkAppsByBindingId(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) { + br := NewBindingByMongoRepo() + bindingInfo, err := br.GetBindingByBindingId(ctx, bindingId) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfo.AppInfos { + assAppIdList = append(assAppIdList, v.AppID) + } + list := make([]mongo.App, 0) + total, err := appTable.GetSome(ctx, bson.M{"groupId": bindingInfo.GroupID, "appId": bson.M{"$in": assAppIdList}}, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) GetLinkAppsBySDKKey(ctx context.Context, sdkKey string, pageNo, pageSize int) (int, []entity.App, error) { + br := NewBindingByMongoRepo() + bindingInfos, err := br.GetBindListBySdkKey(ctx, sdkKey) + log.Infof(utility.InterfaceToJsonString(bindingInfos)) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfos { + for _, y := range v.AppInfos { + assAppIdList = append(assAppIdList, y.AppID) + } + } + + list := make([]mongo.App, 0) + total, err := appTable.GetSome(ctx, bson.M{"status.value": entity.StPublished, "appId": bson.M{"$in": assAppIdList}}, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return total, result, nil +} + +func (ar *AppRepo) AdminGetLinkApps(ctx context.Context, pageNo, pageSize int, searchText string) (int, []entity.AdminGetLinkAppsRspItem, error) { + //这里需要连接三个表 app表、binding表、typeConfig表 + //todo 做优化的时候进行修改 + type TempItem struct { + Id bson.ObjectId `bson:"_id"` + AppIdDetail struct { + AppId string `bson:"appId"` + Name string `bson:"name"` + Sequence int `bson:"sequence"` + } `bson:"appIdDetail"` + AppInfos struct { + AssociatedAt int64 `bson:"associatedAt"` + } `bson:"app_infos"` + BindingId string `bson:"binding_id"` + GroupName string `bson:"group_name"` + Name string `bson:"name"` + } + binds := make([]TempItem, 0) + //连接app表 + lookupFind := bson.M{"from": AppTableName, "localField": "app_infos.appId", "foreignField": "appId", "as": "appIdDetail"} + //分组 + unwindValue := "$app_infos" + //小程序创建时间倒序 + sortValue := bson.M{"app_infos.associatedAt": -1} + skipValue := pageNo * pageSize + limitValue := pageSize + //模糊匹配 + matchValue := bson.M{ + "$or": []bson.M{ + {"name": bson.M{"$regex": bson.RegEx{Pattern: searchText, Options: "i"}}}, + {"appIdDetail.name": bson.M{"$regex": bson.RegEx{Pattern: searchText, Options: "i"}}}, + {"group_name": bson.M{"$regex": bson.RegEx{Pattern: searchText, Options: "i"}}}, + }, + } + //typeConfig 小程序开发匹配namespace为appClass的 + //typeConfigMatchValue := bson.M{"appClassDetail.namespace": "appClass"} + //需要的字段 + projectValue := bson.M{ + "binding_id": 1, + "appClassDetail.customData.chinese": 1, + "appIdDetail.name": 1, + "appIdDetail.appId": 1, + "appIdDetail.sequence": 1, + "name": 1, + "group_name": 1, + "app_infos.associatedAt": 1, + } + //连接typeConfig表 + //appClassLookup := bson.M{"from": "typeConfig", "localField": "appIdDetail.appClass", "foreignField": "value", "as": "appClassDetail"} + pipSelector := []bson.M{ + {"$unwind": unwindValue}, + {"$lookup": lookupFind}, + {"$match": matchValue}, + {"$sort": sortValue}, + {"$skip": skipValue}, + {"$limit": limitValue}, + {"$unwind": "$appIdDetail"}, + //{"$lookup": appClassLookup}, + //{"$match": typeConfigMatchValue}, + //{"$unwind": "$appClassDetail"}, + {"$project": projectValue}, + } + countSelector := []bson.M{ + {"$unwind": unwindValue}, + {"$lookup": lookupFind}, + {"$match": matchValue}, + {"$group": bson.M{"_id": nil, "total": bson.M{"$sum": 1}}}, + } + log.Infof("pipe selector:%+v,countSelector:%+v\n", pipSelector, countSelector) + err := bindingTable.Aggregate(ctx, pipSelector, &binds) + if err != nil && !NotFound(err) { + return 0, nil, err + } + total, err := bindingTable.AggregateCount(ctx, countSelector) + if err != nil { + return 0, nil, err + } + result := make([]entity.AdminGetLinkAppsRspItem, 0) + for _, v := range binds { + item := entity.AdminGetLinkAppsRspItem{} + item.Id = v.Id.Hex() + item.AppIdDetail.AppId = v.AppIdDetail.AppId + item.AppIdDetail.Name = v.AppIdDetail.Name + item.AppIdDetail.Sequence = v.AppIdDetail.Sequence + item.AppInfos.AssociatedAt = v.AppInfos.AssociatedAt + item.BindingId = v.BindingId + item.GroupName = v.GroupName + item.Name = v.Name + + result = append(result, item) + } + return total, result, nil +} + +func (ar *AppRepo) UpdateGrayStatus(ctx context.Context, appId string, seq int, status bool) error { + err := appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": bson.M{"inGrayRelease": status}}) + if err != nil { + return err + } + return nil +} + +func (ar *AppRepo) UpdateExpire(ctx context.Context, appId string, expire int64) error { + err := appTable.UpdateOne(ctx, bson.M{"appId": appId}, bson.M{"$set": bson.M{"expire": expire}}) + if err != nil { + return err + } + + return nil +} + +func (ar *AppRepo) UpdateExpireAppVersion(ctx context.Context, appId string, seq int, expire int64) error { + err := appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": bson.M{"expire": expire}}) + if err != nil { + return err + } + + return nil +} + +func (ar *AppRepo) GetRollbackAbleList(ctx context.Context, groupId, appId string, latestPubSeq int) ([]entity.AppVersion, error) { + appVers := make([]mongo.AppVersion, 0) + limitVersion := 5 // 最近5个版本, 不是最近下架的5个版本 + filter := bson.M{ + "appId": appId, + "groupId": groupId, + "status.value": bson.M{"$eq": entity.StUnpublished}, + "sequence": bson.M{"$gte": latestPubSeq - limitVersion, "$lt": latestPubSeq}, + "$or": []bson.M{ + {"unpublishedStatus.type": entity.TypeUnpublishedByDev}, + {"unpublishedStatus.type": entity.TypeUnpublishedDueToNewSeq}, + }, + } + _, err := appVerTable.GetSome(ctx, filter, []string{"-sequence"}, limitVersion, 1, &appVers) + if err != nil { + return nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range appVers { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetCreatedStatistics(ctx context.Context, startTime, endTime int64, groupId string, isForbidden int) (int, error) { + filter := bson.M{} + if groupId != "" { + filter["groupId"] = groupId + } + if startTime != -1 && startTime != 0 { + filter["created"] = bson.M{"$gt": startTime} + } + if endTime != -1 && endTime != 0 { + if _, ok := filter["created"]; ok { + filter["created"] = bson.M{"$gt": startTime, "$lte": endTime} + } + } + switch isForbidden { + case entity.APP_FORBIDDEN_NOT_STATUS: + filter["$or"] = []bson.M{{"isForbidden": entity.APP_FORBIDDEN_NOT_STATUS}, {"isForbidden": bson.M{"$exists": false}}} + case entity.APP_FORBIDDEN_IS_STATUS: + filter["isForbidden"] = entity.APP_FORBIDDEN_IS_STATUS + } + log.Debugf("GetCreatedStatistics filter:%+v", filter) + return appTable.Count(ctx, filter) +} + +func (ar *AppRepo) GetPublishedStatistics(ctx context.Context, startTime, endTime int64, groupId string) (int, error) { + filter := bson.M{} + if groupId != "" { + filter["groupId"] = groupId + } + if startTime != -1 && startTime != 0 { + filter["publishedStatus.lastUpdated"] = bson.M{"$gt": startTime} + } + if endTime != -1 && endTime != 0 { + filter["publishedStatus.lastUpdated"] = bson.M{"$gt": startTime, "$lte": endTime} + } + filter["status.value"] = entity.StPublished + return appTable.Count(ctx, filter) +} + +//GetSubmittedStatistics 累计审核的小程序----只要小程序被审核过都算 +func (ar *AppRepo) GetSubmittedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) { + filter := bson.M{} + if groupId != "" { + filter["groupId"] = groupId + } + if startTime != -1 && startTime != 0 { + filter = bson.M{"$and": []bson.M{ + filter, + { + "publishingStatus.lastUpdated": bson.M{"$gt": startTime}, + }, + }, + } + } + if endTime != -1 && endTime != 0 { + filter = bson.M{"$and": []bson.M{ + filter, + { + "publishingStatus.lastUpdated": bson.M{"$lte": endTime}, + }, + }, + } + } + filter = bson.M{"$and": []bson.M{ + filter, + { + "status.value": bson.M{ + "$ne": entity.StInDevelopment, + }, + }, + }, + } + if distinct { + aggregate := []bson.M{ + { + "$project": bson.M{ + "appId": 1, + "publishingStatus": 1, + "status": 1, + }, + }, + { + "$match": filter, + }, + { + "$group": bson.M{ + "_id": "appId", + "total": bson.M{"$sum": 1}, + }, + }, + } + return appVerTable.AggregateCount(ctx, aggregate) + } + return appVerTable.Count(ctx, filter) +} + +//审核通过小程序 +func (ar *AppRepo) GetApprovedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) { + filter := bson.M{} + if groupId != "" { + filter["groupId"] = groupId + } + filter = bson.M{ + "$and": []bson.M{ + filter, + { + "status.value": bson.M{ + "$in": []string{ + entity.StPublishApproved, + entity.StPublished, + entity.StUnpublishing, + entity.StUnpublishApproved, + entity.StUnpublishRejected, + entity.StUnpublished, + }, + }, + }, + }, + } + if distinct { + return appTable.Count(ctx, filter) + } + return appVerTable.Count(ctx, filter) +} + +func (ar *AppRepo) GetAppClassPer(ctx context.Context, status string) ([]entity.AppClassPerRsp, error) { + match := bson.M{} + if status != "" { + if status == "published" { + match["status.value"] = entity.StPublished + } + } + group := bson.M{"_id": "$appClass", "count": bson.M{"$sum": 1}} + + type perRsp struct { + Class string `bson:"class"` + Count int `bson:"count"` + Name []string `bson:"name"` + } + lookUp := bson.M{ + "from": TypeConfigTableName, + "localField": "_id", + "foreignField": "value", + "as": "classInfo", + } + project := bson.M{ + "class": "$_id", + "count": 1, + "name": "$classInfo.chinese", + } + perRspList := make([]perRsp, 0) + pipSelector := []bson.M{ + {"$match": match}, + {"$group": group}, + {"$lookup": lookUp}, + {"$project": project}, + } + err := appTable.AggregateOnly(ctx, pipSelector, &perRspList) + if err != nil { + return nil, err + } + rspData := make([]entity.AppClassPerRsp, 0) + for _, v := range perRspList { + rspData = append(rspData, entity.AppClassPerRsp{ + Class: v.Class, + Count: v.Count, + Name: v.Name, + }) + } + return rspData, nil +} + +func (ar *AppRepo) GetAppVerLimitByIdentity(ctx context.Context, t, appId, identity string, limit int) ([]entity.AppVersion, error) { + list := make([]mongo.AppVersion, 0) + var filter bson.M + //默认md5 + filter = bson.M{"appId": appId, "customData.sourceFile.fileMd5": identity} + if t == "sha256" { + filter = bson.M{"appId": appId, "customData.sourceFile.encryptedFileSha256": identity} + } + err := appVerTable.OnlyGetSome(ctx, filter, []string{"-sequence"}, limit, 1, &list) + if err != nil { + return nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetGrayStatisticsVerList(ctx context.Context, appId string, seq int, begin, end int64) (int, []entity.AppVersion, error) { + filter := bson.M{ + "appId": appId, + "sequence": bson.M{"$lt": seq}, + } + if end == 0 { + filter["$or"] = []bson.M{ + {"status.value": entity.StPublished}, + {"status.value": entity.StUnpublished, "unpublishedStatus.lastUpdated": bson.M{"$gte": begin}}, + } + } else { + filter["$or"] = []bson.M{ + {"status.value": entity.StPublished, "publishedStatus.lastUpdated": bson.M{"$lte": end}}, + {"status.value": entity.StUnpublished, "$or": []bson.M{ + {"publishedStatus.lastUpdated": bson.M{"$gte": begin, "$lte": end}}, + {"unpublishedStatus.lastUpdated": bson.M{"$gte": begin, "$lte": end}}, + }, + }, + } + } + log.Debugf("GetGrayStatisticsVerList filter:%+v", filter) + sort := []string{"sequence"} + list := make([]mongo.AppVersion, 0) + num, err := appVerTable.GetAll(ctx, filter, sort, &list) + if err != nil { + log.Errorf("GetGrayStatisticsVerList db err:%s", err.Error()) + return 0, nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return num, result, nil +} + +func (ar *AppRepo) GetAppClassList(ctx context.Context) ([]entity.CItem, error) { + appClassList := make([]entity.CItem, 0) + group := bson.M{"_id": "$appClass"} + pipSelector := []bson.M{ + {"$group": group}, + } + err := appTable.AggregateOnly(ctx, pipSelector, &appClassList) + if err != nil { + return make([]entity.CItem, 0), err + } + + return appClassList, nil +} + +func (ar *AppRepo) GetAppTagList(ctx context.Context) ([]entity.TagItem, error) { + appTagList := make([]entity.TagItem, 0) + group := bson.M{"_id": "$appTag"} + pipSelector := []bson.M{ + {"$group": group}, + } + err := appTable.AggregateOnly(ctx, pipSelector, &appTagList) + if err != nil { + return make([]entity.TagItem, 0), err + } + + return appTagList, nil +} + +func (ar *AppRepo) GetAppsBySearchText(ctx context.Context, searchText string) ([]entity.App, error) { + return nil, nil +} + +func (ar *AppRepo) GetAppByCreator(ctx context.Context, phone string) ([]entity.App, error) { + return nil, nil +} diff --git a/infrastructure/db/repo/mongo/app_build_info.go b/infrastructure/db/repo/mongo/app_build_info.go new file mode 100644 index 0000000..81437ee --- /dev/null +++ b/infrastructure/db/repo/mongo/app_build_info.go @@ -0,0 +1,173 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/db/entity/mongo" + + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IAppBuildInfoRepo = new(AppBuildInfoMongoRepo) + +type AppBuildInfoMongoRepo struct { +} + +func NewAppBuildInfoMongoRepo() *AppBuildInfoMongoRepo { + return &AppBuildInfoMongoRepo{} +} + +func (a *AppBuildInfoMongoRepo) Insert(ctx context.Context, item entity.AppBuildInfo) error { + mgoInfo := tr.CovertAppBuildInfoToMgo(&item) + return appBuildInfoTable.Insert(ctx, mgoInfo) +} + +func (a *AppBuildInfoMongoRepo) GetInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + filter := bson.M{"id": id} + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetOne(ctx, filter, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} + +func (a *AppBuildInfoMongoRepo) GetInfoByBuildInfoId(ctx context.Context, buildInfoId string) (*entity.AppBuildInfo, error) { + filter := bson.M{"buildInfoId": buildInfoId} + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetOne(ctx, filter, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} + +func (a *AppBuildInfoMongoRepo) GetInfoByBuildId(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + filter := bson.M{"buildInfoId": id} + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetOne(ctx, filter, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} + +func (a *AppBuildInfoMongoRepo) GetLatestInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + + filter := bson.M{"appId": appId} + + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetSortOne(ctx, filter, []string{"-created"}, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} + +func (a *AppBuildInfoMongoRepo) GetTrialInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + + filter := bson.M{"appId": appId, "source": entity.APP_BUILD_SOURCE_TRIAL} + + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetOne(ctx, filter, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} +func (a *AppBuildInfoMongoRepo) GetTrialInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + filter := bson.M{"id": id, "source": entity.APP_BUILD_SOURCE_TRIAL} + + item := mongo.AppBuildInfo{} + err := appBuildInfoTable.GetOne(ctx, filter, &item) + if err != nil { + return nil, err + } + return tr.CovertAppBuildInfoToEntity(&item), nil +} +func (a *AppBuildInfoMongoRepo) AddTrial(ctx context.Context, id string) error { + + filter := bson.M{"id": id} + update := bson.M{"$set": bson.M{"source": entity.APP_BUILD_SOURCE_TRIAL}} + + return appBuildInfoTable.UpdateOne(ctx, filter, update) +} +func (a *AppBuildInfoMongoRepo) CancelTrial(ctx context.Context, id string) error { + + filter := bson.M{"id": id} + update := bson.M{"$set": bson.M{"source": entity.APP_BUILD_SOURCE_BUILD, "startParams.path_and_query": ""}} + + return appBuildInfoTable.UpdateOne(ctx, filter, update) + +} +func (a *AppBuildInfoMongoRepo) UpdateTrialStartParams(ctx context.Context, id string, params entity.AppStartParams) error { + + filter := bson.M{"id": id} + update := bson.M{"$set": bson.M{"startParams.path_and_query": params.PathAndQuery}} + + return appBuildInfoTable.UpdateOne(ctx, filter, update) +} +func (a *AppBuildInfoMongoRepo) UpdateTrialPath(ctx context.Context, id, path string) error { + + filter := bson.M{"id": id} + update := bson.M{"$set": bson.M{"path": path}} + + return appBuildInfoTable.UpdateOne(ctx, filter, update) +} + +func (a *AppBuildInfoMongoRepo) UpdateOneStatus(ctx context.Context, id string, status bool) error { + filter := bson.M{"id": id} + update := bson.M{"$set": bson.M{"status": status}} + return appBuildInfoTable.UpdateOne(ctx, filter, update) +} + +func (a *AppBuildInfoMongoRepo) GetList(ctx context.Context, appId string, pageNo, pageSize int) (int64, []entity.AppBuildInfo, error) { + list := make([]mongo.AppBuildInfo, 0) + filter := bson.M{"appId": appId} + + total, err := appBuildInfoTable.GetSome(ctx, filter, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppBuildInfoToEntity(&temp)) + } + return int64(total), result, nil +} +func (a *AppBuildInfoMongoRepo) GetAll(ctx context.Context) ([]entity.AppBuildInfo, error) { + list := make([]mongo.AppBuildInfo, 0) + _, err := appBuildInfoTable.GetAll(ctx, bson.M{}, []string{}, &list) + if err != nil { + return nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppBuildInfoToEntity(&temp)) + } + return result, nil +} + +func (a *AppBuildInfoMongoRepo) GetAppBuilds(ctx context.Context, groupID, appId string, pageSize, pageNo int) (int64, []entity.AppBuildInfo, error) { + list := make([]mongo.AppBuildInfo, 0) + + filter := bson.M{"appId": appId, "groupId": groupID} + total, err := appBuildInfoTable.GetSome(ctx, filter, []string{"-created"}, pageSize, pageNo, &list) + if err != nil { + return 0, nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppBuildInfoToEntity(&temp)) + } + return int64(total), result, nil +} + +func (a *AppBuildInfoMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} diff --git a/infrastructure/db/repo/mongo/app_oper_config.go b/infrastructure/db/repo/mongo/app_oper_config.go new file mode 100644 index 0000000..589c18c --- /dev/null +++ b/infrastructure/db/repo/mongo/app_oper_config.go @@ -0,0 +1,31 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/repository" + + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IAppOperConfigRepo = new(AppOperConfigRepo) + +type AppOperConfigRepo struct { +} + +func (a *AppOperConfigRepo) Insert(ctx context.Context, item repository.AppOperConfig) error { + return appOperConfigTable.Insert(ctx, item) +} + +func (a *AppOperConfigRepo) Update(ctx context.Context, item repository.AppOperConfig) error { + upInfo := make(map[string]interface{}) + upInfo["auto_review_app"] = item.AutoReviewApp + upInfo["update_time"] = item.UpdateTime + + return appTable.UpdateOne(ctx, bson.M{"_id": item.Id}, bson.M{"$set": upInfo}) +} + +func (a *AppOperConfigRepo) Find(ctx context.Context) (repository.AppOperConfig, error) { + item := repository.AppOperConfig{} + err := appTable.GetOne(ctx, bson.M{}, &item) + return item, err +} diff --git a/infrastructure/db/repo/mongo/app_temp_info.go b/infrastructure/db/repo/mongo/app_temp_info.go new file mode 100644 index 0000000..df35bd6 --- /dev/null +++ b/infrastructure/db/repo/mongo/app_temp_info.go @@ -0,0 +1,139 @@ +package mongo + +import ( + "context" + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/utility" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IAppTempInfoRepo = new(AppTempInfoByMongoRepo) + +type AppTempInfoByMongoRepo struct { +} + +type AppTempInfoMongo struct { + AppID string `json:"appId" bson:"app_id"` //id + Name string `json:"name" bson:"name"` //名字 + Sequence int `json:"sequence" bson:"sequence"` //版本号 + AppClass string `json:"appClass" bson:"app_class"` //用途 + AppType string `json:"appType" bson:"app_type"` //应用类型--mop使用为了和应用市场区分开 + StatusValue string `json:"statusValue" bson:"status_value"` + StatusReason string `json:"statusReason" bson:"status_reason"` + StatusLastUpdated int64 `json:"statusLastUpdated" bson:"status_last_updated"` + StatusModifiedBy string `json:"statusModifiedBy" bson:"status_modified_by"` + DeveloperID string `json:"developerId" bson:"developer_id"` //开发者id + GroupID string `json:"groupId" bson:"group_id"` //组id + Created int64 `json:"created" bson:"created"` + CreatedBy string `json:"createdBy" bson:"created_by"` + CustomDataDetailDescription string `bson:"customData_detail_description" json:"customDataDetailDescription"` //小程序详细描述 + CustomDataSourceFile string `bson:"customData_source_file" json:"customDataSourceFile"` + CustomDataVersionDescription string `bson:"customData_version_description" json:"customDataVersionDescription"` //小程序编译包版本描述 + CustomDataDeveloper string `bson:"customData_developer" json:"customDataDeveloper"` //开发者 + Version string `json:"version" bson:"version"` //应用版本 + CoreDescription string `json:"coreDescription" bson:"core_description"` //核心描述 + Logo string `json:"logo" bson:"logo"` //图标 +} + +func (a AppTempInfoByMongoRepo) Insert(ctx context.Context, info *entity.AppTempInfo) error { + return appTempInfoTable.Insert(ctx, convertAppTempInfoToAppTempInfoMongo(info)) +} + +func (a AppTempInfoByMongoRepo) UpdateInfo(ctx context.Context, info *entity.AppTempInfo) error { + mgoInfo := convertAppTempInfoToAppTempInfoMongo(info) + return appTempInfoTable.UpdateOne(ctx, bson.M{"app_id": info.AppID, "sequence": info.Sequence}, mgoInfo) +} + +func (a AppTempInfoByMongoRepo) GetInfoByAppId(ctx context.Context, appId string) (*entity.AppTempInfo, error) { + appTempInfoMongo := AppTempInfoMongo{} + err := appTempInfoTable.GetOne(ctx, bson.M{"app_id": appId, "sequence": entity.AppTempDefSequence}, &appTempInfoMongo) + if err != nil { + return nil, err + } + + info := convertAppTempInfoMongoToAppTempInfo(appTempInfoMongo) + return &info, err +} + +func (a AppTempInfoByMongoRepo) GetInfoByAppIdAndSeq(ctx context.Context, appId string, seq int) (*entity.AppTempInfo, error) { + appTempInfoMongo := AppTempInfoMongo{} + err := appTempInfoTable.GetOne(ctx, bson.M{"app_id": appId, "sequence": seq}, &appTempInfoMongo) + if err != nil { + return nil, err + } + + info := convertAppTempInfoMongoToAppTempInfo(appTempInfoMongo) + return &info, err +} + +func (a AppTempInfoByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertAppTempInfoToAppTempInfoMongo(appTempInfo *entity.AppTempInfo) AppTempInfoMongo { + result := AppTempInfoMongo{} + + result.AppID = appTempInfo.AppID + result.Name = appTempInfo.Name + result.Sequence = appTempInfo.Sequence + result.AppClass = appTempInfo.AppClass + result.AppType = appTempInfo.AppType + result.StatusValue = appTempInfo.Status.Value + result.StatusReason = appTempInfo.Status.Reason + result.StatusLastUpdated = appTempInfo.Status.LastUpdated + result.StatusModifiedBy = appTempInfo.Status.ModifiedBy + result.DeveloperID = appTempInfo.DeveloperID + result.GroupID = appTempInfo.GroupID + result.Created = appTempInfo.Created + result.CreatedBy = appTempInfo.CreatedBy + result.CustomDataDetailDescription = appTempInfo.CustomData.DetailDescription + result.CustomDataSourceFile = utility.InterfaceToJsonString(appTempInfo.CustomData.SourceFile) + result.CustomDataVersionDescription = appTempInfo.CustomData.VersionDescription + result.CustomDataDeveloper = appTempInfo.CustomData.Developer + result.Version = appTempInfo.Version + result.CoreDescription = appTempInfo.CoreDescription + result.Logo = appTempInfo.Logo + + return result +} + +func convertAppTempInfoMongoToAppTempInfo(appTempInfoMongo AppTempInfoMongo) entity.AppTempInfo { + result := entity.AppTempInfo{} + + status := entity.Status{ + Value: appTempInfoMongo.StatusValue, + Reason: appTempInfoMongo.StatusReason, + LastUpdated: appTempInfoMongo.StatusLastUpdated, + ModifiedBy: appTempInfoMongo.StatusModifiedBy, + } + + var sourceFile []entity.CustomDataSourceFile + json.Unmarshal([]byte(appTempInfoMongo.CustomDataSourceFile), &sourceFile) + + customData := entity.CustomDataInfo{ + DetailDescription: appTempInfoMongo.CustomDataDetailDescription, + SourceFile: sourceFile, + VersionDescription: appTempInfoMongo.CustomDataVersionDescription, + Developer: appTempInfoMongo.CustomDataDeveloper, + } + + result.AppID = appTempInfoMongo.AppID + result.Name = appTempInfoMongo.Name + result.Sequence = appTempInfoMongo.Sequence + result.AppClass = appTempInfoMongo.AppClass + result.AppType = appTempInfoMongo.AppType + result.Status = status + result.DeveloperID = appTempInfoMongo.DeveloperID + result.GroupID = appTempInfoMongo.GroupID + result.Created = appTempInfoMongo.Created + result.CreatedBy = appTempInfoMongo.CreatedBy + result.CustomData = customData + result.Version = appTempInfoMongo.Version + result.CoreDescription = appTempInfoMongo.CoreDescription + result.Logo = appTempInfoMongo.Logo + + return result +} diff --git a/infrastructure/db/repo/mongo/binding.go b/infrastructure/db/repo/mongo/binding.go new file mode 100644 index 0000000..d7e8314 --- /dev/null +++ b/infrastructure/db/repo/mongo/binding.go @@ -0,0 +1,997 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "strings" + "time" + + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IBindingRepo = new(BindingByMongoRepo) + +type BindingByMongoRepo struct { +} + +func NewBindingByMongoRepo() *BindingByMongoRepo { + return &BindingByMongoRepo{} +} + +// 这张表暂时废弃 +//type BundleInfoMongo struct { +// BindingId string `json:"bindingId" bson:"binding_id"` +// BundleID string `json:"bundleId" bson:"bundle_id"` +// GroupID string `json:"groupId" bson:"group_id"` //企业ID +// Remark string `json:"remark" bson:"remark"` +// SDKKey string `json:"SDKKey" bson:"sdk_key"` +// SDKID string `json:"SDKID" bson:"sdk_id"` +// IsFirstCreate string `json:"isFirstCreate" bson:"is_first_create"` //是否第一次创建 +// CreatedAt int64 `json:"createdAt" bson:"created_at"` +// CreatedAccount string `json:"createdAccount" bson:"created_account"` +// CreatedBy string `json:"createdBy" bson:"created_by"` +//} + +// BundleInfoData 驼峰换下划线,给BindingMongo使用 +type BundleInfoData struct { + BundleID string `json:"bundle_id" bson:"bundle_id"` + Remark string `json:"remark" bson:"remark"` + SDKKey string `json:"sdk_key" bson:"sdk_key"` + SDKID string `json:"sdk_id" bson:"sdk_id"` + IsFirstCreate bool `json:"is_first_create" bson:"is_first_create"` //是否第一次创建 + CreatedAt int64 `json:"created_at" bson:"created_at"` + CreatedAccount string `json:"created_account" bson:"created_account"` + CreatedBy string `json:"created_by" bson:"created_by"` + IsForbidden int `json:"is_forbidden" bson:"is_forbidden"` + IsReview int `json:"is_review" bson:"is_review"` +} + +type AppInfo struct { + AppID string `json:"appId" bson:"appId"` + AssociatedAt int64 `json:"associatedAt" bson:"associatedAt"` + AssociatedBy string `json:"associatedBy" bson:"associatedBy"` +} + +type BindingMongo struct { + BindingID string `json:"bindingId" bson:"binding_id"` //应用的id + Name string `json:"name" bson:"name"` //应用名称 + BundleInfos []BundleInfoData `json:"bundleInfos" bson:"bundle_infos"` //bundle ids + CreatedInfoBy string `json:"createdInfoBy" bson:"created_info_by"` + CreatedInfoAt int64 `json:"createdInfoAt" bson:"created_info_at"` + CreatedInfoAccount string `json:"createdInfoAccount" bson:"created_info_account"` + GroupID string `json:"groupId" bson:"group_id"` //企业ID + GroupName string `json:"groupName" bson:"group_name"` //企业名称(为了查询) + CooperateStatusValue string `json:"cooperateStatusValue" bson:"cooperate_status_value"` + CooperateStatusReason string `json:"cooperateStatusReason" bson:"cooperate_status_reason"` + CooperateStatusLastUpdated int64 `json:"cooperateStatusLastUpdated" bson:"cooperate_status_last_updated"` + CooperateStatusModifiedBy string `json:"cooperateStatusModifiedBy" bson:"cooperate_status_modified_by"` + CooperateValidStatusReason string `json:"cooperateValidStatusReason" bson:"cooperate_valid_status_reson"` + CooperateValidStatusLastUpdated int64 `json:"cooperateValidStatusLastUpdated" bson:"cooperate_valid_status_last_updated"` + CooperateValidStatusModifiedBy string `json:"cooperateValidStatusModifiedBy" bson:"cooperate_valid_status_modified_by"` + CooperateInvalidStatusReason string `json:"cooperateInvalidStatusReason" bson:"cooperate_invalid_status_reson"` + CooperateInvalidStatusLastUpdated int64 `json:"cooperateInvalidStatusLastUpdated" bson:"cooperate_invalid_status_last_updated"` + CooperateInvalidStatusModifiedBy string `json:"cooperateInvalidStatusModifiedBy" bson:"cooperate_invalid_status_modified_by"` + AppInfos []AppInfo `json:"appInfos" bson:"app_infos"` //appid 的信息 + Owner string `json:"owner" bson:"owner"` //所属企业 + Expire int64 `json:"expire" bson:"expire"` + ApiServer string `json:"apiServer" bson:"api_server"` //子域名 + PlatForm int `json:"platform" bson:"platform"` //来源平台 + AutoBind int `json:"autoBind" bson:"auto_bind"` //自动关联小程序 + HiddenBundle int `json:"hiddenBundle" bson:"hidden_bundle"` //隐藏bundle信息 + FromBindingID string `json:"fromBindingId" bson:"from_binding_id"` //来源ID +} + +func (b BindingByMongoRepo) GetInfo(ctx context.Context, bindingId string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"binding_id": bindingId}, &bindingMongo) + if err != nil { + return nil, err + } + + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetByGroupIdAndName(ctx context.Context, groupId string, name string, isAdmin bool) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + filter := bson.M{} + if isAdmin { + filter["group_id"] = groupId + filter["name"] = name + filter["platform"] = entity.BINGING_PLATFORM_OPER + } else { + filter["group_id"] = groupId + filter["name"] = name + filter["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}} + } + err := bindingTable.GetOne(ctx, filter, &bindingMongo) + if err != nil { + return nil, err + } + + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bindingTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, &bundleInfoMongos) + //if err != nil { + // return nil, err + //} + // + //result := convertBindingMongoToBinding(bindingMongo, bundleInfoMongos) + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetByApiServer(ctx context.Context, apiServer string) (entity.Binding, error) { + bindingMongo := BindingMongo{} + res := entity.Binding{} + + err := bindingTable.GetOne(ctx, bson.M{"api_server": apiServer}, &bindingMongo) + if err != nil { + return res, err + } + + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bindingTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, &bundleInfoMongos) + //if err != nil { + // return nil, err + //} + // + //result := convertBindingMongoToBinding(bindingMongo, bundleInfoMongos) + result := convertBindingMongoToBinding(bindingMongo) + + return result, err +} + +func (b BindingByMongoRepo) GetInfoByParams(ctx context.Context, sdkKey, organId, appId string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + + filters := []bson.M{} + filters = append(filters, bson.M{"bundle_infos": bson.M{"$elemMatch": bson.M{"sdk_key": sdkKey}}}) //bson.M{"bundleInfos.SDKKey": bson.M{"$in": []string{sdkKey}}} + if appId != "" { + filters = append(filters, bson.M{"app_infos": bson.M{"$elemMatch": bson.M{"appId": appId}}}) + } + if organId != "" { + filters = append(filters, bson.M{"group_id": organId}) + } + filter := bson.M{"$and": filters} + + err := bindingTable.GetOne(ctx, filter, &bindingMongo) + if err != nil { + return nil, err + } + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetInfoBySdkKeyOrganId(ctx context.Context, organId, sdkKey string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"group_id": organId, "bundle_infos.sdk_key": sdkKey}, &bindingMongo) + if err != nil { + return nil, err + } + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetAllSdkKey(ctx context.Context, organId string) ([]string, error) { + bindingMongos := make([]BindingMongo, 0) + _, err := bindingTable.GetAll(ctx, bson.M{"group_id": organId}, []string{}, &bindingMongos) + if err != nil { + return nil, err + } + + result := make([]string, 0) + for _, v := range bindingMongos { + //result := make([]string, 0) + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bundleInfoTable.GetAll(ctx, bson.M{"binding_id": v.BindingID}, []string{}, bundleInfoMongos) + //if err != nil { + // return nil, err + //} + + for _, bundleInfo := range v.BundleInfos { + result = append(result, bundleInfo.SDKKey) + } + + } + + return result, err +} + +func (b BindingByMongoRepo) GetBindListBySdkKey(ctx context.Context, sdkKey string) ([]entity.Binding, error) { + bindingMongos := make([]BindingMongo, 0) + _, err := bindingTable.GetAll(ctx, bson.M{"bundle_infos.sdk_key": sdkKey}, []string{"created_info_at"}, &bindingMongos) + if err != nil { + return nil, err + } + + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bundleInfoTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, bundleInfoMongos) + //if err != nil { + // return nil, err + //} + + //bindings = append(bindings, convertBindingMongoToBinding(bindingMongo, bundleInfoMongos)) + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, err +} + +func (b BindingByMongoRepo) SdkKeyExi(ctx context.Context, sdkKey string) (bool, error) { + if _, ok := entity.SdkExiCache.Get(sdkKey); ok { + return true, nil + } + + count, err := bindingTable.Count(ctx, bson.M{"bundle_infos.sdk_key": sdkKey}) + if err != nil { + return false, err + } + + if count > 0 { + entity.SdkExiCache.Set(sdkKey, true, -1) + return true, err + } + return false, err +} + +func (b BindingByMongoRepo) Insert(ctx context.Context, bind *entity.Binding) error { + err := bindingTable.Insert(ctx, convertBindingToBindingMongo(bind)) + if err != nil { + return err + } + + //for _, v := range bind.BundleInfos { + // err = bundleInfoTable.Insert(ctx, convertBundleInfoToBundleInfoMongo(bind.BindingID, bind.GroupID, v)) + //} + + return err +} + +func (b BindingByMongoRepo) Count(ctx context.Context) (int, error) { + return bindingTable.Count(ctx, bson.M{}) +} + +func (b BindingByMongoRepo) GetCountByStatus(ctx context.Context, status string, platform int) (int, error) { + filter := bson.M{} + filter["cooperate_status_value"] = "Valid" + /*switch platform { + case entity.BINGING_PLATFORM_OPER: + filter["platform"] = entity.BINGING_PLATFORM_OPER + filter["fromBindingId"] = "" + case entity.BINGING_PLATFORM_ORGAN: + filter["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}} + default: + filter["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_OPER, "fromBindingId": ""}, {"$or": []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}}}} + }*/ + filter["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_OPER, "group_id": ""}, {"$or": []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}}}} + return bindingTable.Count(ctx, filter) +} + +func (b BindingByMongoRepo) GetBundleIdNum(ctx context.Context) (int, error) { + //校验bundingId的数量 + pipSelect := []bson.M{ + {"$match": bson.M{"bundle_infos": bson.M{"$elemMatch": bson.M{"is_forbidden": 0}}}}, + {"$unwind": "$bundleInfos"}, + {"$group": bson.M{"_id": nil, "total": bson.M{"$sum": 1}}}, + } + bundleIdTotal, err := bindingTable.AggregateCount(ctx, pipSelect) + if err != nil && !b.NotFound(err) { + log.Errorf("GetBundleIdNum err:", err.Error()) + return 0, err + } + if b.NotFound(err) { + bundleIdTotal = 0 + return 0, nil + } + return bundleIdTotal, nil +} + +func (b BindingByMongoRepo) GetBundleIdLimitHand(ctx context.Context, groupId string) (int, error) { + //校验bundingId的数量 + pipSelect := []bson.M{ + //{"$match": bson.M{"group_id": groupId}}, + {"$match": bson.M{"group_id": groupId, "bundle_infos": bson.M{"$elemMatch": bson.M{"is_forbidden": 0}}}}, + {"$unwind": "$bundle_infos"}, + {"$group": bson.M{"_id": nil, "total": bson.M{"$sum": 1}}}, + } + bundleIdTotal, err := bindingTable.AggregateCount(ctx, pipSelect) + if err != nil && !b.NotFound(err) { + return 0, err + } + if b.NotFound(err) { + bundleIdTotal = 0 + return 0, nil + } + return bundleIdTotal, nil +} + +func (b BindingByMongoRepo) GetBundleLimit(ctx context.Context) (int, error) { + //return bundleTable.Count(ctx, bson.M{}) + return bundleTable.Count(ctx, bson.M{"is_forbidden": 0}) +} + +func (b BindingByMongoRepo) GetBindingByBindingId(ctx context.Context, bindingId string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"binding_id": bindingId}, &bindingMongo) + if err != nil { + return nil, err + } + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} +func (b BindingByMongoRepo) GetBindingByGroupIdAndBindingId(ctx context.Context, groupId string, bindingId string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"group_id": groupId, "binding_id": bindingId}, &bindingMongo) + if err != nil { + return nil, err + } + + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bindingTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, &bundleInfoMongos) + //if err != nil { + // return nil, err + //} + // + //result := convertBindingMongoToBinding(bindingMongo, bundleInfoMongos) + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetBindingByGroupIdAndSdkKey(ctx context.Context, groupId string, sdkKey string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"group_id": groupId, "bundle_infos.sdk_key": sdkKey}, &bindingMongo) + if err != nil { + return nil, err + } + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) UpdateBundleInfosByGroupIdAndBindId(ctx context.Context, groupId string, bindingId string, infos []entity.BundleInfo) error { + bundleInfoDatas := make([]BundleInfoData, 0) + for _, v := range infos { + bundleInfoData := BundleInfoData{ + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + } + + bundleInfoDatas = append(bundleInfoDatas, bundleInfoData) + } + return bindingTable.UpdateOne(ctx, bson.M{"group_id": groupId, "binding_id": bindingId}, bson.M{"$set": bson.M{"bundle_infos": bundleInfoDatas}}) +} + +func (b BindingByMongoRepo) AppendBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error { + bindingInfo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"binding_id": bindingId}, &bindingInfo) + if err != nil { + return err + } + bundleInfoDatas := make([]BundleInfoData, 0) + bundleInfoDatas = append(bundleInfoDatas, bindingInfo.BundleInfos...) + for _, v := range bundles { + bundleInfoData := BundleInfoData{ + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + } + + bundleInfoDatas = append(bundleInfoDatas, bundleInfoData) + } + return bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": bson.M{"bundle_infos": bundleInfoDatas}}) +} + +func (b BindingByMongoRepo) UpdateBundleIsView(ctx context.Context, reviews []apiproto.BundleReviewItem, isReview int) error { + return nil +} + +func (b BindingByMongoRepo) ListReviewBundle(ctx context.Context, pageSize int, pageNo int, searchText string, isReview int) (int64, []entity.ReviewBundleInfo, error) { + return 0, nil, nil +} + +func (b BindingByMongoRepo) CheckReviewBySdkKey(ctx context.Context, sdkKey string) bool { + return false +} + +func (b BindingByMongoRepo) GetReviewBindBySdkKey(ctx context.Context, sdkKey string) (*entity.ReviewBundleInfo, error) { + return nil, nil +} + +func (b BindingByMongoRepo) UpdateBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error { + bundleInfoDatas := make([]BundleInfoData, 0) + for _, v := range bundles { + bundleInfoData := BundleInfoData{ + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + IsReview: v.IsReview, + } + + bundleInfoDatas = append(bundleInfoDatas, bundleInfoData) + } + return bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": bson.M{"bundle_infos": bundleInfoDatas}}) +} + +func (b BindingByMongoRepo) GetByBindIdList(ctx context.Context, ids []string) ([]entity.Binding, error) { + bindingMongos := make([]BindingMongo, 0) + _, err := bindingTable.GetAll(ctx, bson.M{"binding_id": bson.M{"$in": ids}}, []string{}, &bindingMongos) + if err != nil { + return nil, err + } + + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bundleInfoTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, bundleInfoMongos) + //if err != nil { + // return nil, err + //} + // + //bindings = append(bindings, convertBindingMongoToBinding(bindingMongo, bundleInfoMongos)) + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, err +} + +func (b BindingByMongoRepo) GetBindListByGroupId(ctx context.Context, groupId string, pageSize int, pageNo int) ([]entity.Binding, int, error) { + bindingMongos := make([]BindingMongo, 0) + filter := bson.M{"group_id": groupId} + filter["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}} + total, err := bindingTable.GetSome(ctx, filter, []string{"-created_info_at"}, pageSize, pageNo, &bindingMongos) + if err != nil { + return make([]entity.Binding, 0), 0, err + } + + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + //bundleInfoMongos := make([]BundleInfoMongo, 0) + //_, err = bundleInfoTable.GetAll(ctx, bson.M{"binding_id": bindingMongo.BindingID}, []string{}, bundleInfoMongos) + //if err != nil { + // return make([]entity.Binding, 0), 0, err + //} + // + //bindings = append(bindings, convertBindingMongoToBinding(bindingMongo, bundleInfoMongos)) + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, total, err +} + +func (b BindingByMongoRepo) UpdateRelatedBindingCooperate(ctx context.Context, bindingId string, status entity.Status, specificStatus entity.SpecificStatus, cooperate bool) error { + if cooperate { + return bindingTable.UpdateAll(ctx, bson.M{"from_binding_id": bindingId, "platform": entity.BINGING_PLATFORM_OPER}, + bson.M{"$set": bson.M{"cooperate_status_value": status.Value, "cooperate_status_last_updated": status.LastUpdated, "cooperate_status_modified_by": status.ModifiedBy, + "cooperate_valid_status_last_updated": specificStatus.LastUpdated, "cooperate_valid_status_modified_by": specificStatus.ModifiedBy}}) + } else { + return bindingTable.UpdateAll(ctx, bson.M{"from_binding_id": bindingId, "platform": entity.BINGING_PLATFORM_OPER}, + bson.M{"$set": bson.M{"cooperate_status_value": status.Value, "cooperate_status_last_updated": status.LastUpdated, "cooperate_status_modified_by": status.ModifiedBy, + "cooperate_invalid_status_last_updated": specificStatus.LastUpdated, "cooperate_invalid_status_modified_by": specificStatus.ModifiedBy}}) + } +} + +func (b BindingByMongoRepo) AppendApps(ctx context.Context, bindingId string, apps []entity.AppInfo) error { + bindingInfo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"binding_id": bindingId}, &bindingInfo) + if err != nil { + return err + } + appsInfo := make([]AppInfo, 0) + appsInfo = append(appsInfo, bindingInfo.AppInfos...) + for _, v := range apps { + app := AppInfo{ + AppID: v.AppID, + AssociatedAt: v.AssociatedAt, + AssociatedBy: v.AssociatedBy, + } + + appsInfo = append(appsInfo, app) + } + return bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": bson.M{"app_infos": appsInfo}}) +} + +func (b BindingByMongoRepo) RemoveApps(ctx context.Context, bindingId string, appIds []string) error { + rmAppsMap := make(map[string]bool) + for _, appId := range appIds { + rmAppsMap[appId] = true + } + bindingInfo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"binding_id": bindingId}, &bindingInfo) + if err != nil { + return err + } + appsInfo := make([]AppInfo, 0) + for _, app := range bindingInfo.AppInfos { + if _, ok := rmAppsMap[app.AppID]; !ok { + appsInfo = append(appsInfo, app) + } + } + return bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": bson.M{"app_infos": appsInfo}}) +} + +func (b BindingByMongoRepo) UpdateByBindId(ctx context.Context, bindingId string, bind *entity.Binding) error { + err := bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, convertBindingToBindingMongo(bind)) + if err != nil { + return err + } + + //for _, v := range bind.BundleInfos { + // err = bundleInfoTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, convertBundleInfoToBundleInfoMongo(bind.BindingID, bind.GroupID, v)) + //} + + return err +} + +func (b BindingByMongoRepo) UpdateBindingInfo(ctx context.Context, bindingId string, info map[string]interface{}, platform int) error { + if platform == entity.BINGING_PLATFORM_OPER { + err := bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": info}) + if err != nil { + return err + } + return bindingTable.UpdateAll(ctx, bson.M{"from_binding_id": bindingId}, bson.M{"$set": info}) + } else { + return bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": info}) + } +} + +func (b BindingByMongoRepo) UpdateBindingGroupName(ctx context.Context, groupId, groupName string) error { + return nil +} + +func (b BindingByMongoRepo) UpdateExpire(ctx context.Context, bindingId string, expire int64) error { + err := bindingTable.UpdateOne(ctx, bson.M{"binding_id": bindingId}, bson.M{"$set": bson.M{"expire": expire}}) + if err != nil { + return err + } + + return nil +} + +func (b BindingByMongoRepo) BundleIdCount(ctx context.Context, groupId string) (int, error) { + var pipSelect []bson.M + if groupId == "" { + pipSelect = []bson.M{ + {"$match": bson.M{"bundle_infos": bson.M{"$elemMatch": bson.M{"is_forbidden": 0}}}}, + {"$unwind": "$bundleInfos"}, + {"$group": bson.M{"_id": nil, "total": bson.M{"$sum": 1}}}, + } + } else { + pipSelect = []bson.M{ + {"$match": bson.M{"groupId": groupId, "bundle_infos": bson.M{"$elemMatch": bson.M{"is_forbidden": 0}}}}, + {"$unwind": "$bundleInfos"}, + {"$group": bson.M{"_id": nil, "total": bson.M{"$sum": 1}}}, + } + } + bundleIdTotal, err := bindingTable.AggregateCount(ctx, pipSelect) + if err != nil && !b.NotFound(err) { + log.Errorf("updateLicenseValid get bundle id count err:%s", err.Error()) + return 0, err + } + if b.NotFound(err) { + bundleIdTotal = 0 + return 0, nil + } + return bundleIdTotal, nil +} + +func (b BindingByMongoRepo) GetBundleByGroupIdAndBundleId(ctx context.Context, groupId string, bundleId string) (*entity.Binding, error) { + //bundleInfoMongo := BundleInfoMongo{} + //err := bundleInfoTable.GetOne(ctx, bson.M{"group_id": groupId, "bundle_id": bundleId}, &bundleInfoMongo) + //if err != nil { + // return nil, err + //} + // + //return convertBundleInfoMongoToBundleInfo(bundleInfoMongo), err + + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"group_id": groupId, "bundle_infos.bundle_id": bson.M{"$in": []string{bundleId}}}, &bindingMongo) + if err != nil { + return nil, err + } + + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetbundlesByBundleId(ctx context.Context, bundleId string) (*entity.Binding, error) { + //bundleInfoMongo := BundleInfoMongo{} + //err := bundleInfoTable.GetOne(ctx, bson.M{"bundle_id": bundleId}, &bundleInfoMongo) + //if err != nil { + // return nil, err + //} + // + //return convertBundleInfoMongoToBundleInfo(bundleInfoMongo), err + + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"bundle_infos.bundle_id": bson.M{"$in": []string{bundleId}}}, &bindingMongo) + if err != nil { + return nil, err + } + + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) GetBindingsBySearch(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, searchFields string, cooperateStatus string, platform int) ([]entity.Binding, int, error) { + bindingMongos := make([]BindingMongo, 0) + + sortColumn := make([]string, 0) + switch sort { + case "-created": + sortColumn = append(sortColumn, "-created_info_at") //按创建时间排序 + case "-expire": + sortColumn = append(sortColumn, "-expire") //按过期时间倒序排序 + case "expire": + sortColumn = append(sortColumn, "expire") //按过期时间正序排序 + default: + sortColumn = append(sortColumn, "-created_info_at") //按创建时间倒序排序 + } + filter := []bson.M{} + if searchText != "" && searchFields != "" { + sf := bson.M{} + r := bson.RegEx{Pattern: searchText, Options: "i"} + searchFilter := make([]bson.M, 0) + for _, v := range strings.Split(searchFields, ",") { + searchFilter = append(searchFilter, bson.M{v: r}) + } + sf["$or"] = searchFilter + filter = append(filter, sf) + } + if cooperateStatus != "all" { + q := bson.M{"cooperateStatus.value": cooperateStatus} + filter = append(filter, q) + } + switch platform { + case entity.BINGING_PLATFORM_OPER: + filter = append(filter, bson.M{"platform": entity.BINGING_PLATFORM_OPER, "group_id": ""}) + case entity.BINGING_PLATFORM_ORGAN: + q := bson.M{} + q["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}} + filter = append(filter, q) + default: + q := bson.M{} + q["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_OPER, "group_id": ""}, {"$or": []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}}}} + filter = append(filter, q) + } + total, err := bindingTable.GetSome(ctx, bson.M{"$and": filter}, sortColumn, pageSize, pageNo, &bindingMongos) + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, total, err +} + +func (b BindingByMongoRepo) GetBindingsByAppId(ctx context.Context, pageSize int, pageNo int, appId string) ([]entity.Binding, int, error) { + bindingMongos := make([]BindingMongo, 0) + + filter := bson.M{"app_infos.appId": appId} + + total, err := bindingTable.GetSome(ctx, filter, []string{"-created_info_at"}, pageSize, pageNo, &bindingMongos) + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, total, err +} + +func (b BindingByMongoRepo) GetDevListBinding(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, pullType string, groupId string, bindStatus string, platform int) ([]entity.Binding, int, error) { + bindingMongos := make([]BindingMongo, 0) + + sortColumn := make([]string, 0) + switch sort { + case "-created": + sortColumn = append(sortColumn, "-created_info_at") //按创建时间排序 + case "-expire": + sortColumn = append(sortColumn, "-expire") //按过期时间倒序排序 + case "expire": + sortColumn = append(sortColumn, "expire") //按过期时间正序排序 + default: + sortColumn = append(sortColumn, "-created_info_at") //按创建时间倒序排序 + } + + filter := []bson.M{} + filter = append(filter, bson.M{"group_id": groupId}) + switch pullType { + case "recently-expire": + q := bson.M{} + beginData := time.Now().UnixNano() / 1e6 + endData := time.Now().AddDate(0, 0, 30).UnixNano() / 1e6 + q["expire"] = bson.M{"$gte": beginData, "$lte": endData} + filter = append(filter, q) + } + + switch bindStatus { + case "Valid": + filter = append(filter, bson.M{"cooperate_status_value": "Valid"}) + case "Invalid": + filter = append(filter, bson.M{"cooperate_status_value": "Invalid"}) + } + if searchText != "" { + q := bson.M{} + r := bson.RegEx{Pattern: searchText, Options: "i"} + q["$or"] = []bson.M{{"name": bson.M{"$regex": r}}} + filter = append(filter, q) + } + switch platform { + case entity.BINGING_PLATFORM_OPER: + filter = append(filter, bson.M{"platform": entity.BINGING_PLATFORM_OPER}) + case entity.BINGING_PLATFORM_ORGAN: + q := bson.M{} + q["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}} + filter = append(filter, q) + default: + q := bson.M{} + q["$or"] = []bson.M{{"platform": entity.BINGING_PLATFORM_OPER}, {"$or": []bson.M{{"platform": entity.BINGING_PLATFORM_ORGAN}, {"platform": bson.M{"$exists": false}}}}} + filter = append(filter, q) + } + total, err := bindingTable.GetSome(ctx, bson.M{"$and": filter}, sortColumn, pageSize, pageNo, &bindingMongos) + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, total, err +} + +func (b BindingByMongoRepo) GetBindingBySdkKey(ctx context.Context, sdkKey string) (*entity.Binding, error) { + bindingMongo := BindingMongo{} + err := bindingTable.GetOne(ctx, bson.M{"bundle_infos.sdk_key": sdkKey}, &bindingMongo) + if err != nil { + return nil, err + } + result := convertBindingMongoToBinding(bindingMongo) + + return &result, err +} + +func (b BindingByMongoRepo) ListAutoBindAppBinding(ctx context.Context, groupId string) ([]string, error) { + bindingMongos := make([]BindingMongo, 0) + _, err := bindingTable.GetAll(ctx, bson.M{"auto_bind": 1, "platform": entity.BINGING_PLATFORM_OPER, "group_id": groupId}, []string{}, &bindingMongos) + if err != nil { + return nil, err + } + result := []string{} + for _, binding := range bindingMongos { + result = append(result, binding.BindingID) + } + return result, nil +} + +func (b BindingByMongoRepo) ListCopyOperBinding(ctx context.Context, bindingId string) ([]string, []entity.Binding, error) { + bindingMongos := make([]BindingMongo, 0) + _, err := bindingTable.GetAll(ctx, bson.M{"platform": entity.BINGING_PLATFORM_OPER, "from_binding_id": bindingId}, []string{}, &bindingMongos) + if err != nil { + return nil, nil, err + } + result := []string{} + bindings := make([]entity.Binding, 0) + for _, binding := range bindingMongos { + result = append(result, binding.BindingID) + bindings = append(bindings, convertBindingMongoToBinding(binding)) + } + return result, bindings, nil +} + +func (b BindingByMongoRepo) ListBindings(ctx context.Context, groupId string, searchText string, pageNo int, pageSize int) ([]entity.Binding, int, error) { + bindingMongos := make([]BindingMongo, 0) + + sortColumn := make([]string, 0) + sortColumn = append(sortColumn, "-created_info_at") //按创建时间排序 + filter := bson.M{} + if groupId != "" { + filter["group_id"] = groupId + } + + if searchText != "" { + r := bson.RegEx{Pattern: searchText, Options: "i"} + filter["$or"] = []bson.M{{"name": r}, {"group_name": r}, {"bundle_infos.bundle_id": r}} + } + + total, err := bindingTable.GetSome(ctx, filter, sortColumn, pageSize, pageNo, &bindingMongos) + bindings := make([]entity.Binding, 0) + for _, bindingMongo := range bindingMongos { + bindings = append(bindings, convertBindingMongoToBinding(bindingMongo)) + } + + return bindings, total, err +} + +func (b BindingByMongoRepo) GetAllAssBinds(ctx context.Context, appId string) ([]entity.Binding, error) { + bindings := make([]BindingMongo, 0) + err := bindingTable.OnlyGetAll(ctx, bson.M{"app_infos.appId": appId}, []string{}, &bindings) + if err != nil { + return nil, err + } + result := make([]entity.Binding, 0) + for _, bindingMongo := range bindings { + result = append(result, convertBindingMongoToBinding(bindingMongo)) + } + return result, nil +} + +func (b BindingByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func (b BindingByMongoRepo) UpdateBundleIdIsForbidden(ctx context.Context, bundleId string) error { + return bindingTable.UpdateAll(ctx, bson.M{"bundle_infos": bson.M{"$elemMatch": bson.M{"bundle_id": bundleId}}}, bson.M{"$set": bson.M{"is_forbidden": 1}}) +} + +func (b BindingByMongoRepo) UpdateBundleIdPlatform(ctx context.Context, bundleId, platform string) error { + return bindingTable.UpdateAll(ctx, bson.M{"bundle_infos": bson.M{"$elemMatch": bson.M{"bundle_id": bundleId}}}, bson.M{"$set": bson.M{"remark": platform}}) +} + +func (b BindingByMongoRepo) UpdateBundleBindingId(ctx context.Context, bundleId, bindingId, toBindingId string) error { + return nil +} + +func convertBindingMongoToBinding(bindingMongo BindingMongo) entity.Binding { + result := entity.Binding{} + + bundleInfos := make([]entity.BundleInfo, 0) + for _, v := range bindingMongo.BundleInfos { + bundleInfo := entity.BundleInfo{ + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + IsReview: v.IsReview, + } + + bundleInfos = append(bundleInfos, bundleInfo) + } + appInfos := make([]entity.AppInfo, 0) + for _, v := range bindingMongo.AppInfos { + item := entity.AppInfo{ + AppID: v.AppID, + AssociatedAt: v.AssociatedAt, + AssociatedBy: v.AssociatedBy, + } + appInfos = append(appInfos, item) + } + + createInfo := entity.CreatedInfo{ + CreatedBy: bindingMongo.CreatedInfoBy, + CreatedAt: bindingMongo.CreatedInfoAt, + } + + cooperateStatus := entity.Status{ + Value: bindingMongo.CooperateStatusValue, + Reason: bindingMongo.CooperateStatusReason, + LastUpdated: bindingMongo.CooperateStatusLastUpdated, + ModifiedBy: bindingMongo.CooperateStatusModifiedBy, + } + + cooperateValidStatus := entity.SpecificStatus{ + Reason: bindingMongo.CooperateValidStatusReason, + LastUpdated: bindingMongo.CooperateValidStatusLastUpdated, + ModifiedBy: bindingMongo.CooperateValidStatusModifiedBy, + } + + cooperateInvalidStatus := entity.SpecificStatus{ + Reason: bindingMongo.CooperateInvalidStatusReason, + LastUpdated: bindingMongo.CooperateInvalidStatusLastUpdated, + ModifiedBy: bindingMongo.CooperateInvalidStatusModifiedBy, + } + + //var appInfos []entity.AppInfo + //json.Unmarshal([]byte(bindingMongo.AppInfos), &appInfos) + + result.BindingID = bindingMongo.BindingID + result.Name = bindingMongo.Name + result.BundleInfos = bundleInfos + result.CreatedInfo = createInfo + result.GroupID = bindingMongo.GroupID + result.GroupName = bindingMongo.GroupName + result.CooperateStatus = cooperateStatus + result.CooperateValidStatus = cooperateValidStatus + result.CooperateInvalidStatus = cooperateInvalidStatus + result.AppInfos = appInfos + result.Owner = bindingMongo.Owner + result.Expire = bindingMongo.Expire + result.ApiServer = bindingMongo.ApiServer + result.PlatForm = bindingMongo.PlatForm + result.AutoBind = bindingMongo.AutoBind + result.HiddenBundle = bindingMongo.HiddenBundle + result.FromBindingID = bindingMongo.FromBindingID + return result +} + +func convertBindingToBindingMongo(binding *entity.Binding) BindingMongo { + result := BindingMongo{} + + bundleInfos := make([]BundleInfoData, 0) + for _, v := range binding.BundleInfos { + bundleInfo := BundleInfoData{ + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + IsReview: v.IsReview, + } + + bundleInfos = append(bundleInfos, bundleInfo) + } + + result.BindingID = binding.BindingID + result.Name = binding.Name + result.BundleInfos = bundleInfos + result.CreatedInfoBy = binding.CreatedInfo.CreatedBy + result.CreatedInfoAt = binding.CreatedInfo.CreatedAt + result.CreatedInfoAccount = binding.CreatedInfo.CreatedAccount + result.GroupID = binding.GroupID + result.GroupName = binding.GroupName + result.CooperateStatusValue = binding.CooperateStatus.Value + result.CooperateStatusReason = binding.CooperateStatus.Reason + result.CooperateStatusLastUpdated = binding.CooperateStatus.LastUpdated + result.CooperateStatusModifiedBy = binding.CooperateStatus.ModifiedBy + result.CooperateValidStatusReason = binding.CooperateValidStatus.Reason + result.CooperateValidStatusLastUpdated = binding.CooperateValidStatus.LastUpdated + result.CooperateValidStatusModifiedBy = binding.CooperateValidStatus.ModifiedBy + result.CooperateInvalidStatusReason = binding.CooperateInvalidStatus.Reason + result.CooperateInvalidStatusLastUpdated = binding.CooperateInvalidStatus.LastUpdated + result.CooperateInvalidStatusModifiedBy = binding.CooperateInvalidStatus.ModifiedBy + appInfos := make([]AppInfo, 0) + for _, v := range binding.AppInfos { + item := AppInfo{ + AppID: v.AppID, + AssociatedAt: v.AssociatedAt, + AssociatedBy: v.AssociatedBy, + } + appInfos = append(appInfos, item) + } + //result.AppInfos = utility.InterfaceToJsonString(binding.AppInfos) + result.AppInfos = appInfos + result.Owner = binding.Owner + result.Expire = binding.Expire + result.ApiServer = binding.ApiServer + result.PlatForm = binding.PlatForm + result.AutoBind = binding.AutoBind + result.HiddenBundle = binding.HiddenBundle + result.FromBindingID = binding.FromBindingID + return result +} diff --git a/infrastructure/db/repo/mongo/bundle.go b/infrastructure/db/repo/mongo/bundle.go new file mode 100644 index 0000000..9ad4274 --- /dev/null +++ b/infrastructure/db/repo/mongo/bundle.go @@ -0,0 +1,154 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IBundleRepo = new(BundleByMongoRepo) + +type BundleByMongoRepo struct { +} + +type BundleMongo struct { + BundleID string `json:"bundle_id" bson:"bundle_id"` + Remark string `json:"remark" bson:"remark"` + SDKKey string `json:"sdk_key" bson:"sdk_key"` + SDKID string `json:"sdk_id" bson:"sdk_id"` + IsFirstCreate bool `json:"is_first_create" bson:"is_first_create"` //是否第一次创建 + CreatedAt int64 `json:"created_at" bson:"created_at"` + CreatedAccount string `json:"created_account" bson:"created_account"` + CreatedBy string `json:"created_by" bson:"created_by"` + IsForbidden int `json:"is_forbidden" bson:"is_forbidden"` //0:可用 1:禁用 +} + +func (b BundleByMongoRepo) Insert(ctx context.Context, bundles []entity.Bundle) error { + var err error + for _, v := range bundles { + err = bundleTable.Insert(ctx, convertBundleToBundleMongo(v)) + } + if err != nil { + return err + } + return err +} + +func (b BundleByMongoRepo) GetListByBundleId(ctx context.Context, ids []string, pageNo int, pageSize int) (int, []entity.Bundle, error) { + bundleMongos := make([]BundleMongo, 0) + filter := bson.M{"bundle_id": bson.M{"$in": ids}} + total, err := bundleTable.GetSome(ctx, filter, []string{}, pageSize, pageNo, &bundleMongos) + if b.NotFound(err) { + return 0, []entity.Bundle{}, nil + } + + bundles := make([]entity.Bundle, 0) + for _, bundleMongo := range bundleMongos { + bundles = append(bundles, convertBundleMongoToBundle(bundleMongo)) + } + + return total, bundles, err +} + +func (b BundleByMongoRepo) GetListByBundleIds(ctx context.Context, ids []string) ([]entity.Bundle, error) { + bundles := make([]BundleMongo, 0) + filter := bson.M{"bundle_id": bson.M{"$in": ids}} + _, err := bundleTable.GetAllV2(ctx, filter, []string{}, &bundles) + if b.NotFound(err) { + return []entity.Bundle{}, nil + } + + result := make([]entity.Bundle, 0) + for _, bundleMongo := range bundles { + result = append(result, convertBundleMongoToBundle(bundleMongo)) + } + + return result, err +} + +func (b BundleByMongoRepo) ExistBundleId(ctx context.Context, bundleId string) (bool, error) { + total, err := bundleTable.Count(ctx, bson.M{"bundle_id": bundleId}) + if err != nil { + return false, err + } + return total > 0, nil +} + +func (b BundleByMongoRepo) GetInfoByBundleId(ctx context.Context, bundleId string) (entity.Bundle, error) { + mgoInfo := BundleMongo{} + err := bundleTable.GetOne(ctx, bson.M{"bundle_id": bundleId}, &mgoInfo) + if err != nil { + return entity.Bundle{}, err + } + return convertBundleMongoToBundle(mgoInfo), err +} + +func (b BundleByMongoRepo) ListAllBundleInfos(ctx context.Context, searchText string, selectType, pageNo int, pageSize int) (int, []entity.Bundle, error) { + bundleInfos := make([]BundleMongo, 0, pageSize) + filter := bson.M{} + if searchText != "" { + filter["bundle_id"] = bson.RegEx{Pattern: searchText, Options: "i"} + } + + if selectType == 1 { + filter["is_forbidden"] = 0 + } else if selectType == 2 { + filter["is_forbidden"] = 1 + } + pageNo += 1 + total, err := bundleTable.GetSome(context.Background(), filter, []string{"-created_at"}, pageSize, pageNo, &bundleInfos) + if err != nil { + return 0, nil, err + } + result := make([]entity.Bundle, 0) + for _, v := range bundleInfos { + result = append(result, convertBundleMongoToBundle(v)) + } + return total, result, nil +} + +func (b BundleByMongoRepo) AllCount(ctx context.Context) (int, error) { + return bundleTable.Count(ctx, bson.M{"is_forbidden": 0}) +} + +func (b BundleByMongoRepo) UpdateBundleForbidden(ctx context.Context, bundleId string, IsForbidden int) error { + return bundleTable.UpdateOne(ctx, bson.M{"bundle_id": bundleId}, bson.M{"$set": bson.M{"is_forbidden": IsForbidden}}) +} +func (b BundleByMongoRepo) UpdateBundlePlatform(ctx context.Context, bundleId, remark string) error { + return bundleTable.UpdateOne(ctx, bson.M{"bundle_id": bundleId}, bson.M{"$set": bson.M{"remark": remark}}) + +} +func (b BundleByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertBundleToBundleMongo(bundleInfo entity.Bundle) BundleMongo { + result := BundleMongo{} + result.BundleID = bundleInfo.BundleID + result.Remark = bundleInfo.Remark + result.SDKKey = bundleInfo.SDKKey + result.SDKID = bundleInfo.SDKID + result.IsFirstCreate = bundleInfo.IsFirstCreate + result.CreatedAt = bundleInfo.CreatedAt + result.CreatedAccount = bundleInfo.CreatedAccount + result.CreatedBy = bundleInfo.CreatedBy + result.IsForbidden = bundleInfo.IsForbidden + return result +} + +func convertBundleMongoToBundle(bundleMongo BundleMongo) entity.Bundle { + result := entity.Bundle{} + result.BundleID = bundleMongo.BundleID + result.Remark = bundleMongo.Remark + result.SDKKey = bundleMongo.SDKKey + result.SDKID = bundleMongo.SDKID + result.IsFirstCreate = bundleMongo.IsFirstCreate + result.CreatedAt = bundleMongo.CreatedAt + result.CreatedAccount = bundleMongo.CreatedAccount + result.CreatedBy = bundleMongo.CreatedBy + result.IsForbidden = bundleMongo.IsForbidden + return result +} diff --git a/infrastructure/db/repo/mongo/link_audit.go b/infrastructure/db/repo/mongo/link_audit.go new file mode 100644 index 0000000..7c3ff38 --- /dev/null +++ b/infrastructure/db/repo/mongo/link_audit.go @@ -0,0 +1,39 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/repository" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.ILinkAuditRepo = new(LinkAuditByMongoRepo) + +type LinkAuditByMongoRepo struct { +} + +type LinkAuditMongo struct { + AuditId string `json:"auditId" bson:"audit_id"` //id + Version int `json:"version" bson:"version"` //审核序号 + AppId string `json:"appId" bson:"app_id"` //应用名称 + AppName string `json:"appName" bson:"app_name"` //应用名称 + BindingId string `json:"bindingId" bson:"binding_id"` //应用名称 + BindingName string `json:"bindingName" bson:"binding_name"` //应用名称 + GroupID string `json:"groupId" bson:"group_id"` //企业ID + Owner string `json:"owner" bson:"owner"` //所属企业 + ApplyBy string `json:"applyBy" bson:"apply_by"` // 申请人 + ApplyStatus string `json:"applyStatus" bson:"apply_status"` // 审核状态 + ApplyAt int64 `json:"applyAt" bson:"apply_at"` // timestamp + AuditBy string `json:"auditBy" bson:"audit_by"` // 审核人 + AuditAt int64 `json:"auditAt" bson:"audit_at"` // 审核人 + AssociateStatus string `json:"associateStatus" bson:"associate_status"` //绑定状态 + Reason string `json:"reason" bson:"reason"` //原因 +} + +func (l LinkAuditByMongoRepo) Count(ctx context.Context, appID string, groupId string, bindingID string, stLinkAudit string) (int, error) { + return linkAuditTable.Count(ctx, bson.M{"app_id": appID, "group_id": groupId, "binding_id": bindingID, "apply_status": stLinkAudit}) +} + +func (l LinkAuditByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} diff --git a/infrastructure/db/repo/mongo/menu_info.go b/infrastructure/db/repo/mongo/menu_info.go new file mode 100644 index 0000000..ae9d25d --- /dev/null +++ b/infrastructure/db/repo/mongo/menu_info.go @@ -0,0 +1,172 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IMenuInfoRepo = new(MenuInfoByMongoRepo) + +type MenuInfoByMongoRepo struct { +} + +type MenuInfoMongo struct { + TraceId string `bson:"trace_id" json:"traceId"` + Name string `bson:"name" json:"name"` + InfoId string `bson:"info_id" json:"infoId"` + ImageUrl string `bson:"image_url" json:"imageUrl"` + SortNum int `bson:"sort_num" json:"sortNum"` + CreateTime int64 `bson:"create_time" json:"createTime"` + UpdateTime int64 `bson:"update_time" json:"updateTime"` + UpdateOperator string `bson:"update_operator" json:"updateOperator"` +} + +func (b MenuInfoByMongoRepo) GetInfoByTraceId(ctx context.Context, id string) (*entity.MenuInfo, error) { + menuInfoMongo := MenuInfoMongo{} + err := menuInfoTable.GetOne(ctx, bson.M{"trace_id": id}, &menuInfoMongo) + if err != nil { + if NotFound(err) { + log.Errorf("GetInfoByTraceId err:%s", err.Error()) + return &entity.MenuInfo{}, entity.NotFoundErr + } + } + + result := convertMenuInfoMongoToMenuInfo(menuInfoMongo) + return &result, err +} + +func (b MenuInfoByMongoRepo) GetAllMenuList(ctx context.Context, sort []string) ([]entity.MenuInfo, int, error) { + menuInfoMongos := make([]MenuInfoMongo, 0) + total, err := menuInfoTable.GetAll(ctx, bson.M{}, sort, &menuInfoMongos) + if b.NotFound(err) { + return []entity.MenuInfo{}, 0, nil + } + + menuInfos := make([]entity.MenuInfo, 0) + for _, menuInfoMongo := range menuInfoMongos { + menuInfos = append(menuInfos, convertMenuInfoMongoToMenuInfo(menuInfoMongo)) + } + + return menuInfos, total, err +} + +func (b MenuInfoByMongoRepo) Add(ctx context.Context, info *entity.MenuInfo) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + count, err := menuInfoTable.Count(ctx, bson.M{"$or": []bson.M{ + {"info_id": info.InfoId}, + {"name": info.Name}, + }}) + if err != nil { + return err + } + if count > 0 { + return entity.MenuIdOrNameExiErr + } + + nextSortNum, err := b.GetNextSortNum(ctx) + if err != nil { + return err + } + + info.SortNum = nextSortNum + + return menuInfoTable.Insert(ctx, convertMenuInfoToMenuInfoMongo(info)) +} + +func (b MenuInfoByMongoRepo) GetNextSortNum(ctx context.Context) (int, error) { + latestInfo := new(MenuInfoMongo) + err := menuInfoTable.GetSortOne(ctx, bson.M{}, []string{"-sort_num"}, latestInfo) + if b.NotFound(err) { + return 1, nil + } + return latestInfo.SortNum + 1, nil +} + +func (b MenuInfoByMongoRepo) DelByTraceId(ctx context.Context, id string) error { + return menuInfoTable.Del(ctx, bson.M{"trace_id": id}) +} + +func (b MenuInfoByMongoRepo) UpdateInfo(ctx context.Context, id string, info *entity.MenuInfo) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + menuInfoMongos := make([]MenuInfoMongo, 0) + _, err := menuInfoTable.GetAll(ctx, bson.M{"$or": []bson.M{ + {"info_id": info.InfoId}, + {"name": info.Name}, + }}, []string{}, &menuInfoMongos) + if err != nil && !b.NotFound(err) { + return err + } + + for _, m := range menuInfoMongos { + if m.TraceId != id { + return entity.MenuIdOrNameExiErr + } + } + return menuInfoTable.UpdateOne(ctx, bson.M{"trace_id": id}, info) +} + +func (b MenuInfoByMongoRepo) AllCount(ctx context.Context) (int, error) { + return menuInfoTable.Count(ctx, bson.M{}) +} + +func (b MenuInfoByMongoRepo) Sort(ctx context.Context, req *apiproto.MenuSortReq) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + var resError error + for _, v := range req.List { + err := menuInfoTable.UpdateData(bson.M{"trace_id": v.TraceId}, bson.M{"$set": bson.M{"sort_num": v.SortNum}}) + if err != nil { + err = err + } + } + return resError +} + +func (b MenuInfoByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertMenuInfoMongoToMenuInfo(menuInfoMongo MenuInfoMongo) entity.MenuInfo { + result := entity.MenuInfo{} + + result.TraceId = menuInfoMongo.TraceId + result.Name = menuInfoMongo.Name + result.InfoId = menuInfoMongo.InfoId + result.ImageUrl = menuInfoMongo.ImageUrl + result.SortNum = menuInfoMongo.SortNum + result.CreateTime = menuInfoMongo.CreateTime + result.UpdateTime = menuInfoMongo.UpdateTime + result.UpdateOperator = menuInfoMongo.UpdateOperator + + return result +} + +func convertMenuInfoToMenuInfoMongo(menuInfo *entity.MenuInfo) MenuInfoMongo { + result := MenuInfoMongo{} + + result.TraceId = menuInfo.TraceId + result.Name = menuInfo.Name + result.InfoId = menuInfo.InfoId + result.ImageUrl = menuInfo.ImageUrl + result.SortNum = menuInfo.SortNum + result.CreateTime = menuInfo.CreateTime + result.UpdateTime = menuInfo.UpdateTime + result.UpdateOperator = menuInfo.UpdateOperator + + return result +} diff --git a/infrastructure/db/repo/mongo/mongo.go b/infrastructure/db/repo/mongo/mongo.go new file mode 100644 index 0000000..5f4cd56 --- /dev/null +++ b/infrastructure/db/repo/mongo/mongo.go @@ -0,0 +1,34 @@ +package mongo + +import ( + "finclip-app-manager/infrastructure/config" + "fmt" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" +) + +//每次使用的时候copy一个,用完之后close +var Dbsession *mgo.Session + +//func init() { +// start() +//} + +func Start() error { + url := config.GetConfig().MongoURL + var err error + Dbsession, err = mgo.Dial(url) + if err != nil { + panic(err) + } + if Dbsession == nil { + panic("mongo db session is nil!") + } + + Dbsession.SetMode(mgo.Strong, true) + fmt.Println("mongo start success ...") + return nil +} + +func Copy() *mgo.Session { + return Dbsession.Copy() +} diff --git a/infrastructure/db/repo/mongo/privacy_setting_info.go b/infrastructure/db/repo/mongo/privacy_setting_info.go new file mode 100644 index 0000000..9348d32 --- /dev/null +++ b/infrastructure/db/repo/mongo/privacy_setting_info.go @@ -0,0 +1,71 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/db/entity/mongo" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.IPrivacySettingRepo = new(PrivacySettingRepoMongoRepo) + +type PrivacySettingRepoMongoRepo struct { +} + +func NewPrivacySettingRepoMongoRepo() *PrivacySettingRepoMongoRepo { + return &PrivacySettingRepoMongoRepo{} +} + +func (a *PrivacySettingRepoMongoRepo) Insert(ctx context.Context, item entity.PrivacySettingInfo) error { + return privacyTable.Insert(ctx, tr.CovertPrivacySettingInfoToMongo(&item)) +} +func (a *PrivacySettingRepoMongoRepo) Count(ctx context.Context, appId string) (int, error) { + return privacyTable.Count(ctx, bson.M{"app_id": appId}) +} +func (a *PrivacySettingRepoMongoRepo) GetInfoByAppId(ctx context.Context, appId string) (*entity.PrivacySettingInfo, error) { + privacySettingInfoMongo := mongo.PrivacySettingInfoMongo{} + err := privacyTable.GetOne(ctx, bson.M{"app_id": appId}, &privacySettingInfoMongo) + if err != nil { + if NotFound(err) { + log.Errorf("GetInfoByTraceId err:%s", err.Error()) + return &entity.PrivacySettingInfo{}, entity.NotFoundErr + } + } + + result := tr.CovertPrivacySettingInfoToEntity(&privacySettingInfoMongo) + return result, err +} +func (a *PrivacySettingRepoMongoRepo) UpdateInfo(ctx context.Context, info entity.PrivacySettingInfo) error { + params := map[string]interface{}{} + params["app_id"] = info.AppId + params["commit_type"] = info.CommitType + params["user_message_type"] = info.UserMessageType + params["sdk_message"] = info.SdkMessage + params["contact_info_phone"] = info.ContactInfoPhone + params["contact_info_email"] = info.ContactInfoEmail + params["contact_info_wechat"] = info.ContactInfoWeChat + params["contact_info_other"] = info.ContactInfoOther + params["fixed_storage_time"] = info.FixedStorageTime + params["is_shortest_time"] = info.IsShortestTime + params["additional_doc_name"] = info.AdditionalDocName + params["additional_doc_netdiskid"] = info.AdditionalDocNetDiskId + params["additional_doc_content"] = info.AdditionalDocContent + params["is_first_save"] = info.IsFirstSave + params["effective_time"] = info.EffectiveTime + params["create_time"] = info.CreateTime + params["update_time"] = info.UpdateTime + filter := bson.M{ + "app_id": info.AppId, + } + return privacyTable.UpdateOne(ctx, filter, bson.M{"$set": params}) + +} + +func (a PrivacySettingRepoMongoRepo) DelInfoByAppId(ctx context.Context, appId string) error { + return privacyTable.Del(ctx, bson.M{"app_id": appId}) +} +func (a PrivacySettingRepoMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} diff --git a/infrastructure/db/repo/mongo/public.go b/infrastructure/db/repo/mongo/public.go new file mode 100644 index 0000000..9b9e511 --- /dev/null +++ b/infrastructure/db/repo/mongo/public.go @@ -0,0 +1,42 @@ +package mongo + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/db/translator" + "finclip-app-manager/infrastructure/logger" + + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" +) + +const ( + AppTableName = "app" + AppVersionTableName = "appVersion" + menuInfoTableName = "menu_info" + TableWechatInfo = "wechatInfo" + TypeConfigTableName = "type_config" +) + +var ( + appTable = NewTable("app") + appVerTable = NewTable("appVersion") + menuInfoTable = NewTable("menu_info") + qrCodeInfoTable = NewTable("qr_code_info") + typeConfigTable = NewTable("type_config") + appTempInfoTable = NewTable("app_temp_info") + bindingTable = NewTable("binding") + bundleTable = NewTable("bundle") + linkAuditTable = NewTable("link_audit") + redDotTable = NewTable("red_dot_read_record") + bundleInfoTable = NewTable("bundle_info") + appBuildInfoTable = NewTable("appBuildInfo") + wechatTable = NewTable("wechatInfo") + privacyTable = NewTable("privacy_setting") + appOperConfigTable = NewTable("app_oper_config") + + tr = translator.NewMgoTranslator() + log = logger.GetLogger() +) + +func NotFound(err error) bool { + return err == mgo.ErrNotFound || err == entity.NotFoundErr || err == entity.ErrNotFound +} diff --git a/infrastructure/db/repo/mongo/qr_code_info.go b/infrastructure/db/repo/mongo/qr_code_info.go new file mode 100644 index 0000000..90be780 --- /dev/null +++ b/infrastructure/db/repo/mongo/qr_code_info.go @@ -0,0 +1,226 @@ +package mongo + +import ( + "context" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/utility" + "finclip-app-manager/infrastructure/utils" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "time" +) + +var _ repository.IQrCodeInfoRepo = new(QrCodeInfoByMongoRepo) + +type QrCodeInfoByMongoRepo struct { +} + +type QrCodeInfoMongo struct { + Type string `json:"type" bson:"type"` //二维码的类型 + Uuid string `json:"uuid" bson:"uuid"` //标识该二维码 + AppId string `json:"appId" bson:"app_id"` //小程序Id + Sequence int `json:"sequence" bson:"sequence"` //小程序序列号 + ApiServer string `json:"apiServer" bson:"api_server"` //小程序apiServer + CodeId string `json:"codeId" bson:"code_id"` //标识某个编译版本的id + PathAndQuery string `json:"pathAndQuery" bson:"path_and_query"` //小程序启动参数 + ExpireTime int64 `json:"expireTime" bson:"expire_time"` //过期时间 + CreateTime int64 `json:"createTime" bson:"create_time"` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"Update_time"` //更新时间 + DeleteTime int64 `json:"deleteTime" bson:"Delete_time"` //删除时间-暂不用 + DebugInfo map[string]interface{} `json:"debugInfo" bson:"debug_info"` //拓展数据 +} + +func (q QrCodeInfoByMongoRepo) Insert(ctx context.Context, info *entity.QrCodeInfo) error { + return qrCodeInfoTable.Insert(ctx, convertQrCodeInfoToQrCodeInfoMongo(info)) +} + +func (q QrCodeInfoByMongoRepo) GenInfo(ctx context.Context, info *entity.QrCodeInfo) error { + switch info.Type { + case entity.QrCodeTypeReview: + count, err := qrCodeInfoTable.Count(ctx, bson.M{"type": info.Type, "app_id": info.AppId, "sequence": info.Sequence}) + if err != nil { + return err + } + //如果存在就不再进行插入 + if count > 0 { + return nil + } + case entity.QrCodeTypeRelease: + count, err := qrCodeInfoTable.Count(ctx, bson.M{"type": info.Type, "app_id": info.AppId}) + if err != nil { + return err + } + //如果已经存在,更新就好 + if count > 0 { + return qrCodeInfoTable.UpdateData(bson.M{"type": info.Type, "app_id": info.AppId}, bson.M{"$set": bson.M{"update_time": time.Now().UnixNano() / 1e6}}) + } + case entity.QrCodeTypeTrial: + count, err := qrCodeInfoTable.Count(ctx, bson.M{"type": info.Type, "app_id": info.AppId}) + if err != nil { + return err + } + if count > 0 { + upInfo := bson.M{"$set": bson.M{"path_and_query": "", "code_id": info.CodeId, "update_time": utils.GetNowMs()}} + return qrCodeInfoTable.UpdateData(bson.M{"type": info.Type, "app_id": info.AppId}, upInfo) + } + case entity.QrCodeTypeTemporary: + //直接插入 + default: + return errors.New("info type err") + } + //不存在就插入 + return qrCodeInfoTable.Insert(ctx, convertQrCodeInfoToQrCodeInfoMongo(info)) +} + +func (q QrCodeInfoByMongoRepo) GetInfoByUuid(ctx context.Context, uuid string) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"uuid": uuid}, &qrCodeInfoMongo) + log.Infof(utility.InterfaceToJsonString(qrCodeInfoMongo)) + if err != nil { + return nil, err + } + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetInfoByCodeId(ctx context.Context, codeId string) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"code_id": codeId}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetReviewInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"type": entity.QrCodeTypeReview, "app_id": appId, "sequence": seq}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetReleaseInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"type": entity.QrCodeTypeRelease, "app_id": appId}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetTrialInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"type": entity.QrCodeTypeTrial, "app_id": appId}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetTemporaryInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"type": entity.QrCodeTypeTemporary, "app_id": appId}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) GetRemoteDebugInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + qrCodeInfoMongo := QrCodeInfoMongo{} + err := qrCodeInfoTable.GetOne(ctx, bson.M{"type": entity.QrCodeTypeRomoteDebug, "app_id": appId, "sequence": seq}, &qrCodeInfoMongo) + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo) + + return &result, err +} + +func (q QrCodeInfoByMongoRepo) UpdateTrialStartParams(ctx context.Context, codeId string, p entity.AppStartParams) error { + return qrCodeInfoTable.UpdateData(bson.M{"type": entity.QrCodeTypeTrial, "code_id": codeId}, bson.M{"$set": bson.M{"path_and_query": p.PathAndQuery}}) +} + +func (q QrCodeInfoByMongoRepo) UpdateStartParamsByUuid(ctx context.Context, uuid string, p entity.AppStartParams) error { + return qrCodeInfoTable.UpdateData(bson.M{"uuid": uuid}, bson.M{"$set": bson.M{"path_and_query": p.PathAndQuery}}) +} + +func (q QrCodeInfoByMongoRepo) UpdateApiServer(ctx context.Context, uuid string, apiServer string) error { + return qrCodeInfoTable.UpdateData(bson.M{"uuid": uuid}, bson.M{"$set": bson.M{"api_server": apiServer}}) +} + +func (q QrCodeInfoByMongoRepo) UpdateInfo(ctx context.Context, uuid string, upInfo map[string]interface{}) error { + params := make(map[string]interface{}) + if t, ok := upInfo["expire_time"]; ok { + params["expire_time"] = t + } + return qrCodeInfoTable.UpdateData(bson.M{"uuid": uuid}, bson.M{"$set": params}) +} + +func (q QrCodeInfoByMongoRepo) GenReviewQrCodeInfo(ctx context.Context, info *entity.QrCodeInfo) error { + return nil +} + +func (q QrCodeInfoByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertQrCodeInfoToQrCodeInfoMongo(qrCodeInfo *entity.QrCodeInfo) QrCodeInfoMongo { + result := QrCodeInfoMongo{} + + result.Type = qrCodeInfo.Type + result.Uuid = qrCodeInfo.Uuid + result.AppId = qrCodeInfo.AppId + result.Sequence = qrCodeInfo.Sequence + result.ApiServer = qrCodeInfo.ApiServer + result.CodeId = qrCodeInfo.CodeId + result.PathAndQuery = qrCodeInfo.StartParams.PathAndQuery + result.ExpireTime = qrCodeInfo.ExpireTime + result.CreateTime = qrCodeInfo.CreateTime + result.UpdateTime = qrCodeInfo.UpdateTime + result.DeleteTime = qrCodeInfo.DeleteTime + result.DebugInfo = qrCodeInfo.DebugInfo + return result +} + +func convertQrCodeInfoMongoToQrCodeInfo(qrCodeInfoMongo QrCodeInfoMongo) entity.QrCodeInfo { + result := entity.QrCodeInfo{} + + appStartParams := entity.AppStartParams{ + PathAndQuery: qrCodeInfoMongo.PathAndQuery, + } + + result.Type = qrCodeInfoMongo.Type + result.Uuid = qrCodeInfoMongo.Uuid + result.AppId = qrCodeInfoMongo.AppId + result.Sequence = qrCodeInfoMongo.Sequence + result.ApiServer = qrCodeInfoMongo.ApiServer + result.CodeId = qrCodeInfoMongo.CodeId + result.StartParams = appStartParams + result.ExpireTime = qrCodeInfoMongo.ExpireTime + result.CreateTime = qrCodeInfoMongo.CreateTime + result.UpdateTime = qrCodeInfoMongo.UpdateTime + result.DeleteTime = qrCodeInfoMongo.DeleteTime + result.DebugInfo = qrCodeInfoMongo.DebugInfo + return result +} diff --git a/infrastructure/db/repo/mongo/red_dot.go b/infrastructure/db/repo/mongo/red_dot.go new file mode 100644 index 0000000..80674ee --- /dev/null +++ b/infrastructure/db/repo/mongo/red_dot.go @@ -0,0 +1,49 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "time" +) + +var _ repository.IRedDotRepo = new(RedDotByMongoRepo) + +type RedDotByMongoRepo struct { +} + +type RedDotReadRecordMongo struct { + Type string `json:"type" bson:"type"` //红点类型 + TraceId string `json:"traceId" bson:"trace_id"` //红点唯一标识 + AccountId string `json:"accountId" bson:"account_id"` //已经阅读的账户Id + CreateTime int64 `json:"createTime" bson:"create_time""` //创建时间 + UpdateTime int64 `json:"updateTime" bson:"update_time"` //更新时间 +} + +func (r RedDotByMongoRepo) ReadTrialQr(ctx context.Context, readDotType string, id string, userId string) error { + info := entity.RedDotReadRecord{ + Type: readDotType, + TraceId: id, + AccountId: userId, + CreateTime: time.Now().UnixNano() / 1e6, + } + return redDotTable.Insert(ctx, convertRedDotReadRecordToRedDotReadRecordMongo(&info)) +} + +func (r RedDotByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertRedDotReadRecordToRedDotReadRecordMongo(redDotReadRecord *entity.RedDotReadRecord) RedDotReadRecordMongo { + result := RedDotReadRecordMongo{} + + result.Type = redDotReadRecord.Type + result.TraceId = redDotReadRecord.TraceId + result.AccountId = redDotReadRecord.AccountId + result.CreateTime = redDotReadRecord.CreateTime + result.UpdateTime = redDotReadRecord.UpdateTime + + return result +} + diff --git a/infrastructure/db/repo/mongo/table.go b/infrastructure/db/repo/mongo/table.go new file mode 100644 index 0000000..ae552de --- /dev/null +++ b/infrastructure/db/repo/mongo/table.go @@ -0,0 +1,316 @@ +package mongo + +import ( + "context" + "finclip-app-manager/infrastructure/config" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "gitlab.finogeeks.club/finclip-backend/apm" + "time" +) + +type Table struct { + DbName string + CollName string +} + +func NewTable(colName string) *Table { + return &Table{ + DbName: config.Cfg.DBName, + CollName: colName, + } +} + +func (t *Table) GetOne(ctx context.Context, filter bson.M, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetOne", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetOne") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + return col.Find(filter).One(result) +} + +func (t *Table) GetSortOne(ctx context.Context, filter bson.M, sort []string, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetSortOne", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetSortOne") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + query := col.Find(filter) + return query.Sort(sort...).Limit(1).One(result) +} + +func (t *Table) GetSome(ctx context.Context, filter bson.M, sort []string, pageSize, pageNo int, result interface{}) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetSome", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetSome") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + query := col.Find(filter) + total, err := query.Count() + if err != nil { + return 0, err + } + return total, query.Sort(sort...).Skip(pageSize * (pageNo - 1)).Limit(pageSize).All(result) +} + +func (t *Table) OnlyGetSome(ctx context.Context, filter bson.M, sort []string, pageSize, pageNo int, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetSome", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetSome") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + query := col.Find(filter) + return query.Sort(sort...).Skip(pageSize * (pageNo - 1)).Limit(pageSize).All(result) + +} + +func (t *Table) GetAll(ctx context.Context, filter bson.M, sort []string, result interface{}) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetAll", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetAll") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + query := col.Find(filter) + total, err := query.Count() + if err != nil { + return 0, err + } + return total, query.Sort(sort...).All(result) +} + +func (t *Table) GetAllV2(ctx context.Context, filter bson.M, sort []string, result interface{}) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetAll", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetAll") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + query := col.Find(filter) + total, err := query.Count() + if err != nil { + return 0, err + } + if err := query.Sort(sort...).All(result); err != nil { + return 0, err + } + return total, nil +} + +func (t *Table) OnlyGetAll(ctx context.Context, filter bson.M, sort []string, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetAll", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetAll") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + query := col.Find(filter) + if err := query.Sort(sort...).All(result); err != nil { + return err + } + return nil +} + +func (t *Table) GetAllAndSomeField(ctx context.Context, filter bson.M, selector bson.M, sort []string, result interface{}) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.GetAllAndSomeField", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "GetAllAndSomeField") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + query := col.Find(filter) + total, err := query.Count() + if err != nil { + return 0, err + } + return total, query.Sort(sort...).Select(selector).All(result) +} + +func (t *Table) Aggregate(ctx context.Context, pipeSelector []bson.M, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.Aggregate", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "Aggregate") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + return col.Pipe(pipeSelector).All(result) +} + +func (t *Table) AggregateOnly(ctx context.Context, pipeSelector []bson.M, result interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.AggregateOnly", config.Cfg.MongoURL, t.DbName) + defer span.End() + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + if err := col.Pipe(pipeSelector).All(result); err != nil { + log.Errorf("pip find error:%s", err.Error()) + span.Error(time.Now(), "collection", t.DbName, "method", "Pipe.All", "error", err.Error()) + return err + } + span.Log(time.Now(), "collection", t.DbName, "method", "Pipe.All") + return nil +} + +func (t *Table) AggregateCount(ctx context.Context, countPip []bson.M) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.AggregateCount", config.Cfg.MongoURL, t.DbName) + defer span.End() + + type TotalInfo struct { + Id string `bson:"_id"` + Total int `bson:"total"` + } + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + result := &TotalInfo{} + err := col.Pipe(countPip).One(result) + if err != nil && err != mgo.ErrNotFound { + log.Errorf("pip find error:%s", err.Error()) + span.Error(time.Now(), "collection", t.CollName, "method", "Pipe.One", "error", err.Error()) + return 0, err + } + if err == mgo.ErrNotFound { + span.Error(time.Now(), "collection", t.CollName, "method", "Pipe.One", "error", err.Error()) + return 0, nil + } + span.Log(time.Now(), "collection", t.CollName, "method", "Pipe.One") + return result.Total, nil +} + +func (t *Table) Insert(ctx context.Context, data interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.Insert", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "Insert") + + conn := Dbsession.Copy() + defer conn.Close() + return conn.DB(t.DbName).C(t.CollName).Insert(data) +} + +func (t *Table) UpdateOne(ctx context.Context, selector bson.M, update interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.UpdateOne", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "UpdateOne") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + return col.Update(selector, update) +} + +func (t *Table) UpdateAll(ctx context.Context, selector bson.M, update interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.UpdateAll", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "UpdateAll") + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + _, err := col.UpdateAll(selector, update) + return err +} + +func (t *Table) Upsert(selector bson.M, update interface{}) error { + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + _, err := col.Upsert(selector, update) + return err +} + +func (t *Table) UpdateData(filter bson.M, data bson.M) error { + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + return col.Update(filter, data) +} + +func (t *Table) UpSert(filter bson.M, data interface{}) error { + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + + _, err := col.Upsert(filter, data) + return err +} + +func (t *Table) EnsureIndex(index mgo.Index) error { + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + return col.EnsureIndex(index) +} + +func (t *Table) Count(ctx context.Context, filter bson.M) (int, error) { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.Count", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "Count") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + total, err := col.Find(filter).Count() + if err != nil { + return 0, err + } + return total, nil +} + +func (t *Table) Del(ctx context.Context, selector bson.M) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.Del", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "Del") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + err := col.Remove(selector) + if err != nil && err != mgo.ErrNotFound { + return err + } + return err +} + +func (t *Table) DelAll(ctx context.Context, selector bson.M) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.DelAll", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "DelAll") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + _, err := col.RemoveAll(selector) + if err != nil && err != mgo.ErrNotFound { + return err + } + return err +} + +func (t *Table) BulkInsert(ctx context.Context, list []interface{}) error { + span := apm.ApmClient().CreateMongoExitSpan(ctx, "Table.BulkInsert", config.Cfg.MongoURL, t.DbName) + defer span.End() + span.Log(time.Now(), "collection", t.CollName, "method", "BulkInsert") + + conn := Dbsession.Copy() + defer conn.Close() + col := conn.DB(t.DbName).C(t.CollName) + b := col.Bulk() + b.Insert(list...) + _, err := b.Run() + if err != nil { + return err + } + return err +} diff --git a/infrastructure/db/repo/mongo/type_config.go b/infrastructure/db/repo/mongo/type_config.go new file mode 100644 index 0000000..8bedd92 --- /dev/null +++ b/infrastructure/db/repo/mongo/type_config.go @@ -0,0 +1,133 @@ +package mongo + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + mgo "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" +) + +var _ repository.ITypeConfigRepo = new(TypeConfigByMongoRepo) + +type TypeConfigByMongoRepo struct { +} + +func NewTypeConfigByMongoRepo() *TypeConfigByMongoRepo { + return &TypeConfigByMongoRepo{} +} + +type TypeConfigMongo struct { + TypeConfigID string `json:"typeConfigId" bson:"type_config_id"` + Namespace string `json:"namespace" bson:"namespace"` + Value string `json:"value" bson:"value"` + MarketID string `json:"marketId" bson:"market_id"` + Chinese string `json:"chinese" bson:"chinese"` + //CustomData string `json:"customData" bson:"customData"` + SortNum int `json:"sortNum" bson:"sort_num"` +} + +func (t TypeConfigByMongoRepo) Insert(ctx context.Context, typeConfig *entity.TypeConfig) error { + return typeConfigTable.Insert(ctx, convertTypeConfigToTypeConfigMongo(typeConfig)) +} + +func (t TypeConfigByMongoRepo) GetOne(ctx context.Context, filter bson.M) error { + panic("implement me") +} + +func (t TypeConfigByMongoRepo) Exist(ctx context.Context, namespace string, value string) (bool, error) { + typeConfigMongo := TypeConfigMongo{} + err := typeConfigTable.GetOne(ctx, bson.M{"namespace": namespace, "value": value}, &typeConfigMongo) + if err != nil && t.NotFound(err) { + return false, err + } + + return true, err +} + +func (t TypeConfigByMongoRepo) Update(ctx context.Context, selector bson.M, update bson.M) error { + panic("implement me") +} + +func (t TypeConfigByMongoRepo) GetSome(ctx context.Context, pageSize, pageNo int) (int, []entity.TypeConfig, error) { + typeConfigMongos := make([]TypeConfigMongo, 0) + total, err := typeConfigTable.GetSome(ctx, bson.M{}, []string{}, pageSize, pageNo, &typeConfigMongos) + if err != nil { + return 0, nil, err + } + + typeConfigs := make([]entity.TypeConfig, 0) + for _, typeConfigMongo := range typeConfigMongos { + typeConfig := convertTypeConfigMongoToTypeConfig(typeConfigMongo) + typeConfigs = append(typeConfigs, typeConfig) + } + + return int(total), typeConfigs, err +} + +func (t TypeConfigByMongoRepo) GetAll(ctx context.Context) (int, []entity.TypeConfig, error) { + typeConfigMongos := make([]TypeConfigMongo, 0) + total, err := typeConfigTable.GetAll(ctx, bson.M{}, []string{}, &typeConfigMongos) + if err != nil { + return 0, nil, err + } + + typeConfigs := make([]entity.TypeConfig, 0) + for _, typeConfigMongo := range typeConfigMongos { + typeConfig := convertTypeConfigMongoToTypeConfig(typeConfigMongo) + typeConfigs = append(typeConfigs, typeConfig) + } + + return int(total), typeConfigs, err +} + +func (t TypeConfigByMongoRepo) Delete(ctx context.Context, typeConfigId string) error { + return typeConfigTable.Del(ctx, bson.M{"type_config_id": typeConfigId}) +} + +func (t TypeConfigByMongoRepo) GetNowSortNumInfo(ctx context.Context) (*entity.TypeConfig, error) { + typeConfigMongo := TypeConfigMongo{} + err := typeConfigTable.GetSortOne(ctx, bson.M{"sort_num": bson.M{"$lt": 99990000}}, []string{"-sort_num"}, &typeConfigMongo) + if err != nil { + return nil, err + } + + result := convertTypeConfigMongoToTypeConfig(typeConfigMongo) + + return &result, err +} + +func (t TypeConfigByMongoRepo) NotFound(err error) bool { + return err == mgo.ErrNotFound +} + +func convertTypeConfigMongoToTypeConfig(typeConfigMongo TypeConfigMongo) entity.TypeConfig { + result := entity.TypeConfig{} + + //var customData entity.TypeConfigCustomData + //json.Unmarshal([]byte(typeConfigMongo.CustomData), &customData) + + result.TypeConfigID = typeConfigMongo.TypeConfigID + result.Namespace = typeConfigMongo.Namespace + result.Value = typeConfigMongo.Value + result.MarketID = typeConfigMongo.MarketID + //result.CustomData = customData + result.CustomData.Chinese = typeConfigMongo.Chinese + result.SortNum = typeConfigMongo.SortNum + + return result +} + +func convertTypeConfigToTypeConfigMongo(typeConfig *entity.TypeConfig) TypeConfigMongo { + result := TypeConfigMongo{} + + result.TypeConfigID = typeConfig.TypeConfigID + result.Namespace = typeConfig.Namespace + result.Value = typeConfig.Value + result.MarketID = typeConfig.MarketID + result.Chinese = typeConfig.CustomData.Chinese + //result.CustomData = utility.InterfaceToJsonString(typeConfig.CustomData) + result.SortNum = typeConfig.SortNum + + return result +} diff --git a/infrastructure/db/repo/mysql/app.go b/infrastructure/db/repo/mysql/app.go new file mode 100644 index 0000000..ab7a7a8 --- /dev/null +++ b/infrastructure/db/repo/mysql/app.go @@ -0,0 +1,1694 @@ +package mysql + +import ( + "context" + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/infrastructure/db/entity/sql" + "finclip-app-manager/infrastructure/utils" + "strings" + "time" + + "gorm.io/gorm" +) + +type AppRepo struct { +} + +func NewAppRepo() *AppRepo { + return &AppRepo{} +} + +func (ar *AppRepo) AppCount(ctx context.Context, organId string) (int, error) { + + var ( + total int64 + err error + ) + if organId != "" { + err = DB.Model(&sql.App{}).Where("organ_id=? and is_forbidden=?", organId, 0).Count(&total).Error + } else { + err = DB.Model(&sql.App{}).Where("is_forbidden=?", 0).Count(&total).Error + } + return int(total), err +} + +func (ar *AppRepo) InsertApp(ctx context.Context, info entity.App) error { + sqlInfo := tr.CovertAppToSql(&info) + sqlInfoV2 := tr.CovertAppToAppV2(sqlInfo) + err := DB.WithContext(ctx).Model(&sql.AppV2{}).Create(sqlInfoV2).Error + if err != nil { + return err + } + + return DB.WithContext(ctx).Model(&sql.AppStatusInfo{}).Create(&sqlInfo.StatusInfo).Error +} + +func (ar *AppRepo) GetAppInfo(ctx context.Context, appId string) (entity.App, error) { + info := sql.App{} + err := DB.WithContext(ctx). + //Joins("StatusInfo"). + Where("apps.app_id=?", appId). + First(&info).Error + if err != nil { + return entity.App{}, err + } + + statusInfo, _ := ar.GetAppStatusInfo(ctx, appId) + info.StatusInfo = statusInfo + return *tr.CovertAppToEntity(&info), nil +} + +func (ar *AppRepo) UpdateApp(ctx context.Context, info entity.App) error { + sqlInfo := tr.CovertAppToSql(&info) + + data := make(map[string]interface{}) + data["app_class"] = sqlInfo.AppClass + data["app_tag"] = sqlInfo.AppTag + data["app_type"] = sqlInfo.AppType + data["name"] = sqlInfo.Name + data["logo"] = sqlInfo.Logo + data["desc"] = sqlInfo.Desc + data["detail_desc"] = sqlInfo.DetailDesc + data["class"] = sqlInfo.Class + data["created_by"] = sqlInfo.CreatedBy + data["developer_id"] = sqlInfo.DeveloperId + data["group_id"] = sqlInfo.GroupId + data["is_rollback"] = sqlInfo.IsRollback + data["ext"] = sqlInfo.Ext + data["is_forbidden"] = sqlInfo.IsForbidden + data["privacy_setting_type"] = sqlInfo.PrivacySettingType + data["expire"] = sqlInfo.Expire + data["create_time"] = sqlInfo.CreateTime + data["update_time"] = sqlInfo.UpdateTime + + return DB.Model(&sql.App{}).Where("app_id=?", info.AppID).Updates(data).Error +} + +func (ar *AppRepo) GetAppStatusInfo(ctx context.Context, appId string) (sql.AppStatusInfo, error) { + tmpQuery := "app_id = ?" + tmpArgs := []interface{}{appId} + + var appStatusInfo sql.AppStatusInfo + err := DB.Model(&sql.AppStatusInfo{}).Where(tmpQuery, tmpArgs...).First(&appStatusInfo).Error + + return appStatusInfo, err +} + +func (ar *AppRepo) GetAppBuildInfoAndAppVersionStatusInfo(ctx context.Context, buildInfoId string, appId string, sequence int) (sql.AppBuildInfo, sql.AppVersionStatusInfo, error) { + tmpQuery := "trace_id = ? or build_info_id = ?" + tmpArgs := []interface{}{buildInfoId, buildInfoId} + + var appBuildInfo sql.AppBuildInfo + err := DB.Model(&sql.AppBuildInfo{}).Where(tmpQuery, tmpArgs...).First(&appBuildInfo).Error + + tmpQuery = "app_id = ? AND sequence = ?" + tmpArgs = []interface{}{appId, sequence} + + var appVersionStatusInfo sql.AppVersionStatusInfo + err = DB.Model(&sql.AppVersionStatusInfo{}).Where(tmpQuery, tmpArgs...).First(&appVersionStatusInfo).Error + + return appBuildInfo, appVersionStatusInfo, err +} + +func (ar *AppRepo) GetAppBuildInfoAndAppVersionStatusInfoV2(ctx context.Context, appId, appVer string, sequence int) (sql.AppBuildInfo, sql.AppVersionStatusInfo, error) { + tmpQuery := "app_id = ? and version = ? and buildStatus = ?" + tmpArgs := []interface{}{appId, appVer, "success"} + + var appBuildInfo sql.AppBuildInfo + var appVersionStatusInfo sql.AppVersionStatusInfo + var buildInfo sql.BuildInfo + err := DB.Model(&sql.BuildInfo{}).Where(tmpQuery, tmpArgs...). + Order("create_time DESC"). + First(&buildInfo).Error + if err != nil { + return appBuildInfo, appVersionStatusInfo, err + } + + tmpQuery = "app_id = ? AND sequence = ?" + tmpArgs = []interface{}{appId, sequence} + + err = DB.Model(&sql.AppVersionStatusInfo{}).Where(tmpQuery, tmpArgs...).First(&appVersionStatusInfo).Error + + appBuildInfo.AppId = appId + appBuildInfo.UserId = buildInfo.UserId + appBuildInfo.CreatedBy = buildInfo.Username + appBuildInfo.Status = true + appBuildInfo.Version = appVer + appBuildInfo.VersionDescription = buildInfo.VersionRemark + appBuildInfo.Name = "app.zip" + appBuildInfo.Url = buildInfo.FileUrl + appBuildInfo.EncryptedUrl = buildInfo.EncryptedUrl + appBuildInfo.Packages = buildInfo.Packages + appBuildInfo.EncryptPackages = buildInfo.EncryptPackage + appBuildInfo.CreateTime = buildInfo.CreateTime + appBuildInfo.UpdateTime = buildInfo.UpdateTime + + return appBuildInfo, appVersionStatusInfo, err +} + +func (ar *AppRepo) GetAppVerInfo(ctx context.Context, appId string, seq int) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + err := DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, seq). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Find(&sqlInfo).Error + + if sqlInfo.AppId == "" { + err = gorm.ErrRecordNotFound + } + + if sqlInfo.BuildInfoId != "" { + appBuildInfo, appVersionStatusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + sqlInfo.StatusInfo = appVersionStatusInfo + } else { + appBuildInfo, appVersionStatusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfoV2(ctx, sqlInfo.AppId, sqlInfo.Version, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + sqlInfo.StatusInfo = appVersionStatusInfo + } + + return *tr.CovertAppVerToEntity(&sqlInfo), err +} +func (ar *AppRepo) GetOnlineAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + /*err := DB.WithContext(ctx). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("StatusInfo.app_id=? AND StatusInfo.status_value=?", appId, entity.StPublished). + First(&sqlInfo).Error*/ + + statusInfo := sql.AppVersionStatusInfo{} + err := DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.status_value=?", appId, entity.StPublished). + First(&statusInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + err = DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, statusInfo.Sequence). + First(&sqlInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + sqlInfo.StatusInfo = statusInfo + + if sqlInfo.BuildInfoId != "" { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } else { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfoV2(ctx, sqlInfo.AppId, sqlInfo.Version, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } + + return *tr.CovertAppVerToEntity(&sqlInfo), err +} + +func (ar *AppRepo) GetLatestPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + /*err := DB.WithContext(ctx). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("StatusInfo.app_id=? AND StatusInfo.published_update_time<>0", appId). + Order("StatusInfo.published_update_time DESC"). + First(&sqlInfo).Error*/ + + statusInfo := sql.AppVersionStatusInfo{} + err := DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.published_update_time<>0", appId). + Order("app_version_status_infos.published_update_time DESC"). + First(&statusInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + err = DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, statusInfo.Sequence). + First(&sqlInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + sqlInfo.StatusInfo = statusInfo + + if sqlInfo.BuildInfoId != "" { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } else { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfoV2(ctx, sqlInfo.AppId, sqlInfo.Version, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } + + return *tr.CovertAppVerToEntity(&sqlInfo), err +} + +func (ar *AppRepo) UpdateAppVerAppName(ctx context.Context, appId, appName string) error { + data := make(map[string]interface{}) + data["name"] = appName + return DB.Model(&sql.AppVersionV2{}).Where("app_id=?", appId).Updates(data).Error +} + +func (ar *AppRepo) GetNowPubAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + /*err := DB.WithContext(ctx). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("StatusInfo.app_id=? AND StatusInfo.status_value=?", appId, entity.StPublished). + Order("sequence DESC"). + First(&sqlInfo).Error*/ + + statusInfo := sql.AppVersionStatusInfo{} + err := DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.status_value=?", appId, entity.StPublished). + Order("app_version_status_infos.sequence DESC"). + First(&statusInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + err = DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, statusInfo.Sequence). + First(&sqlInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + sqlInfo.StatusInfo = statusInfo + + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + + return *tr.CovertAppVerToEntity(&sqlInfo), err +} + +func (ar *AppRepo) GetLatestReviewAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + /*err := DB.WithContext(ctx). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("app_versions.app_id=? AND StatusInfo.publishing_update_time <> 0", appId). + Order("app_versions.sequence DESC"). + First(&sqlInfo).Error*/ + + statusInfo := sql.AppVersionStatusInfo{} + err := DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.publishing_update_time <> 0", appId). + Order("app_version_status_infos.publishing_update_time DESC"). + First(&statusInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + err = DB.WithContext(ctx). + Where("app_versions.app_id=?", appId). + Order("app_versions.sequence DESC"). + First(&sqlInfo).Error + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + sqlInfo.StatusInfo = statusInfo + + if sqlInfo.BuildInfoId != "" { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } else { + appBuildInfo, _, _ := ar.GetAppBuildInfoAndAppVersionStatusInfoV2(ctx, sqlInfo.AppId, sqlInfo.Version, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + } + + return *tr.CovertAppVerToEntity(&sqlInfo), err +} + +func (ar *AppRepo) GetAllPermitGrayPubVers(ctx context.Context, appId string, maxSeq int) ([]entity.AppVersion, error) { + statusList := make([]sql.AppVersionStatusInfo, 0) + /*err := DB.WithContext(ctx). + Joins("StatusInfo"). + Where("StatusInfo.app_id=? AND StatusInfo.status_value=? AND StatusInfo.sequence>?", appId, entity.StPublishApproved, maxSeq). + Find(&list).Error*/ + err := DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.status_value=? AND app_version_status_infos.sequence>?", appId, entity.StPublishApproved, maxSeq). + Find(&statusList).Error + if err != nil { + return nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range statusList { + sqlInfo := sql.AppVersion{} + err = DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, v.Sequence). + First(&sqlInfo).Error + if err == nil { + result = append(result, *tr.CovertAppVerToEntity(&sqlInfo)) + } + } + + return result, nil +} + +func (ar *AppRepo) GetMaxSeqAppVer(ctx context.Context, appId string) (entity.AppVersion, error) { + sqlInfo := sql.AppVersion{} + err := DB.WithContext(ctx). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Where("app_versions.app_id=?", appId). + Order("sequence DESC"). + First(&sqlInfo).Error + + if err != nil { + return *tr.CovertAppVerToEntity(&sqlInfo), err + } + + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + sqlInfo.StatusInfo = statusInfo + return *tr.CovertAppVerToEntity(&sqlInfo), err +} + +func (ar *AppRepo) SubmitApp(ctx context.Context, req entity.SubmitAppReq, expire int64, userId string) error { + nowMaxSeq := 0 + maxAppVerInfo, err := ar.GetMaxSeqAppVer(ctx, req.AppId) + if err == nil { + nowMaxSeq = maxAppVerInfo.Sequence + } else { + if !DbNotFound(err) { + return err + } + } + buildInfo, err := NewAppBuildInfoMysqlRepo().GetInfoById(ctx, req.BuildId) + if DbNotFound(err) { + buildInfo, err = NewAppBuildInfoMysqlRepo().GetInfoByBuildId(ctx, req.BuildId) + if err != nil { + return err + } + } + + appInfo, err := ar.GetAppInfo(ctx, req.AppId) + if err != nil { + return err + } + now := utils.GetNowMs() + appVerInfo := sql.AppVersion{ + AppId: appInfo.AppID, + Sequence: nowMaxSeq + 1, + Name: appInfo.Name, + Logo: appInfo.Logo, + Version: buildInfo.Version, + Desc: appInfo.CoreDescription, + DetailDesc: appInfo.CustomData.DetailDescription, + Class: appInfo.AppClass, + Tag: strings.Join(appInfo.AppTag, ","), + AppType: appInfo.AppType, + DeveloperId: userId, + GroupId: appInfo.GroupID, + AutoPub: req.NeedAutoPub, + InGrayRelease: false, + BuildInfoId: req.BuildId, + StatusInfo: sql.AppVersionStatusInfo{ + AppId: appInfo.AppID, + Sequence: nowMaxSeq + 1, + StatusValue: entity.StPublishing, + StatusReason: "", + StatusUpdateTime: now, + StatusUpdater: req.Account, + PublishingReason: "", + PublishingUpdateTime: now, + PublishingUpdater: req.Account, + PublishedReason: "", + PublishedUpdateTime: 0, + PublishedUpdater: "", + UnpublishedReason: "", + UnpublishedUpdateTime: 0, + UnpublishedUpdater: "", + UnpublishedType: "", + ApprovalReason: "", + ApprovalUpdateTime: 0, + ApprovalUpdater: "", + ActionReason: "", + ActionUpdater: req.Account, + ActionUpdateTime: now, + PublishingApprovalReason: "", + PublishingApprovalUpdateTime: 0, + PublishingApprovalUpdater: "", + CreateTime: now, + }, + CreatedBy: req.Account, + IsRollback: false, + ExpireTime: expire, + CreateTime: now, + TestInfo: "", + } + testInfoByte, _ := json.Marshal(req.TestInfo) + appVerInfo.TestInfo = string(testInfoByte) + appVerInfoV2 := tr.CovertAppVerToAppVerV2(&appVerInfo) + err = DB.WithContext(ctx).Model(&sql.AppVersionV2{}).Create(appVerInfoV2).Error + if err != nil { + return err + } + + return DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}).Create(&appVerInfo.StatusInfo).Error +} + +func (ar *AppRepo) WithdrawPubApp(ctx context.Context, appId string, seq int, account string) error { + now := utils.GetNowMs() + params := map[string]interface{}{ + "status_value": entity.StPublishWithdrawed, + "status_update_time": now, + "status_updater": account, + } + return DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}).Where("app_id=? AND sequence=?", appId, seq).Updates(params).Error +} + +/* +//结束所有低版本的灰度 + err := appVerTable.UpdateAll(ctx, bson.M{"appId": appId, "sequence": bson.M{"$lte": seq}}, bson.M{"$set": bson.M{"inGrayRelease": false}}) + if err != nil { + return err + } + now := time.Now().UnixNano() / 1e6 + //下架之前上架的小程序版本 + oldAppVer, err := ar.GetNowPubAppVer(ctx, appId) + if err != nil && !NotFound(err) { + return err + } + if !NotFound(err) { + unpublishedStatus := mongo.UnpublishedStatus{ + LastUpdated: now, + ModifiedBy: account, + Type: entity.TypeUnpublishedDueToNewSeq, // Mark the type. + } + //if !isDev { + // unpublishedStatus.Type = entity.TypeUnpublishedByAdmin + //} + unPubUpInfo := map[string]interface{}{ + "unpublishedStatus": unpublishedStatus, + "status": mongo.Status{ + Value: entity.StUnpublished, + LastUpdated: now, + ModifiedBy: account, + }, + } + err = appVerTable.UpdateOne(ctx, bson.M{"appId": oldAppVer.AppID, "sequence": oldAppVer.Sequence}, bson.M{"$set": unPubUpInfo}) + if err != nil { + return err + } + } + //上架当前小程序版本 + upInfo := make(map[string]interface{}) + upInfo["status"] = mongo.Status{ + Value: entity.StPublished, + Reason: "", + LastUpdated: now, + ModifiedBy: account, + } + upInfo["publishedStatus"] = mongo.SpecificStatus{ + Reason: "", + LastUpdated: now, + ModifiedBy: account, + } + upInfo["actionStatus"] = mongo.SpecificStatus{ + LastUpdated: now, + ModifiedBy: account, + } + //修改小程序元数据信息 + err = appTable.UpdateOne(ctx, bson.M{"appId": appId}, bson.M{"$set": upInfo}) + if err != nil { + return err + } + upInfo["isRollback"] = isRollback + err = appVerTable.UpdateOne(ctx, bson.M{"appId": appId, "sequence": seq}, bson.M{"$set": upInfo}) + if err != nil { + return err + } + return nil +*/ +func (ar *AppRepo) PubApp(ctx context.Context, appId string, seq int, account string, isDev, isRollback bool) error { + now := utils.GetNowMs() + oldAppVer, oldPubAppErr := ar.GetNowPubAppVer(ctx, appId) + if oldPubAppErr != nil && !DbNotFound(oldPubAppErr) { + return oldPubAppErr + } + return DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + var err error + //下架之前上架的小程序版本 + if !DbNotFound(oldPubAppErr) { + updateInfos := map[string]interface{}{ + "unpublished_update_time": now, + "unpublished_updater": account, + "unpublished_type": entity.TypeUnpublishedDueToNewSeq, + "status_value": entity.StUnpublished, + "status_update_time": now, + "status_updater": account, + } + //if !isDev { + // updateInfos["unpublished_type"] = entity.TypeUnpublishedByAdmin + //} + err = tx.WithContext(ctx). + Model(&sql.AppVersionStatusInfo{}). + Where("app_id=? AND sequence=?", oldAppVer.AppID, oldAppVer.Sequence). + Updates(updateInfos).Error + if err != nil { + return err + } + } + //结束所有低版本的灰度 + err = tx.WithContext(ctx). + Model(&sql.AppVersion{}). + Where("app_id=? AND sequence<=?", appId, seq). + Update("in_gray_release", false).Error + if err != nil { + return err + } + //上架当前小程序版本 + upInfo := map[string]interface{}{ + "status_value": entity.StPublished, + "status_update_time": now, + "status_updater": account, + "published_reason": "", + "published_update_time": now, + "published_updater": account, + "action_update_time": now, + "action_updater": account, + } + err = tx.WithContext(ctx). + Model(&sql.AppStatusInfo{}). + Where("app_id=?", appId). + Updates(upInfo).Error + if err != nil { + return err + } + err = tx.WithContext(ctx). + Model(&sql.AppVersionStatusInfo{}). + Where("app_id=? AND sequence=?", appId, seq). + Updates(upInfo).Error + if err != nil { + return err + } + if isRollback { + err = tx.WithContext(ctx). + Model(&sql.AppVersionV2{}). + Where("app_id=? AND sequence=?", appId, seq). + Update("is_rollback", isRollback).Error + if err != nil { + return err + } + } + return nil + }) +} + +func (ar *AppRepo) ListApps(ctx context.Context, groupId string, pageNo, pageSize int, searchText string, sortType, pullType string) (int, []entity.App, error) { + var ( + list []sql.App + sort string + query string + total int64 + queryList []interface{} + err error + ) + switch sortType { + case "created": + sort = "apps.create_time" + case "-created": + sort = "apps.create_time DESC" + case "updated": + sort = "app_status_infos.status_update_time" + case "-updated": + sort = "app_status_infos.status_update_time DESC" + default: + sort = "app_status_infos.status_update_time DESC" + } + if groupId != "" { + query = genQuery(query, "AND", "apps.group_id=? ") + queryList = append(queryList, groupId) + } + switch pullType { + case "published": + //已上架 + query = genQuery(query, "AND", "app_status_infos.status_value=? ") + queryList = append(queryList, entity.StPublished) + case "inDevelopment": + //未上架 + query = genQuery(query, "AND", "app_status_infos.status_value=? ") + queryList = append(queryList, entity.StInDevelopment) + case "unPublished": + //已下架 + query = genQuery(query, "AND", "app_status_infos.status_value=? ") + queryList = append(queryList, entity.StUnpublished) + } + + if searchText != "" { + s := "%" + searchText + "%" + query = genQuery(query, "AND", "( apps.app_id LIKE ? OR apps.name LIKE ? )") + queryList = append(queryList, s, s) + } + if query != "" { + err = DB.WithContext(ctx).Debug().Model(&sql.App{}). + //Joins("StatusInfo"). + Joins("left join app_status_infos on apps.app_id = app_status_infos.app_id"). + Where(query, queryList...). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + if sortType == "updated" || sortType == "-updated" { + err = DB.WithContext(ctx).Debug().Model(&sql.App{}). + Joins("left join app_status_infos on apps.app_id = app_status_infos.app_id"). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + err = DB.WithContext(ctx).Debug().Model(&sql.App{}). + //Joins("StatusInfo"). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } + + } + if err != nil { + return 0, nil, err + } + if query != "" { + err = DB.WithContext(ctx).Model(&sql.App{}). + Joins("left join app_status_infos on apps.app_id = app_status_infos.app_id"). + Where(query, queryList...). + Count(&total).Error + } else { + err = DB.WithContext(ctx).Model(&sql.App{}). + Count(&total).Error + } + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return int(total), result, err +} + +func (ar *AppRepo) ListAppVers(ctx context.Context, pageNo, pageSize int, searchText string, t string, groupId string) (int, []entity.AppVersion, error) { + var ( + list []sql.AppVersion + sort string + query string + total int64 + queryList []interface{} + err error + ) + sort = "app_version_status_infos.publishing_update_time DESC" + switch t { + case "pendingReview": //待审核 + query += "app_version_status_infos.status_value IN (?) " + queryList = append(queryList, []string{entity.StPublishing, entity.StUnpublishing}) + case "reviewed": //已审核 + query += "app_version_status_infos.status_value NOT IN (?) " + queryList = append(queryList, []string{entity.StPublishing, entity.StPublishWithdrawed}) + case "revoked": //已撤销 + query += "app_version_status_infos.status_value IN (?)" + queryList = append(queryList, []string{entity.StPublishWithdrawed}) + } + if searchText != "" { + query = genQuery(query, "AND", "(app_versions.name LIKE ? OR app_versions.app_id LIKE ? )") + //query += "(app_versions.name LIKE ? OR app_versions.app_id LIKE ?)" + queryList = append(queryList, "%"+searchText+"%", "%"+searchText+"%") + } + if groupId != "" { + query = genQuery(query, "AND", "app_versions.group_id = ?") + queryList = append(queryList, groupId) + } + + if query != "" { + err = DB.Debug().Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where(query, queryList...). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + err = DB.Debug().Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } + /*if query != "" { + err = DB.WithContext(ctx). + Model(&sql.AppVersion{}). + Order(sort). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where(query, queryList...). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + err = DB.WithContext(ctx). + Model(&sql.AppVersion{}). + Order(sort). + Joins("StatusInfo"). + Joins("BuildInfo"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + }*/ + if err != nil { + return 0, nil, err + } + if query != "" { + err = DB.WithContext(ctx). + Model(&sql.AppVersion{}). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where(query, queryList...). + Count(&total).Error + } else { + err = DB.WithContext(ctx). + Model(&sql.AppVersion{}). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Count(&total).Error + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, v.BuildInfoId, v.AppId, v.Sequence) + v.BuildInfo = appBuildInfo + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return int(total), result, err +} + +func (ar *AppRepo) UnpubApp(ctx context.Context, appId string, seq int, account, reason string, isDev bool) error { + var err error + unpublishedType := "" + if isDev { + unpublishedType = entity.TypeUnpublishedByDev + } else { + unpublishedType = entity.TypeUnpublishedByAdmin + } + now := time.Now().UnixNano() / 1e6 + params := map[string]interface{}{ + "status_value": entity.StUnpublished, + "status_updater": account, + "status_update_time": now, + "status_reason": reason, + "unpublished_updater": account, + "unpublished_update_time": now, + "unpublished_reason": reason, + "action_updater": account, + "action_update_time": now, + "action_reason": reason, + } + return DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + //更新app + err = tx.Model(&sql.AppStatusInfo{}). + Where("app_id=?", appId). + Updates(params).Error + if err != nil { + return err + } + //更新app_version + params["unpublished_type"] = unpublishedType + err = tx.Model(&sql.AppVersionStatusInfo{}). + Where("app_id=? AND sequence=?", appId, seq).Updates(params).Error + if err != nil { + return err + } + return nil + }) +} + +func (ar *AppRepo) ListAppVersByAppId(ctx context.Context, appId string, pageNo, pageSize int) (int, []entity.AppVersion, error) { + var ( + list = make([]sql.AppVersion, 0) + total int64 + err error + ) + err = DB.WithContext(ctx). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Where("app_versions.app_id=?", appId). + Order("sequence DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Where("app_id=?", appId). + Count(&total).Error + if err != nil { + return 0, nil, err + } + + result := make([]entity.AppVersion, 0) + for _, v := range list { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, v.BuildInfoId, v.AppId, v.Sequence) + v.BuildInfo = appBuildInfo + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return int(total), result, err +} + +func (ar *AppRepo) GetAppReviews(ctx context.Context, req apiproto.AdminGetAppReviewsReq) (int, []entity.AppVersion, error) { + return 0, nil, nil +} + +func (ar *AppRepo) GetAllPublishedVerList(ctx context.Context, appId string) ([]entity.AppVersion, int, error) { + var ( + //list = make([]sql.AppVersion, 0) + statusList = make([]sql.AppVersionStatusInfo, 0) + total int64 + err error + ) + /*err = DB.WithContext(ctx). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("app_versions.app_id=? AND StatusInfo.status_value=?", appId, entity.StPublished). + Order("sequence DESC"). + Find(&list).Error*/ + err = DB.WithContext(ctx). + Where("app_version_status_infos.app_id=? AND app_version_status_infos.status_value=?", appId, entity.StPublished). + Order("sequence DESC"). + Find(&statusList).Error + if err != nil { + return nil, 0, err + } + + result := make([]entity.AppVersion, 0) + for _, v := range statusList { + sqlInfo := sql.AppVersion{} + err = DB.WithContext(ctx). + Where("app_versions.app_id=? AND app_versions.sequence=?", appId, v.Sequence). + First(&sqlInfo).Error + if err == nil { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, sqlInfo.BuildInfoId, sqlInfo.AppId, sqlInfo.Sequence) + sqlInfo.BuildInfo = appBuildInfo + sqlInfo.StatusInfo = statusInfo + result = append(result, *tr.CovertAppVerToEntity(&sqlInfo)) + } + } + return result, int(total), err + +} + +func (ar *AppRepo) GetPublishedAppList(ctx context.Context, pageNo, pageSize int, searchText string) ([]entity.AppVersion, int, error) { + var ( + err error + total int64 + list = make([]sql.AppVersion, 0) + ) + if searchText != "" { + s := genLike(searchText) + /*err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("StatusInfo.status_value=? AND app_versions.name LIKE ? OR app_versions.app_id LIKE ?", entity.StPublished, s, s). + Find(&list).Error*/ + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where("app_version_status_infos.status_value=? AND (app_versions.name LIKE ? OR app_versions.app_id LIKE ?)", entity.StPublished, s, s). + Order("app_versions.create_time desc"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + /*err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("StatusInfo"). + Joins("BuildInfo"). + Where("StatusInfo.status_value=?", entity.StPublished). + Find(&list).Error*/ + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where("app_version_status_infos.status_value=?", entity.StPublished). + Order("app_versions.create_time desc"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } + if err != nil { + return nil, 0, err + } + if searchText != "" { + s := genLike(searchText) + /*err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("StatusInfo"). + Where("StatusInfo.status_value=? AND app_versions.name LIKE ? OR app_versions.app_id LIKE ?", entity.StPublished, s, s). + Count(&total).Error*/ + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where("app_version_status_infos.status_value=? AND app_versions.name LIKE ? OR app_versions.app_id LIKE ?", entity.StPublished, s, s). + Count(&total).Error + } else { + /*err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("StatusInfo"). + Where("StatusInfo.status_value=?", entity.StPublished). + Count(&total).Error*/ + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where("app_version_status_infos.status_value=?", entity.StPublished). + Count(&total).Error + } + if err != nil { + return nil, 0, err + } + + result := make([]entity.AppVersion, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, int(total), nil +} + +func (ar *AppRepo) GetAllVers(ctx context.Context, appId string) ([]entity.AppVersion, int, error) { + var ( + list = make([]sql.AppVersion, 0) + total int64 + err error + ) + err = DB.WithContext(ctx). + //Joins("StatusInfo"). + //Joins("BuildInfo"). + Where("app_versions.app_id=?", appId). + Order("app_versions.sequence DESC"). + Find(&list).Error + if err != nil { + return nil, 0, err + } + + result := make([]entity.AppVersion, 0) + for _, v := range list { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, v.BuildInfoId, v.AppId, v.Sequence) + v.BuildInfo = appBuildInfo + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, int(total), err +} + +func (ar *AppRepo) GetAppsByAppIds(ctx context.Context, appIds []string) ([]entity.App, error) { + list := make([]sql.App, 0) + err := DB.WithContext(ctx). + Model(&sql.App{}). + Where("apps.app_id IN (?)", appIds). + //Joins("StatusInfo"). + Order("apps.create_time DESC"). + Find(&list).Error + if err != nil { + return nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetAppsByGroupIds(ctx context.Context, groupIds []string) (int, []entity.App, error) { + list := make([]sql.App, 0) + var total int64 + err := DB.WithContext(ctx).Model(&sql.App{}). + Where("group_id IN (?)", groupIds). + Count(&total). + Order("create_time DESC"). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return int(total), result, nil +} + +func (ar *AppRepo) GetAppsToBinding(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) { + br := NewBindingByMysqlRepo() + bindingInfo, err := br.GetBindingByBindingId(ctx, bindingId) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfo.AppInfos { + assAppIdList = append(assAppIdList, v.AppID) + } + query := "apps.group_id=? " + queryList := []interface{}{bindingInfo.GroupID} + if len(assAppIdList) != 0 { + query = genQuery(query, "AND", "apps.app_id NOT IN (?) ") + queryList = append(queryList, assAppIdList) + } + if searchText != "" { + query = genQuery(query, "AND", "apps.name LIKE ?") + queryList = append(queryList, "%"+searchText+"%") + } + list := make([]sql.App, 0) + var total int64 + err = DB.WithContext(ctx). + Model(&sql.App{}). + Where(query, queryList...). + Count(&total). + Find(&list).Error + if err != nil { + return 0, nil, err + } + err = DB.WithContext(ctx). + Model(&sql.App{}). + //Joins("StatusInfo"). + Where(query, queryList...). + Order("apps.create_time DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return int(total), result, nil +} + +func (ar *AppRepo) GetLinkAppsByBindingId(ctx context.Context, bindingId string, pageNo, pageSize int, searchText string) (int, []entity.App, error) { + br := NewBindingByMysqlRepo() + bindingInfo, err := br.GetBindingByBindingId(ctx, bindingId) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfo.AppInfos { + assAppIdList = append(assAppIdList, v.AppID) + } + list := make([]sql.App, 0) + var total int64 + err = DB.WithContext(ctx).Model(&sql.App{}). + Where("group_id=? AND app_id IN (?)", bindingInfo.GroupID, assAppIdList). + Count(&total). + Order("create_time DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return int(total), result, nil +} + +func (ar *AppRepo) GetLinkAppsBySDKKey(ctx context.Context, sdkKey string, pageNo, pageSize int) (int, []entity.App, error) { + br := NewBindingByMysqlRepo() + //bindingInfo, err := br.GetBindingByBindingId(ctx, bindingId) + bindingInfos, err := br.GetBindListBySdkKey(ctx, sdkKey) + if err != nil { + return 0, nil, err + } + //获取应用关联的小程序Id + assAppIdList := make([]string, 0) + for _, v := range bindingInfos { + for _, y := range v.AppInfos { + assAppIdList = append(assAppIdList, y.AppID) + } + } + list := make([]sql.App, 0) + var total int64 + err = DB.WithContext(ctx).Model(&sql.App{}). + Joins("left join app_status_infos on apps.app_id = app_status_infos.app_id"). + Where("app_status_infos.status_value=? and apps.app_id IN (?)", entity.StPublished, assAppIdList). + Count(&total). + Order("create_time DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return int(total), result, nil +} + +func (ar *AppRepo) AdminGetLinkApps(ctx context.Context, pageNo, pageSize int, searchText string) (int, []entity.AdminGetLinkAppsRspItem, error) { + type temp struct { + AppId string `gorm:"column:app_id"` + AppName string `gorm:"column:app_name"` + AssTime int64 `gorm:"column:ass_time"` + BindingId string `gorm:"column:binding_id"` + GroupName string `gorm:"column:group_name"` + BindingName string `gorm:"column:binding_name"` + } + var ( + err error + list = make([]temp, 0) + total int64 + ) + // 和mongo保持一致,mongo 0 代表的第一页,客户端的pageNo也是从0开始的 + pageNo = pageNo + 1 + if searchText != "" { + s := genLike(searchText) + err = DB.WithContext(ctx). + Table("link_app_infos l"). + Joins("JOIN apps a ON l.app_id=a.app_id"). + Joins("JOIN binding b ON l.binding_id=b.binding_id"). + Joins("JOIN app_status_infos c ON l.app_id=c.app_id"). + Where("c.status_value =? and (a.name LIKE ? OR b.name LIKE ? OR b.group_name LIKE ? )", entity.StPublished, s, s, s). + Select("l.app_id AS app_id,a.name AS app_name,l.associated_at AS ass_time," + + "l.binding_id AS binding_id,b.group_name AS group_name,b.name AS binding_name"). + Order("l.associated_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } else { + err = DB.WithContext(ctx). + Table("link_app_infos l"). + Joins("JOIN apps a ON l.app_id=a.app_id"). + Joins("JOIN binding b ON l.binding_id=b.binding_id"). + Joins("JOIN app_status_infos c ON l.app_id=c.app_id"). + Where("c.status_value =? ", entity.StPublished). + Select("l.app_id AS app_id,a.name AS app_name,l.associated_at AS ass_time," + + "l.binding_id AS binding_id,b.group_name AS group_name,b.name AS binding_name"). + Order("l.associated_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + } + if err != nil { + return 0, nil, err + } + if searchText != "" { + s := genLike(searchText) + err = DB.WithContext(ctx). + Table("link_app_infos l"). + Joins("JOIN apps a ON l.app_id=a.app_id"). + Joins("JOIN binding b ON l.binding_id=b.binding_id"). + Joins("JOIN app_status_infos c ON l.app_id=c.app_id"). + Where("c.status_value =? and (a.name LIKE ? OR b.name LIKE ? OR b.group_name LIKE ? )", entity.StPublished, s, s, s). + Count(&total).Error + } else { + err = DB.WithContext(ctx). + Table("link_app_infos l"). + Joins("JOIN app_status_infos c ON l.app_id=c.app_id"). + Where("c.status_value =? ", entity.StPublished). + Count(&total).Error + } + if err != nil { + return 0, nil, err + } + result := make([]entity.AdminGetLinkAppsRspItem, 0) + for _, v := range list { + item := entity.AdminGetLinkAppsRspItem{} + item.Id = v.BindingId + item.AppIdDetail.AppId = v.AppId + item.AppIdDetail.Name = v.AppName + item.AppIdDetail.Sequence = 0 + item.AppInfos.AssociatedAt = v.AssTime + item.BindingId = v.BindingId + item.GroupName = v.GroupName + item.Name = v.BindingName + result = append(result, item) + } + return int(total), result, nil +} + +func (ar *AppRepo) ApproveApp(ctx context.Context, appId string, seq int, account, reason string, isPass bool) error { + now := utils.GetNowMs() + params := map[string]interface{}{ + "status_update_time": now, + "status_updater": account, + "status_reason": reason, + "publishing_approval_update_time": now, + "publishing_approval_updater": account, + "publishing_approval_reason": reason, + "approval_update_time": now, + "approval_updater": account, + "approval_reason": reason, + } + if isPass { + params["status_value"] = entity.StPublishApproved + } else { + params["status_value"] = entity.StPublishRejected + } + + return DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}). + Where("app_id=? AND sequence=?", appId, seq). + Updates(params).Error +} + +func (ar *AppRepo) GetRollbackAbleList(ctx context.Context, groupId, appId string, latestPubSeq int) ([]entity.AppVersion, error) { + appVers := make([]sql.AppVersion, 0) + limitVersion := 5 // 最近5个版本, 不是最近下架的5个版本 + /*query := "app_versions.app_id=? AND app_versions.group_id=? AND " + + "StatusInfo.app_id=? AND StatusInfo.status_value=? AND " + + "StatusInfo.sequence>=? AND StatusInfo.sequence=? AND app_version_status_infos.sequence 0 { + query = genQuery(query, "AND", "create_time>? ") + queryList = append(queryList, startTime) + } + if endTime > 0 { + query = genQuery(query, "AND", "create_time<=? ") + queryList = append(queryList, endTime) + } + switch isForbidden { + case entity.APP_FORBIDDEN_NOT_STATUS, entity.APP_FORBIDDEN_IS_STATUS: + query = genQuery(query, "AND", "is_forbidden=? ") + queryList = append(queryList, isForbidden) + } + if query != "" { + err = DB.WithContext(ctx). + Model(&sql.App{}). + Where(query, queryList...). + Count(&total).Error + } else { + err = DB.WithContext(ctx). + Model(&sql.App{}). + Count(&total).Error + } + return int(total), err +} + +func (ar *AppRepo) GetPublishedStatistics(ctx context.Context, startTime, endTime int64, groupId string) (int, error) { + var ( + query = "" + queryList = make([]interface{}, 0) + err error + total int64 + ) + query += "status_value=? " + queryList = append(queryList, entity.StPublished) + + if groupId != "" { + query += "group_id = ? " + queryList = append(queryList, groupId) + } + if startTime > 0 { + query = genQuery(query, "AND", "published_update_time>? ") + queryList = append(queryList, startTime) + } + if endTime > 0 { + query = genQuery(query, "AND", "published_update_time<=? ") + queryList = append(queryList, endTime) + } + if query != "" { + err = DB.WithContext(ctx).Model(&sql.AppStatusInfo{}). + Where(query, queryList...). + Count(&total).Error + } else { + err = DB.WithContext(ctx).Model(&sql.AppStatusInfo{}).Count(&total).Error + } + return int(total), err +} + +//GetSubmittedStatistics 累计审核的小程序----只要小程序被审核过都算 +func (ar *AppRepo) GetSubmittedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) { + var ( + query = "" + queryList = make([]interface{}, 0) + err error + total int64 + ) + query += "status_value<>? " + queryList = append(queryList, entity.StInDevelopment) + + if groupId != "" { + query += "AND group_id = ? " + queryList = append(queryList, groupId) + } + if startTime > 0 { + query = genQuery(query, "AND", "publishing_update_time>? ") + queryList = append(queryList, startTime) + } + if endTime > 0 { + query = genQuery(query, "AND", "publishing_update_time<=? ") + queryList = append(queryList, endTime) + } + if distinct { + if query != "" { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}). + Where(query, queryList...). + Select("count(distinct app_id)"). + Count(&total).Error + } else { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}). + Select("count(distinct app_id)"). + Count(&total).Error + } + } else { + if query != "" { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}). + Where(query, queryList...). + Count(&total).Error + } else { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}). + Count(&total).Error + } + } + return int(total), err +} + +//审核通过小程序 +func (ar *AppRepo) GetApprovedStatistics(ctx context.Context, startTime, endTime int64, groupId string, distinct bool) (int, error) { + var ( + query = "" + queryList = make([]interface{}, 0) + err error + total int64 + ) + query += "status_value IN (?) " + queryList = append(queryList, []string{entity.StPublishApproved, entity.StPublished, entity.StUnpublishing, entity.StUnpublishApproved, entity.StUnpublishRejected, entity.StUnpublished}) + + if groupId != "" { + query += "AND group_id = ? " + queryList = append(queryList, groupId) + } + if startTime > 0 { + query = genQuery(query, "AND", "published_update_time>? ") + queryList = append(queryList, startTime) + } + if endTime > 0 { + query = genQuery(query, "AND", "published_update_time<=? ") + queryList = append(queryList, endTime) + } + if distinct { + if query != "" { + err = DB.WithContext(ctx).Debug(). + Model(&sql.AppVersionStatusInfo{}). + Where(query, queryList...). + Select("COUNT(DISTINCT app_id)"). + Count(&total).Error + } else { + err = DB.WithContext(ctx).Debug(). + Model(&sql.AppVersionStatusInfo{}). + Select("COUNT(DISTINCT app_id)"). + Count(&total).Error + } + } else { + if query != "" { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}).Where(query, queryList...).Count(&total).Error + } else { + err = DB.WithContext(ctx).Model(&sql.AppVersionStatusInfo{}).Count(&total).Error + } + } + return int(total), err +} + +func (ar *AppRepo) GetAppClassPer(ctx context.Context, status string) ([]entity.AppClassPerRsp, error) { + //先获取所有的class + _, typeConfigList, err := NewTypeConfigByMysqlRepo().GetAll(ctx) + if err != nil { + return nil, err + } + type TempRsp struct { + AppClass string `gorm:"column:app_class"` + Count int `gorm:"column:count"` + } + rspList := make([]TempRsp, 0) + if status == "published" { + err = DB.WithContext(ctx).Model(&sql.App{}). + Joins("StatusInfo"). + Where("StatusInfo.status_value = ?", entity.StPublished). + Select("apps.app_class as app_class ,count(apps.class) as count"). + Group("app_class").Find(&rspList).Error + if err != nil { + return nil, err + } + } else { + err = DB.WithContext(ctx).Model(&sql.App{}). + Select("app_class,count(*) as count"). + Group("app_class").Find(&rspList).Error + if err != nil { + return nil, err + } + } + typeConfigListMap := make(map[string]string) + for _, v := range typeConfigList { + typeConfigListMap[v.Value] = v.CustomData.Chinese + } + result := make([]entity.AppClassPerRsp, 0) + for _, v := range rspList { + item := entity.AppClassPerRsp{ + Class: v.AppClass, + Count: v.Count, + } + if name, ok := typeConfigListMap[v.AppClass]; ok { + item.Name = []string{name} + } + result = append(result, item) + } + return result, err +} + +func (ar *AppRepo) GetAppVerLimitByIdentity(ctx context.Context, t, appId, identity string, limit int) ([]entity.AppVersion, error) { + var ( + list = make([]sql.AppVersion, 0) + query = "" + err error + ) + query = "app_build_infos.file_md5=?" + if t == "sha256" { + query = "app_build_infos.encrypted_file_sha256=?" + } + err = DB.WithContext(ctx). + //Joins("BuildInfo"). + //Joins("StatusInfo"). + Joins("left join app_build_infos on app_versions.build_info_id = app_build_infos.trace_id"). + Where(query, identity). + Order("sequence DESC"). + Limit(limit).Find(&list).Error + if err != nil { + return nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, v.BuildInfoId, v.AppId, v.Sequence) + v.BuildInfo = appBuildInfo + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetGrayStatisticsVerList(ctx context.Context, appId string, seq int, begin, end int64) (int, []entity.AppVersion, error) { + var ( + list = make([]sql.AppVersion, 0) + total int64 + query = "" + queryList = make([]interface{}, 0) + err error + ) + query = "app_versions.app_id=? AND app_versions.sequence<=? " + queryList = append(queryList, appId, seq) + if end == 0 { + query += "AND (app_version_status_infos.status_value=? OR (app_version_status_infos.status_value=? AND app_version_status_infos.unpublished_update_time >=?) ) " + queryList = append(queryList, entity.StPublished, entity.StUnpublished, begin) + } else { + query += "AND ( (app_version_status_infos.status_value=? AND app_version_status_infos.published_update_time<=?) OR " + + "(app_version_status_infos.status_value=? AND ((app_version_status_infos.published_update_time >=? AND app_version_status_infos.published_update_time<=?) " + + "OR (app_version_status_infos.unpublished_update_time>=? AND app_version_status_infos.unpublished_update_time<=?)))) " + queryList = append(queryList, entity.StPublished, end, entity.StUnpublished, begin, end, begin, end) + } + err = DB.WithContext(ctx).Model(&sql.AppVersion{}).Debug(). + //Joins("BuildInfo"). + //Joins("StatusInfo"). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where(query, queryList...). + Order("app_versions.sequence ASC"). + Find(&list).Error + if err != nil { + return 0, nil, err + } + err = DB.WithContext(ctx).Model(&sql.AppVersion{}). + //Joins("BuildInfo"). + //Joins("StatusInfo"). + Joins("left join app_version_status_infos on concat(app_versions.app_id,app_versions.sequence)=concat(app_version_status_infos.app_id,app_version_status_infos.sequence)"). + Where(query, queryList...). + Count(&total).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.AppVersion, 0) + for _, v := range list { + appBuildInfo, statusInfo, _ := ar.GetAppBuildInfoAndAppVersionStatusInfo(ctx, v.BuildInfoId, v.AppId, v.Sequence) + v.BuildInfo = appBuildInfo + v.StatusInfo = statusInfo + temp := v + result = append(result, *tr.CovertAppVerToEntity(&temp)) + } + return int(total), result, nil +} + +func (ar *AppRepo) GetAppClassList(ctx context.Context) ([]entity.CItem, error) { + apps := make([]sql.App, 0) + err := DB.Model(&sql.App{}). + Select("apps.app_class").Group("apps.app_class"). + Find(&apps).Error + if err != nil { + return make([]entity.CItem, 0), err + } + + cItems := make([]entity.CItem, 0) + for _, v := range apps { + cItem := entity.CItem{ + Id: v.AppClass, + } + cItems = append(cItems, cItem) + } + + return cItems, nil +} + +func (ar *AppRepo) GetAppTagList(ctx context.Context) ([]entity.TagItem, error) { + apps := make([]sql.App, 0) + err := DB.Model(&sql.App{}). + Select("apps.app_tag").Group("apps.app_tag"). + Find(&apps).Error + if err != nil { + return make([]entity.TagItem, 0), err + } + + tagItem := make([]entity.TagItem, 0) + for _, v := range apps { + var id []string + appTags := strings.Split(v.AppTag, ",") + for _, x := range appTags { + id = append(id, x) + } + tag := entity.TagItem{ + Id: id, + } + tagItem = append(tagItem, tag) + } + + return tagItem, nil +} + +func (ar *AppRepo) GetAppsBySearchText(ctx context.Context, searchText string) ([]entity.App, error) { + list := make([]sql.App, 0) + err := DB.WithContext(ctx).Model(&sql.App{}). + Where("app_id LIKE ? OR name LIKE ?", "%"+searchText+"%", "%"+searchText+"%"). + Find(&list).Error + if err != nil { + return nil, err + } + result := make([]entity.App, 0) + for _, v := range list { + /*statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo*/ + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return result, nil +} + +func (ar *AppRepo) GetAppByCreator(ctx context.Context, phone string) ([]entity.App, error) { + list := make([]sql.App, 0) + err := DB.WithContext(ctx).Model(&sql.App{}). + Where("created_by = ? ", phone). + Find(&list).Error + if err != nil { + return nil, err + } + + result := make([]entity.App, 0) + for _, v := range list { + /*statusInfo, _ := ar.GetAppStatusInfo(ctx, v.AppId) + v.StatusInfo = statusInfo*/ + temp := v + result = append(result, *tr.CovertAppToEntity(&temp)) + } + return result, nil +} diff --git a/infrastructure/db/repo/mysql/app_build_info.go b/infrastructure/db/repo/mysql/app_build_info.go new file mode 100644 index 0000000..6ffbae7 --- /dev/null +++ b/infrastructure/db/repo/mysql/app_build_info.go @@ -0,0 +1,199 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/db/entity/sql" + "gorm.io/gorm" +) + +var _ repository.IAppBuildInfoRepo = new(AppBuildInfoMysqlRepo) + +type AppBuildInfoMysqlRepo struct { +} + +func NewAppBuildInfoMysqlRepo() *AppBuildInfoMysqlRepo { + return &AppBuildInfoMysqlRepo{} +} + +func (a *AppBuildInfoMysqlRepo) Insert(ctx context.Context, item entity.AppBuildInfo) error { + err := DB.Model(&sql.AppBuildInfo{}).Create(tr.CovertBuildInfoToSql(&item)).Error + return err +} + +func (a *AppBuildInfoMysqlRepo) GetInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + query := "trace_id=?" + args := []interface{}{id} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}). + Where(query, args...). + First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), err +} + +func (a *AppBuildInfoMysqlRepo) GetInfoByBuildInfoId(ctx context.Context, buildInfoId string) (*entity.AppBuildInfo, error) { + query := "build_info_id=?" + args := []interface{}{buildInfoId} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}). + Where(query, args...). + First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), err +} + +func (a *AppBuildInfoMysqlRepo) GetInfoByBuildId(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + query := "build_info_id=?" + args := []interface{}{id} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}). + Where(query, args...). + First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), err +} + +func (a *AppBuildInfoMysqlRepo) GetLatestInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + query := "app_id=?" + args := []interface{}{appId} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}). + Where(query, args...). + Order("create_time DESC"). + First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), nil +} + +func (a *AppBuildInfoMysqlRepo) GetTrialInfoByAppId(ctx context.Context, appId string) (*entity.AppBuildInfo, error) { + query := "app_id=? and source=?" + args := []interface{}{appId, entity.APP_BUILD_SOURCE_TRIAL} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}).Where(query, args...).First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), nil +} + +func (a *AppBuildInfoMysqlRepo) GetTrialInfoById(ctx context.Context, id string) (*entity.AppBuildInfo, error) { + query := "trace_id=? and source=?" + args := []interface{}{id, entity.APP_BUILD_SOURCE_TRIAL} + info := sql.AppBuildInfo{} + err := DB.Model(&sql.AppBuildInfo{}). + Where(query, args...).First(&info).Error + if err != nil { + return nil, err + } + return tr.CovertBuildInfoToEntity(&info), nil +} + +func (a *AppBuildInfoMysqlRepo) AddTrial(ctx context.Context, id string) error { + query := "trace_id=?" + args := []interface{}{id} + return DB.Model(&sql.AppBuildInfo{}).Where(query, args...).Update("source", entity.APP_BUILD_SOURCE_TRIAL).Error +} + +func (a *AppBuildInfoMysqlRepo) CancelTrial(ctx context.Context, id string) error { + query := "trace_id=?" + args := []interface{}{id} + data := make(map[string]interface{}) + data["source"] = entity.APP_BUILD_SOURCE_BUILD //零值字段 + data["path_and_query"] = "" + return DB.Model(&sql.AppBuildInfo{}).Where(query, args...).Updates(data).Error + +} + +func (a *AppBuildInfoMysqlRepo) UpdateTrialStartParams(ctx context.Context, id string, params entity.AppStartParams) error { + query := "trace_id=?" + args := []interface{}{id} + return DB.Model(&sql.AppBuildInfo{}).Where(query, args...).Update("path_and_query", params.PathAndQuery).Error + +} + +func (a *AppBuildInfoMysqlRepo) UpdateTrialPath(ctx context.Context, id, path string) error { + query := "trace_id=?" + args := []interface{}{id} + return DB.Model(&sql.AppBuildInfo{}).Where(query, args...).Update("path", path).Error + +} + +func (a *AppBuildInfoMysqlRepo) UpdateOneStatus(ctx context.Context, id string, status bool) error { + query := "trace_id=?" + args := []interface{}{id} + return DB.Model(&sql.AppBuildInfo{}).Where(query, args...).Update("status", status).Error +} + +func (a *AppBuildInfoMysqlRepo) GetList(ctx context.Context, appId string, pageNo, pageSize int) (int64, []entity.AppBuildInfo, error) { + query := "app_id =? " + args := []interface{}{appId} + sort := "create_time DESC" + var total int64 + + list := make([]sql.AppBuildInfo, 0) + err := DB.Model(&sql.AppBuildInfo{}).Debug(). + Where(query, args...).Count(&total). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertBuildInfoToEntity(&temp)) + } + return total, result, nil +} + +func (a *AppBuildInfoMysqlRepo) GetAll(ctx context.Context) ([]entity.AppBuildInfo, error) { + list := make([]sql.AppBuildInfo, 0) + err := DB.Model(&sql.AppBuildInfo{}).Debug(). + Find(&list).Error + if err != nil { + return nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertBuildInfoToEntity(&temp)) + } + return result, nil +} + +func (a *AppBuildInfoMysqlRepo) GetAppBuilds(ctx context.Context, groupID, appId string, pageSize, pageNo int) (int64, []entity.AppBuildInfo, error) { + query := "app_id =? and group_id =?" + args := []interface{}{appId, groupID} + sort := "create_time desc" + var total int64 + list := make([]sql.AppBuildInfo, 0) + err := DB.Model(&sql.AppBuildInfo{}).Debug(). + Where(query, args...).Count(&total). + Order(sort). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.AppBuildInfo, 0) + for _, v := range list { + temp := v + result = append(result, *tr.CovertBuildInfoToEntity(&temp)) + } + return total, result, nil +} + +func (a *AppBuildInfoMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} diff --git a/infrastructure/db/repo/mysql/app_oper_config.go b/infrastructure/db/repo/mysql/app_oper_config.go new file mode 100644 index 0000000..317b42b --- /dev/null +++ b/infrastructure/db/repo/mysql/app_oper_config.go @@ -0,0 +1,31 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/repository" +) + +var _ repository.IAppOperConfigRepo = new(AppOperConfigRepo) + +type AppOperConfigRepo struct { +} + +func (a *AppOperConfigRepo) Insert(ctx context.Context, item repository.AppOperConfig) error { + err := DB.Model(&repository.AppOperConfig{}).Create(&item).Error + return err +} + +func (a *AppOperConfigRepo) Update(ctx context.Context, item repository.AppOperConfig) error { + data := make(map[string]interface{}) + data["auto_review_app"] = item.AutoReviewApp + data["update_time"] = item.UpdateTime + + return DB.Model(&repository.AppOperConfig{}).Where("id=?", item.Id).Updates(data).Error +} + +func (a *AppOperConfigRepo) Find(ctx context.Context) (repository.AppOperConfig, error) { + var item repository.AppOperConfig + err := DB.Model(&repository.AppOperConfig{}).First(&item).Error + + return item, err +} diff --git a/infrastructure/db/repo/mysql/app_temp_info.go b/infrastructure/db/repo/mysql/app_temp_info.go new file mode 100644 index 0000000..e11d557 --- /dev/null +++ b/infrastructure/db/repo/mysql/app_temp_info.go @@ -0,0 +1,180 @@ +package mysql + +import ( + "context" + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/utility" + + "gorm.io/gorm" +) + +var _ repository.IAppTempInfoRepo = new(AppTempInfoByMysqlRepo) + +type AppTempInfoByMysqlRepo struct { +} + +type AppTempInfoMysql struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AppID string `json:"appId" gorm:"column:app_id;type:varchar(64);comment:id"` + Name string `json:"name" gorm:"column:name;type:varchar(256);comment:名字"` + Sequence int `json:"sequence" gorm:"column:sequence;type:INT(4);comment:版本号"` + AppClass string `json:"appClass" gorm:"column:app_class;type:varchar(64);comment:用途"` + AppType string `json:"appType" gorm:"column:app_type;type:varchar(64);comment:应用类型--mop使用为了和应用市场区分开"` + StatusValue string `json:"statusValue" gorm:"column:status_value;type:varchar(64);comment:状态值"` + StatusReason string `json:"statusReason" gorm:"column:status_reason;type:varchar(64);comment:状态原因"` + StatusLastUpdated int64 `json:"statusLastUpdated" gorm:"column:status_last_updated;type:BIGINT(16);comment:状态更新时间"` + StatusModifiedBy string `json:"statusModifiedBy" gorm:"column:status_modified_by;type:varchar(64);comment:状态更新人"` + DeveloperID string `json:"developerId" gorm:"column:developer_id;type:varchar(64);comment:开发者id"` + GroupID string `json:"groupId" gorm:"column:group_id;type:varchar(64);comment:组id"` + Created int64 `json:"created" gorm:"column:created;type:BIGINT(16);comment:创建时间"` + CreatedBy string `json:"createdBy" gorm:"column:created_by;type:varchar(64);comment:组id"` + CustomDataDetailDescription string `json:"customDataDetailDescription" gorm:"column:customData_detail_description;type:varchar(64);comment:小程序详细描述"` + CustomDataSourceFile string `json:"customDataSourceFile" gorm:"column:customData_source_file;type:TEXT;comment:编译文件"` + CustomDataVersionDescription string `json:"customDataVersionDescription" gorm:"column:customData_version_description;type:varchar(64);comment:小程序编译包版本描述"` + CustomDataDeveloper string `json:"customDataDeveloper" gorm:"column:customData_developer;type:varchar(64);comment:开发者"` + Version string `json:"version" gorm:"column:version;type:varchar(64);comment:应用版本"` + CoreDescription string `json:"coreDescription" gorm:"column:core_description;type:varchar(64);comment:核心描述"` + Logo string `json:"logo" gorm:"column:logo;type:varchar(64);comment:图标"` + ProjectType int `gorm:"column:project_type;type:tinyint(1);default:0;comment:'项目类型'"` +} + +func (AppTempInfoMysql) TableName() string { + return "app_temp_info_mysqls" +} + +func (b AppTempInfoByMysqlRepo) Insert(ctx context.Context, info *entity.AppTempInfo) error { + sqlInfo := convertAppTempInfoToAppTempInfoMysql(info) + return DB.Debug().Model(&AppTempInfoMysql{}).Create(&sqlInfo).Error +} + +func (b AppTempInfoByMysqlRepo) UpdateInfo(ctx context.Context, info *entity.AppTempInfo) error { + query := "app_id = ? and sequence = ?" + args := []interface{}{info.AppID, info.Sequence} + sqlInfo := convertAppTempInfoToAppTempInfoMysql(info) + + params := map[string]interface{}{ + "app_id": sqlInfo.AppID, + "name": sqlInfo.Name, + "sequence": sqlInfo.Sequence, + "app_class": sqlInfo.AppClass, + "app_type": sqlInfo.AppType, + "status_value": sqlInfo.StatusValue, + "status_reason": sqlInfo.StatusValue, + "status_last_updated": sqlInfo.StatusLastUpdated, + "status_modified_by": sqlInfo.StatusModifiedBy, + "developer_id": sqlInfo.DeveloperID, + "group_id": sqlInfo.GroupID, + "created": sqlInfo.Created, + "created_by": sqlInfo.CreatedBy, + "customData_detail_description": sqlInfo.CustomDataDetailDescription, + "customData_source_file": sqlInfo.CustomDataSourceFile, + "customData_version_description": sqlInfo.CustomDataVersionDescription, + "customData_developer": sqlInfo.CustomDataDeveloper, + "version": sqlInfo.Version, + "core_description": sqlInfo.CoreDescription, + "logo": sqlInfo.Logo, + } + + return DB.Model(&AppTempInfoMysql{}).Where(query, args...).Updates(¶ms).Error +} + +func (b AppTempInfoByMysqlRepo) GetInfoByAppId(ctx context.Context, appId string) (*entity.AppTempInfo, error) { + query := "app_id = ? and sequence = ?" + args := []interface{}{appId, entity.AppTempDefSequence} + + appTempInfoMysql := AppTempInfoMysql{} + err := DB.Model(&AppTempInfoMysql{}).Where(query, args...).First(&appTempInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertAppTempInfoMysqlToAppTempInfo(appTempInfoMysql) + return &result, err +} + +func (b AppTempInfoByMysqlRepo) GetInfoByAppIdAndSeq(ctx context.Context, appId string, seq int) (*entity.AppTempInfo, error) { + query := "app_id = ? and sequence = ?" + args := []interface{}{appId, seq} + + appTempInfoMysql := AppTempInfoMysql{} + err := DB.Model(&AppTempInfoMysql{}).Where(query, args...).First(&appTempInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertAppTempInfoMysqlToAppTempInfo(appTempInfoMysql) + return &result, err +} + +func (b AppTempInfoByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertAppTempInfoToAppTempInfoMysql(appTempInfo *entity.AppTempInfo) AppTempInfoMysql { + result := AppTempInfoMysql{} + + result.AppID = appTempInfo.AppID + result.Name = appTempInfo.Name + result.Sequence = appTempInfo.Sequence + result.AppClass = appTempInfo.AppClass + result.AppType = appTempInfo.AppType + result.StatusValue = appTempInfo.Status.Value + result.StatusReason = appTempInfo.Status.Reason + result.StatusLastUpdated = appTempInfo.Status.LastUpdated + result.StatusModifiedBy = appTempInfo.Status.ModifiedBy + result.DeveloperID = appTempInfo.DeveloperID + result.GroupID = appTempInfo.GroupID + result.Created = appTempInfo.Created + result.CreatedBy = appTempInfo.CreatedBy + result.CustomDataDetailDescription = appTempInfo.CustomData.DetailDescription + result.CustomDataSourceFile = utility.InterfaceToJsonString(appTempInfo.CustomData.SourceFile) + result.CustomDataVersionDescription = appTempInfo.CustomData.VersionDescription + result.CustomDataDeveloper = appTempInfo.CustomData.Developer + result.Version = appTempInfo.Version + result.CoreDescription = appTempInfo.CoreDescription + result.Logo = appTempInfo.Logo + result.ProjectType = appTempInfo.ProjectType + + return result +} + +func convertAppTempInfoMysqlToAppTempInfo(appTempInfoMysql AppTempInfoMysql) entity.AppTempInfo { + result := entity.AppTempInfo{} + + status := entity.Status{ + Value: appTempInfoMysql.StatusValue, + Reason: appTempInfoMysql.StatusReason, + LastUpdated: appTempInfoMysql.StatusLastUpdated, + ModifiedBy: appTempInfoMysql.StatusModifiedBy, + } + + var sourceFile []entity.CustomDataSourceFile + json.Unmarshal([]byte(appTempInfoMysql.CustomDataSourceFile), &sourceFile) + + customData := entity.CustomDataInfo{ + DetailDescription: appTempInfoMysql.CustomDataDetailDescription, + SourceFile: sourceFile, + VersionDescription: appTempInfoMysql.CustomDataVersionDescription, + Developer: appTempInfoMysql.CustomDataDeveloper, + } + + result.AppID = appTempInfoMysql.AppID + result.Name = appTempInfoMysql.Name + result.Sequence = appTempInfoMysql.Sequence + result.AppClass = appTempInfoMysql.AppClass + result.AppType = appTempInfoMysql.AppType + result.Status = status + result.DeveloperID = appTempInfoMysql.DeveloperID + result.GroupID = appTempInfoMysql.GroupID + result.Created = appTempInfoMysql.Created + result.CreatedBy = appTempInfoMysql.CreatedBy + result.CustomData = customData + result.Version = appTempInfoMysql.Version + result.CoreDescription = appTempInfoMysql.CoreDescription + result.Logo = appTempInfoMysql.Logo + result.ProjectType = appTempInfoMysql.ProjectType + + return result +} diff --git a/infrastructure/db/repo/mysql/binding.go b/infrastructure/db/repo/mysql/binding.go new file mode 100644 index 0000000..7a4a849 --- /dev/null +++ b/infrastructure/db/repo/mysql/binding.go @@ -0,0 +1,1687 @@ +package mysql + +import ( + "context" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/db/entity/sql" + "finclip-app-manager/infrastructure/utility" + "fmt" + "time" + + "gorm.io/gorm" +) + +var _ repository.IBindingRepo = new(BindingByMysqlRepo) + +type BindingByMysqlRepo struct { +} + +func NewBindingByMysqlRepo() *BindingByMysqlRepo { + return &BindingByMysqlRepo{} +} + +type Bundle struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BundleID string `json:"bundleId" gorm:"column:bundle_id;type:varchar(512);default:'';comment:bundleId"` + Remark string `json:"remark" gorm:"column:remark;type:varchar(512);default:'';comment:类型"` + SDKKey string `json:"SDKKey" gorm:"column:sdk_key;type:varchar(512);default:'';comment:sdkKey"` + SDKID string `json:"SDKID" gorm:"column:sdk_id;type:varchar(64);default:'';comment:sdkid"` + IsFirstCreate bool `json:"isFirstCreate" gorm:"column:is_first_create;type:bool;default:false;comment:是否第一次创建"` //是否第一次创建 + CreatedAt int64 `json:"createdAt" gorm:"column:created_at;type:BIGINT(16);default:0;comment:创建时间"` + CreatedAccount string `json:"createdAccount" bson:"created_account" gorm:"column:created_account;type:varchar(64);default:'';comment:创建账号"` + CreatedBy string `json:"createdBy" bson:"created_by" gorm:"column:created_by;type:varchar(64);default:'';comment:创建人"` + IsForbidden int `json:"isForbidden" bson:"is_forbidden" gorm:"column:is_forbidden;type:BIGINT(16);default:0;comment:是否禁用"` //是否禁用 0:可用 1:禁用 +} + +func (Bundle) TableName() string { + return "bundle" +} + +type BundleInfo struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BindingId string `json:"bindingId" gorm:"column:binding_id;key;type:varchar(64);default:'';comment:应用Id"` + GroupID string `json:"groupId" gorm:"column:group_id;key;type:varchar(64);default:'';comment:企业ID"` + BundleID string `json:"bundleId" gorm:"column:bundle_id;type:varchar(512);default:'';comment:bundleId"` + Remark string `json:"remark" gorm:"column:remark;type:varchar(512);default:'';comment:类型"` + SDKKey string `json:"SDKKey" gorm:"column:sdk_key;type:varchar(512);default:'';comment:sdkKey"` + SDKID string `json:"SDKID" gorm:"column:sdk_id;type:varchar(64);default:'';comment:sdkid"` + IsFirstCreate bool `json:"isFirstCreate" gorm:"column:is_first_create;type:bool;default:false;comment:是否第一次创建"` //是否第一次创建 + CreatedAt int64 `json:"createdAt" gorm:"column:created_at;type:BIGINT(16);default:0;comment:创建时间"` + CreatedAccount string `json:"createdAccount" gorm:"column:created_account;type:varchar(64);default:'';comment:创建账号"` + CreatedBy string `json:"createdBy" gorm:"column:created_by;type:varchar(64);default:'';comment:创建人"` + IsForbidden int `json:"isForbidden" gorm:"column:is_forbidden;type:BIGINT(16);default:0;comment:是否禁用"` //是否禁用 0:未禁用 1:禁用 + IsReview int `json:"isReview" gorm:"column:is_review;type:tinyint;default:0;comment:是否审核应用"` //是否禁用 0:未禁用 1:禁用 +} + +func (BundleInfo) TableName() string { + return "bundle_info" +} + +type BindingMysql struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BindingID string `json:"bindingID" gorm:"column:binding_id;unique;type:varchar(64);comment:'应用的id'"` + Name string `json:"name" gorm:"column:name;type:varchar(64);default:'';comment:'应用名称'"` + //BundleInfos string `json:"bundleInfos" gorm:"column:bundle_infos;type:text;comment:'bundle ids'"` + CreatedInfoBy string `json:"createdInfoBy" gorm:"column:created_info_by;type:varchar(64);default:'';comment:''"` + CreatedInfoAt int64 `json:"createdInfoAt" gorm:"column:created_info_at;type:BIGINT(16);default:0;comment:''"` + CreatedInfoAccount string `json:"createdInfoAccount" gorm:"column:created_info_account;type:varchar(64);default:'';comment:''"` + GroupID string `json:"groupId" gorm:"column:group_id;type:varchar(64);default:'';comment:'企业ID'"` + GroupName string `json:"groupName" gorm:"column:group_name;type:varchar(64);default:'';comment:'企业名称(为了查询)'"` + CooperateStatusValue string `json:"cooperateStatusValue" gorm:"column:cooperate_status_value;type:varchar(256);default:'';comment:''"` + CooperateStatusReason string `json:"cooperateStatusReason" gorm:"column:cooperate_status_reason;type:varchar(256);default:'';comment:''"` + CooperateStatusLastUpdated int64 `json:"cooperateStatusLastUpdated" gorm:"column:cooperate_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateStatusModifiedBy string `json:"cooperateStatusModifiedBy" gorm:"column:cooperate_status_modified_by;type:varchar(256);default:0;comment:''"` + CooperateValidStatusReason string `json:"cooperateValidStatusReason" gorm:"column:cooperate_valid_status_reson;type:varchar(256);default:'';comment:''"` + CooperateValidStatusLastUpdated int64 `json:"cooperateValidStatusLastUpdated" gorm:"column:cooperate_valid_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateValidStatusModifiedBy string `json:"cooperateValidStatusModifiedBy" gorm:"column:cooperate_valid_status_modified_by;type:varchar(256);default:0;comment:''"` + CooperateInvalidStatusReason string `json:"cooperateInvalidStatusReason" gorm:"column:cooperate_invalid_status_reson;type:varchar(256);default:'';comment:''"` + CooperateInvalidStatusLastUpdated int64 `json:"cooperateInvalidStatusLastUpdated" gorm:"column:cooperate_invalid_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateInvalidStatusModifiedBy string `json:"cooperateInvalidStatusModifiedBy" gorm:"column:cooperate_invalid_status_modified_by;type:varchar(256);default:0;comment:''"` + BundleInfos []BundleInfo `json:"bundleInfos" gorm:"ForeignKey:binding_id;AssociationForeignKey:binding_id"` + AppInfos []LinkAppInfo `json:"appInfos" gorm:"ForeignKey:binding_id;AssociationForeignKey:binding_id"` + //sAppInfos string `json:"appInfos" gorm:"column:app_infos;type:text;comment:'appid 的信息'"` + Owner string `json:"owner" gorm:"column:owner;type:varchar(64);default:'';comment:'所属企业'"` + Expire int64 `json:"expire" gorm:"column:expire;type:BIGINT(16);default:0;comment:''"` + ApiServer string `json:"apiServer" gorm:"column:api_server;type:varchar(256);default:'';comment:'子域名'"` + PlatForm int `json:"platform" gorm:"column:platform;type:tinyint;comment:'来源平台'"` + AutoBind int `json:"autoBind" gorm:"column:auto_bind;type:tinyint;comment:'自动绑定'"` + HiddenBundle int `json:"hiddenBundle" gorm:"column:hidden_bundle;type:tinyint;comment:'隐藏bundle信息'"` + FromBindingID string `json:"fromBindingId" gorm:"column:from_binding_id;type:varchar(64);default:'';comment:'来源bindingid'"` +} + +type BindingMysqlV2 struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BindingID string `json:"bindingID" gorm:"column:binding_id;unique;type:varchar(64);comment:'应用的id'"` + Name string `json:"name" gorm:"column:name;type:varchar(64);default:'';comment:'应用名称'"` + CreatedInfoBy string `json:"createdInfoBy" gorm:"column:created_info_by;type:varchar(64);default:'';comment:''"` + CreatedInfoAt int64 `json:"createdInfoAt" gorm:"column:created_info_at;type:BIGINT(16);default:0;comment:''"` + CreatedInfoAccount string `json:"createdInfoAccount" gorm:"column:created_info_account;type:varchar(64);default:'';comment:''"` + GroupID string `json:"groupId" gorm:"column:group_id;type:varchar(64);default:'';comment:'企业ID'"` + GroupName string `json:"groupName" gorm:"column:group_name;type:varchar(64);default:'';comment:'企业名称(为了查询)'"` + CooperateStatusValue string `json:"cooperateStatusValue" gorm:"column:cooperate_status_value;type:varchar(256);default:'';comment:''"` + CooperateStatusReason string `json:"cooperateStatusReason" gorm:"column:cooperate_status_reason;type:varchar(256);default:'';comment:''"` + CooperateStatusLastUpdated int64 `json:"cooperateStatusLastUpdated" gorm:"column:cooperate_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateStatusModifiedBy string `json:"cooperateStatusModifiedBy" gorm:"column:cooperate_status_modified_by;type:varchar(256);default:0;comment:''"` + CooperateValidStatusReason string `json:"cooperateValidStatusReason" gorm:"column:cooperate_valid_status_reson;type:varchar(256);default:'';comment:''"` + CooperateValidStatusLastUpdated int64 `json:"cooperateValidStatusLastUpdated" gorm:"column:cooperate_valid_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateValidStatusModifiedBy string `json:"cooperateValidStatusModifiedBy" gorm:"column:cooperate_valid_status_modified_by;type:varchar(256);default:0;comment:''"` + CooperateInvalidStatusReason string `json:"cooperateInvalidStatusReason" gorm:"column:cooperate_invalid_status_reson;type:varchar(256);default:'';comment:''"` + CooperateInvalidStatusLastUpdated int64 `json:"cooperateInvalidStatusLastUpdated" gorm:"column:cooperate_invalid_status_last_updated;type:BIGINT(16);default:0;comment:''"` + CooperateInvalidStatusModifiedBy string `json:"cooperateInvalidStatusModifiedBy" gorm:"column:cooperate_invalid_status_modified_by;type:varchar(256);default:0;comment:''"` + Owner string `json:"owner" gorm:"column:owner;type:varchar(64);default:'';comment:'所属企业'"` + Expire int64 `json:"expire" gorm:"column:expire;type:BIGINT(16);default:0;comment:''"` + ApiServer string `json:"apiServer" gorm:"column:api_server;type:varchar(256);default:'';comment:'子域名'"` + PlatForm int `json:"platform" gorm:"column:platform;type:tinyint;comment:'来源平台'"` + AutoBind int `json:"autoBind" gorm:"column:auto_bind;type:tinyint;comment:'自动绑定'"` + HiddenBundle int `json:"hiddenBundle" gorm:"column:hidden_bundle;type:tinyint;comment:'隐藏bundle信息'"` + FromBindingID string `json:"fromBindingId" gorm:"column:from_binding_id;type:varchar(64);default:'';comment:'来源bindingid'"` +} + +type LinkAppInfo struct { + Id uint64 `gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BindingId string `gorm:"column:binding_id;key;type:varchar(64);comment:'关联应用的id'"` + AppId string `gorm:"column:app_id;key;type:varchar(64);comment:'小程序id'"` + AssociatedAt int64 `gorm:"column:associated_at;type:BIGINT(16);default:0;comment:'关联时间'"` + AssociatedBy string `gorm:"column:associated_by;type:varchar(64);default:'';comment:'关联人'"` +} + +func (LinkAppInfo) TableName() string { + return "link_app_infos" +} + +func (BindingMysql) TableName() string { + return "binding" +} + +func (BindingMysqlV2) TableName() string { + return "binding" +} + +func (b BindingByMysqlRepo) GetInfo(ctx context.Context, bindingId string) (*entity.Binding, error) { + info := BindingMysql{} + err := DB.Model(&BindingMysql{}).WithContext(ctx). + Where("binding_id=?", bindingId). + //Preload("BundleInfos"). + //Preload("AppInfos"). + First(&info).Error + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, info.BindingID) + + if len(linkAppInfos) > 0 { + info.AppInfos = linkAppInfos + } + + if len(bundleInfos) > 0 { + info.BundleInfos = bundleInfos + } + + result := convertBindingMysqlToBinding(info) + return &result, err +} + +func (b BindingByMysqlRepo) GetByGroupIdAndName(ctx context.Context, groupId string, name string, isAdmin bool) (*entity.Binding, error) { + query := "group_id = ? and name = ? " + args := []interface{}{groupId, name} + if isAdmin { + query += "and platform = ? " + args = append(args, entity.BINGING_PLATFORM_OPER) + } else { + query += "and platform = ? " + args = append(args, entity.BINGING_PLATFORM_ORGAN) + } + bindingMysql := BindingMysql{} + err := DB.Model(&BindingMysql{}).Where(query, args...). + //Preload("BundleInfos").Preload("AppInfos"). + First(&bindingMysql).Error + if err != nil { + return nil, err + } + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + result := convertBindingMysqlToBinding(bindingMysql) + return &result, err +} + +func (b BindingByMysqlRepo) GetByApiServer(ctx context.Context, apiServer string) (entity.Binding, error) { + query := "api_server = ?" + args := []interface{}{apiServer} + res := entity.Binding{} + bindingMysql := BindingMysql{} + err := DB.Model(&BindingMysql{}).Where(query, args...).First(&bindingMysql).Error + if err != nil { + return res, err + } + + query = "binding_id = ?" + args = []interface{}{bindingMysql.BindingID} + + bundleInfoMysqls := make([]BundleInfo, 0) + err = DB.Model(&BindingMysql{}).Where(query, args...).Find(&bundleInfoMysqls).Error + if err != nil { + return res, err + } + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + result := convertBindingMysqlToBinding(bindingMysql) + return result, err +} + +func (b BindingByMysqlRepo) GetInfoByParams(ctx context.Context, sdkKey, organId, appId string) (*entity.Binding, error) { + db := DB.Model(&BindingMysql{}) + //db = db.Preload("BundleInfos").Preload("AppInfos") + + db.Where("bundle_info.sdk_key like ?", sdkKey) + + if appId != "" { + db.Where("link_app_infos.app_id like ?", appId) + } + + if organId != "" { + db.Where("binding.group_id = ?", organId) + } + + bindingMysql := BindingMysql{} + err := db. + Select("DISTINCT(binding.id), binding.*"). + Joins("left join bundle_info on binding.binding_id = bundle_info.binding_id"). + Joins("left join link_app_infos on binding.binding_id = link_app_infos.binding_id"). + First(&bindingMysql).Error + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + binding := convertBindingMysqlToBinding(bindingMysql) + + return &binding, err +} + +func (b BindingByMysqlRepo) GetInfoBySdkKeyOrganId(ctx context.Context, organId, sdkKey string) (*entity.Binding, error) { + query := "group_id = ? and sdk_key = ?" + args := []interface{}{organId, sdkKey} + + bundleInfoMysql := BundleInfo{} + err := DB.Model(&BundleInfo{}).Where(query, args...).First(&bundleInfoMysql).Error + if err != nil { + return nil, err + } + + return b.GetInfo(ctx, bundleInfoMysql.BindingId) +} + +func (b BindingByMysqlRepo) GetAllSdkKey(ctx context.Context, organId string) ([]string, error) { + query := "group_id = ?" + args := []interface{}{organId} + + bundleInfoMysqls := make([]BundleInfo, 0) + err := DB.Model(&BundleInfo{}).Where(query, args...).Find(&bundleInfoMysqls).Error + if err != nil { + return nil, err + } + + result := make([]string, 0) + for _, v := range bundleInfoMysqls { + result = append(result, v.SDKKey) + } + + return result, err +} + +func (b BindingByMysqlRepo) GetBindListBySdkKey(ctx context.Context, sdkKey string) ([]entity.Binding, error) { + query := "sdk_key = ?" + args := []interface{}{sdkKey} + + bundleInfoMysqls := make([]BundleInfo, 0) + err := DB.Model(&BundleInfo{}).Where(query, args...).Order("created_at").Find(&bundleInfoMysqls).Error + if err != nil { + return nil, err + } + + bindings := make([]entity.Binding, 0) + for _, bundleInfoMysql := range bundleInfoMysqls { + binding, _ := b.GetInfo(ctx, bundleInfoMysql.BindingId) + bindings = append(bindings, *binding) + } + + return bindings, err +} + +func (b BindingByMysqlRepo) SdkKeyExi(ctx context.Context, sdkKey string) (bool, error) { + if _, ok := entity.SdkExiCache.Get(sdkKey); ok { + return true, nil + } + + var count int64 + err := DB.Model(&BundleInfo{}). + Where("sdk_key=?", sdkKey). + Count(&count).Error + if err != nil { + return false, err + } + + if count > 0 { + entity.SdkExiCache.Set(sdkKey, true, -1) + return true, err + } + return false, err +} + +func (b BindingByMysqlRepo) Insert(ctx context.Context, bind *entity.Binding) error { + info := convertBindingToBindingMysql(bind) + infoV2 := convertBindingMysqlToBindingMysqlV2(&info) + err := DB.WithContext(ctx).Model(&BindingMysqlV2{}).Create(&infoV2).Error + if err != nil { + return err + } + if len(info.BundleInfos) > 0 { + for _, v := range info.BundleInfos { + DB.Model(&BundleInfo{}).Create(&v) + } + } + if len(info.AppInfos) > 0 { + for _, v := range info.AppInfos { + DB.Model(&LinkAppInfo{}).Create(&v) + } + } + return nil +} + +func (b BindingByMysqlRepo) Count(ctx context.Context) (int, error) { + query := "" + args := []interface{}{} + var count int64 + err := DB.Model(&BindingMysql{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (b BindingByMysqlRepo) GetCountByStatus(ctx context.Context, status string, platform int) (int, error) { + query := "cooperate_status_value = ?" + args := []interface{}{"Valid"} + /*switch platform { + case entity.BINGING_PLATFORM_OPER: + query += " and platform = ? and from_binding_id = ?" + args = append(args, platform) + args = append(args, "") + case entity.BINGING_PLATFORM_ORGAN: + query += " and platform = ?" + args = append(args, platform) + default: + query += " and ( ( platform = ? and from_binding_id = ? ) or ( platform = ? ) )" + args = append(args, entity.BINGING_PLATFORM_OPER) + args = append(args, "") + args = append(args, entity.BINGING_PLATFORM_ORGAN) + }*/ + query += " and ( ( platform = ? and group_id = ? ) or ( platform = ? ) )" + args = append(args, entity.BINGING_PLATFORM_OPER) + args = append(args, "") + args = append(args, entity.BINGING_PLATFORM_ORGAN) + var count int64 + err := DB.Model(&BindingMysql{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (b BindingByMysqlRepo) GetBundleIdNum(ctx context.Context) (int, error) { + query := "is_forbidden = ?" + args := []interface{}{0} + var count int64 + err := DB.Model(&BundleInfo{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (b BindingByMysqlRepo) GetBundleIdLimitHand(ctx context.Context, groupId string) (int, error) { + var total int64 + err := DB.Model(&BundleInfo{}). + Select("select * from bundle_info").Joins("left join binding on binding.binding_id = bundle_info.binding_id"). + Where("binding.group_id = ? and bundle_info.is_forbidden = ?", groupId, 0). + Count(&total).Error + + return int(total), err +} + +func (b BindingByMysqlRepo) GetBundleLimit(ctx context.Context) (int, error) { + /*query := "" + args := []interface{}{}*/ + query := "is_forbidden = ?" + args := []interface{}{0} + var count int64 + err := DB.Model(&Bundle{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (b BindingByMysqlRepo) GetBindingByBindingId(ctx context.Context, bindingId string) (*entity.Binding, error) { + bindingMysql := BindingMysql{} + err := DB.Model(&BindingMysql{}). + Where("binding_id = ?", bindingId). + //Preload("BundleInfos").Preload("AppInfos"). + First(&bindingMysql).Error + if err != nil { + return nil, err + } + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + result := convertBindingMysqlToBinding(bindingMysql) + return &result, err +} + +func (b BindingByMysqlRepo) GetBindingByGroupIdAndBindingId(ctx context.Context, groupId string, bindingId string) (*entity.Binding, error) { + info := BindingMysql{} + err := DB.Model(&BindingMysql{}).WithContext(ctx). + Where("group_id = ? and binding_id = ?", []interface{}{groupId}, []interface{}{bindingId}). + //Preload("BundleInfos"). + //Preload("AppInfos"). + First(&info).Error + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, info.BindingID) + if len(linkAppInfos) > 0 { + info.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + info.BundleInfos = bundleInfos + } + result := convertBindingMysqlToBinding(info) + return &result, err +} + +func (b BindingByMysqlRepo) GetBindingByGroupIdAndSdkKey(ctx context.Context, groupId string, sdkKey string) (*entity.Binding, error) { + query := "group_id = ? and sdk_key = ?" + args := []interface{}{groupId, sdkKey} + + bundleInfoMysql := BundleInfo{} + err := DB.Model(&BundleInfo{}).Where(query, args...).First(&bundleInfoMysql).Error + if err != nil { + return nil, err + } + + return b.GetInfo(ctx, bundleInfoMysql.BindingId) +} + +func (b BindingByMysqlRepo) UpdateBundleInfosByGroupIdAndBindId(ctx context.Context, groupId string, bindingId string, infos []entity.BundleInfo) error { + return DB.Transaction(func(tx *gorm.DB) error { + var err error + for _, v := range infos { + query := "group_id = ? and binding_id = ?" + args := []interface{}{groupId, bindingId} + err = tx.Model(&BundleInfo{}). + Where(query, args...). + Updates(convertBundleInfoToBundleInfoMysql(bindingId, groupId, v)).Error + } + return err + }) +} + +func (b BindingByMysqlRepo) AppendBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error { + return DB.Transaction(func(tx *gorm.DB) error { + var err error + for _, v := range bundles { + item := convertBundleInfoToBundleInfoMysql(bindingId, groupId, v) + + if config.Cfg.PublishEnv == entity.ENV_PRIVATE { + //私有化环境中,如果要变为启用状态,要先判断该bundleId运营端是否已启用 + if v.IsForbidden == 0 { + info := BundleMysql{} + err := DB.Debug().Model(&BundleMysql{}).Where("binary bundle_id=?", v.BundleID).First(&info).Error + if err != nil { + return err + } + if info.IsForbidden == 1 { + return errors.New(utility.FS_BIND_IS_FORBIDDEN) + } + } + } + + if err = tx.Model(&BundleInfo{}).Create(&item).Error; err != nil { + return err + } + } + return nil + }) +} + +func (b BindingByMysqlRepo) UpdateBundleIsView(ctx context.Context, reviews []apiproto.BundleReviewItem, isReview int) error { + return DB.Transaction(func(tx *gorm.DB) error { + var err error + for _, review := range reviews { + query := "binding_id = ? and binary bundle_id= ?" + args := []interface{}{review.BindingId, review.BundleId} + params := map[string]interface{}{ + "is_review": isReview, + } + err = tx.Model(&BundleInfo{}).Debug(). + Where(query, args...). + Updates(params).Error + } + return err + }) +} + +func (b BindingByMysqlRepo) ListReviewBundle(ctx context.Context, pageSize int, pageNo int, searchText string, isReview int) (int64, []entity.ReviewBundleInfo, error) { + query := "binding.platform = ? AND binding.from_binding_id = ? AND bundle_info.is_review = ?" + args := []interface{}{entity.BINGING_PLATFORM_OPER, "", isReview} + if searchText != "" { + query += " AND (binding.name LIKE ? OR bundle_info.bundle_id LIKE ?) " + args = append(args, genLike(searchText)) + args = append(args, genLike(searchText)) + } + list := []entity.ReviewBundleInfo{} + var total int64 + var err error + DB.Debug().Model(&BindingMysql{}). + Joins("LEFT JOIN bundle_info ON binding.binding_id = bundle_info.binding_id"). + Where(query, args...). + Count(&total) + if pageSize == 0 && pageNo == 0 { + err = DB.Debug().Model(&BindingMysql{}). + Select("binding.binding_id as binding_id, binding.created_info_at as created_info_at, binding.name as name, binding.cooperate_status_value as status, bundle_info.bundle_id as bundle_id, bundle_info.remark as remark, bundle_info.sdk_key as sdk_key, bundle_info.sdk_id as sdk_id, bundle_info.is_forbidden as is_forbidden, bundle_info.is_review as is_review"). + Joins("LEFT JOIN bundle_info ON binding.binding_id = bundle_info.binding_id"). + Order("binding.created_info_at desc"). + Where(query, args...). + Scan(&list).Error + } else { + err = DB.Debug().Model(&BindingMysql{}). + Select("binding.binding_id as binding_id, binding.created_info_at as created_info_at, binding.name as name, binding.cooperate_status_value as status, bundle_info.bundle_id as bundle_id, bundle_info.remark as remark, bundle_info.sdk_key as sdk_key, bundle_info.sdk_id as sdk_id, bundle_info.is_forbidden as is_forbidden, bundle_info.is_review as is_review"). + Joins("LEFT JOIN bundle_info ON binding.binding_id = bundle_info.binding_id"). + Order("binding.created_info_at desc"). + Where(query, args...). + Offset((pageNo - 1) * pageSize). + Limit(pageSize). + Scan(&list).Error + } + return total, list, err +} + +func (b BindingByMysqlRepo) CheckReviewBySdkKey(ctx context.Context, sdkKey string) bool { + query := "binding.platform = ? AND binding.from_binding_id = ? AND binding.cooperate_status_value = ? AND bundle_info.is_review = ? and bundle_info.sdk_key = ? AND bundle_info.is_forbidden = ?" + args := []interface{}{entity.BINGING_PLATFORM_OPER, "", entity.StBindValid, 1, sdkKey, 0} + var total int64 + DB.Debug().Model(&BindingMysql{}). + Joins("LEFT JOIN bundle_info ON binding.binding_id = bundle_info.binding_id"). + Where(query, args...). + Count(&total) + return total > 0 +} + +func (b BindingByMysqlRepo) GetReviewBindBySdkKey(ctx context.Context, sdkKey string) (*entity.ReviewBundleInfo, error) { + query := "binding.platform = ? AND binding.from_binding_id = ? AND bundle_info.sdk_key = ?" + args := []interface{}{entity.BINGING_PLATFORM_OPER, "", sdkKey} + list := []entity.ReviewBundleInfo{} + + err := DB.Debug().Model(&BindingMysql{}). + Select("binding.binding_id as binding_id, binding.created_info_at as created_info_at, binding.name as name, binding.cooperate_status_value as status, bundle_info.bundle_id as bundle_id, bundle_info.remark as remark, bundle_info.sdk_key as sdk_key, bundle_info.sdk_id as sdk_id, bundle_info.is_forbidden as is_forbidden, bundle_info.is_review as is_review"). + Joins("LEFT JOIN bundle_info ON binding.binding_id = bundle_info.binding_id"). + Order("binding.created_info_at desc"). + Where(query, args...). + Scan(&list).Error + if err != nil { + return nil, err + } + if len(list) > 0 { + return &list[0], nil + } else { + return nil, nil + } +} + +func (b BindingByMysqlRepo) UpdateBundles(ctx context.Context, bindingId, groupId string, bundles []entity.BundleInfo) error { + return DB.Transaction(func(tx *gorm.DB) error { + var err error + for _, v := range bundles { + if config.Cfg.PublishEnv == entity.ENV_PRIVATE { + //私有化环境中,如果要变为启用状态,要先判断该bundleId运营端是否已启用 + if v.IsForbidden == 0 { + info := BundleMysql{} + err := DB.Debug().Model(&BundleMysql{}).Where("binary bundle_id=?", v.BundleID).First(&info).Error + if err != nil { + return err + } + if info.IsForbidden == 1 { + return errors.New(utility.FS_BIND_IS_FORBIDDEN) + } + } + } + query := "binding_id = ? and binary bundle_id= ?" + args := []interface{}{bindingId, v.BundleID} + + params := map[string]interface{}{ + "is_forbidden": v.IsForbidden, + "remark": v.Remark, + } + err = tx.Model(&BundleInfo{}).Debug(). + Where(query, args...). + Updates(params).Error + } + return err + }) +} + +func (b BindingByMysqlRepo) GetByBindIdList(ctx context.Context, ids []string) ([]entity.Binding, error) { + query := "binding_id in ?" + args := []interface{}{ids} + + bindingMysqls := make([]BindingMysql, 0) + err := DB.Model(&BindingMysql{}).Where(query, args...).Find(&bindingMysqls).Error + if err != nil { + return nil, err + } + + bindings := make([]entity.Binding, 0) + for _, bindingMysql := range bindingMysqls { + query = "binding_id = ?" + args = []interface{}{bindingMysql.BindingID} + + bundleInfoMysqls := make([]BundleInfo, 0) + err = DB.Model(&BundleInfo{}).Where(query, args...).Find(&bundleInfoMysqls).Error + if err != nil { + return nil, err + } + bindingMysql.BundleInfos = bundleInfoMysqls + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + bindings = append(bindings, convertBindingMysqlToBinding(bindingMysql)) + } + + return bindings, err +} + +func (b BindingByMysqlRepo) GetBindListByGroupId(ctx context.Context, groupId string, pageSize int, pageNo int) ([]entity.Binding, int, error) { + bindingMysqls := make([]BindingMysql, 0) + var total int64 + err := DB.Model(&BindingMysql{}).WithContext(ctx). + Where("group_id = ? and platform = 0", groupId). + //Preload("BundleInfos"). + //Preload("AppInfos"). + Order("created_info_at desc"). + Offset((pageNo - 1) * pageSize). + Limit(pageSize). + Find(&bindingMysqls).Error + DB.Model(&BindingMysql{}).WithContext(ctx). + Where("group_id = ? and platform = 0", groupId).Count(&total) + bindings := make([]entity.Binding, 0) + for _, bindingMysql := range bindingMysqls { + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + bindings = append(bindings, convertBindingMysqlToBinding(bindingMysql)) + } + return bindings, int(total), err +} + +func (b BindingByMysqlRepo) AppendApps(ctx context.Context, bindingId string, apps []entity.AppInfo) error { + for _, app := range apps { + linkApp := LinkAppInfo{ + BindingId: bindingId, + AppId: app.AppID, + AssociatedAt: app.AssociatedAt, + AssociatedBy: app.AssociatedBy, + } + DB.Model(&LinkAppInfo{}).Create(&linkApp) + } + return nil +} + +func (b BindingByMysqlRepo) RemoveApps(ctx context.Context, bindingId string, appIds []string) error { + err := DB.Where("binding_id = ? AND app_id IN ?", bindingId, appIds).Delete(&LinkAppInfo{}).Error + if err != nil { + log.Errorf("RemoveApps delete binding:%s LinkAppInfo err:%s", bindingId, err.Error()) + } else { + log.Infof("RemoveApps delete binding:%s LinkAppInfo succ", bindingId) + } + return err +} + +func (b BindingByMysqlRepo) UpdateByBindId(ctx context.Context, bindingId string, bind *entity.Binding) error { + info := convertBindingToBindingMysql(bind) + + data := make(map[string]interface{}) + data["name"] = info.Name + data["cooperate_status_value"] = info.CooperateStatusValue + data["cooperate_status_reason"] = info.CooperateStatusReason + data["cooperate_status_last_updated"] = info.CooperateStatusLastUpdated + data["cooperate_status_modified_by"] = info.CooperateStatusModifiedBy + data["cooperate_valid_status_reson"] = info.CooperateValidStatusReason + data["cooperate_valid_status_last_updated"] = info.CooperateValidStatusLastUpdated + data["cooperate_valid_status_modified_by"] = info.CooperateValidStatusModifiedBy + data["cooperate_invalid_status_reson"] = info.CooperateInvalidStatusReason + data["cooperate_invalid_status_last_updated"] = info.CooperateInvalidStatusLastUpdated + data["cooperate_invalid_status_modified_by"] = info.CooperateInvalidStatusModifiedBy + data["owner"] = info.Owner + data["expire"] = info.Expire + data["api_server"] = info.ApiServer + //DB.Delete(&BundleInfo{}, "binding_id=?", bindingId) + //DB.Delete(&LinkAppInfo{}, "binding_id=?", bindingId) + err := DB.Where("binding_id=?", bindingId).Delete(&BundleInfo{}).Error + if err != nil { + log.Errorf("UpdateByBindId delete binding:%s BundleInfo err:%s", bindingId, err.Error()) + } else { + log.Infof("UpdateByBindId delete binding:%s BundleInfo succ", bindingId) + } + err = DB.Where("binding_id=?", bindingId).Delete(&LinkAppInfo{}).Error + if err != nil { + log.Errorf("UpdateByBindId delete binding:%s LinkAppInfo err:%s", bindingId, err.Error()) + } else { + log.Infof("UpdateByBindId delete binding:%s LinkAppInfo succ", bindingId) + } + for _, v := range info.AppInfos { + DB.Model(&LinkAppInfo{}).Create(&v) + } + for _, v := range info.BundleInfos { + DB.Model(&BundleInfo{}).Create(&v) + } + + return DB.Model(&BindingMysql{}).Where("binding_id=?", bindingId).Updates(data).Error +} + +func (b BindingByMysqlRepo) UpdateExpire(ctx context.Context, bindingId string, expire int64) error { + return DB.WithContext(ctx).Model(&sql.AppVersion{}).Where("binding_id=? ", bindingId).Update("expire", expire).Error +} + +func (b BindingByMysqlRepo) UpdateBindingInfo(ctx context.Context, bindingId string, info map[string]interface{}, platform int) error { + if platform == entity.BINGING_PLATFORM_OPER { + query := "binding_id = ? " + args := []interface{}{bindingId} + err := DB.Model(&BindingMysqlV2{}).Debug(). + Where(query, args...). + Updates(info).Error + if err != nil { + return err + } + query = "from_binding_id = ? " + args = []interface{}{bindingId} + return DB.Model(&BindingMysqlV2{}).Debug(). + Where(query, args...). + Updates(info).Error + + } else { + query := "binding_id = ? " + args := []interface{}{bindingId} + return DB.Model(&BindingMysqlV2{}).Debug(). + Where(query, args...). + Updates(info).Error + } +} + +func (b BindingByMysqlRepo) UpdateBindingGroupName(ctx context.Context, groupId, groupName string) error { + info := make(map[string]interface{}) + info["group_name"] = groupName + query := "group_id = ? " + args := []interface{}{groupId} + return DB.Model(&BindingMysqlV2{}).Debug(). + Where(query, args...). + Updates(info).Error +} + +func (b BindingByMysqlRepo) BundleIdCount(ctx context.Context, groupId string) (int, error) { + if groupId == "" { + query := "is_forbidden = 0" + args := make([]interface{}, 0) + var count int64 + err := DB.Model(&BundleInfo{}).Where(query, args...).Count(&count).Error + return int(count), err + } else { + query := "group_id = ? and is_forbidden = 0" + args := []interface{}{groupId} + var count int64 + err := DB.Model(&BundleInfo{}).Where(query, args...).Count(&count).Error + return int(count), err + } +} + +func (b BindingByMysqlRepo) GetBundleByGroupIdAndBundleId(ctx context.Context, groupId string, bundleId string) (*entity.Binding, error) { + bindingMysql := BindingMysql{} + err := DB.Model(&BindingMysql{}). + Select("binding.*").Joins("left join bundle_info on binding.binding_id = bundle_info.binding_id"). + Where("binding.group_id = ? and binary bundle_info.bundle_id = ?", []interface{}{groupId}, []interface{}{bundleId}). + First(&bindingMysql).Error + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + binding := convertBindingMysqlToBinding(bindingMysql) + + return &binding, err + + //query := "group_id = ? and bundle_id = ?" + //args := []interface{}{groupId, bundleId} + // + //bundleInfoMysql := BundleInfo{} + //err := DB.Model(&BundleInfo{}).Where(query, args...).First(&bundleInfoMysql).Error + //if err != nil { + // return nil, err + //} + // + //return b.GetInfo(ctx, bundleInfoMysql.BindingId) +} + +func (b BindingByMysqlRepo) GetbundlesByBundleId(ctx context.Context, bundleId string) (*entity.Binding, error) { + query := "binary bundle_id = ?" + args := []interface{}{bundleId} + + bundleInfoMysql := BundleInfo{} + err := DB.Model(&BundleInfo{}).Where(query, args...).First(&bundleInfoMysql).Error + if err != nil { + return nil, err + } + + return b.GetInfo(ctx, bundleInfoMysql.BindingId) +} + +type BindingsResult struct { + BindingId string `json:"bindingId" gorm:"column:binding_id"` +} + +func (b BindingByMysqlRepo) GetBindingsBySearch(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, searchFields string, cooperateStatus string, platform int) ([]entity.Binding, int, error) { + log.Infof("ListBindings req,groupId:[%s],searchText:[%s],pageNo:[%d],pageSize:[%d]", searchText, pageNo, pageSize) + var sortColumn string + switch sort { + case "-created": + sortColumn = "binding.created_info_at DESC" //按创建时间排序 + case "-expire": + sortColumn = "binding.expire DESC" //按过期时间倒序排序 + case "expire": + sortColumn = "binding.expire ASC" //按过期时间正序排序 + default: + sortColumn = "binding.created_info_at DESC" //按创建时间倒序排序 + } + list := make([]BindingMysql, 0) + var total int64 + if searchText == "" { + if cooperateStatus != "all" { + query := "cooperate_status_value = ?" + queryList := []interface{}{cooperateStatus} + switch platform { + case entity.BINGING_PLATFORM_OPER: + query += " AND platform = ? and group_id = ?" + queryList = append(queryList, platform) + queryList = append(queryList, "") + case entity.BINGING_PLATFORM_ORGAN: + query += " AND platform = ?" + queryList = append(queryList, platform) + default: + query += " AND ( ( platform = ? AND group_id = ? ) OR ( platform = ? ) )" + queryList = append(queryList, entity.BINGING_PLATFORM_OPER) + queryList = append(queryList, "") + queryList = append(queryList, entity.BINGING_PLATFORM_ORGAN) + } + err := DB. + Where(query, queryList...). + //Preload("BundleInfos"). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + err = DB.Model(&BindingMysql{}). + Where(query, queryList...). + Count(&total).Error + if err != nil { + return nil, 0, err + } + } else { + query := "" + queryList := []interface{}{} + switch platform { + case entity.BINGING_PLATFORM_OPER: + query += "platform = ? and group_id = ?" + queryList = append(queryList, platform) + queryList = append(queryList, "") + case entity.BINGING_PLATFORM_ORGAN: + query += "platform = ?" + queryList = append(queryList, platform) + default: + query += "( platform = ? AND group_id = ? ) OR ( platform = ? )" + queryList = append(queryList, entity.BINGING_PLATFORM_OPER) + queryList = append(queryList, "") + queryList = append(queryList, entity.BINGING_PLATFORM_ORGAN) + } + err := DB. + Where(query, queryList...). + //Preload("BundleInfos"). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + err = DB.Model(&BindingMysql{}). + Where(query, queryList...). + Count(&total).Error + if err != nil { + return nil, 0, err + } + } + } else { + + query := "" + queryList := []interface{}{} + if cooperateStatus != "all" { + query = "(binding.name LIKE ? OR binding.group_name LIKE ? OR bundle_info.bundle_id LIKE ?) AND binding.cooperate_status_value = ? " + s := genLike(searchText) + queryList = []interface{}{s, s, s, cooperateStatus} + switch platform { + case entity.BINGING_PLATFORM_OPER: + query += " AND binding.platform = ? and binding.group_id = ?" + queryList = append(queryList, platform) + queryList = append(queryList, "") + case entity.BINGING_PLATFORM_ORGAN: + query += " AND binding.platform = ?" + queryList = append(queryList, platform) + default: + query += " AND ( ( binding.platform = ? AND binding.group_id = ? ) OR ( binding.platform = ? ) )" + queryList = append(queryList, entity.BINGING_PLATFORM_OPER) + queryList = append(queryList, "") + queryList = append(queryList, entity.BINGING_PLATFORM_ORGAN) + } + } else { + query = "(binding.name LIKE ? OR binding.group_name LIKE ? OR bundle_info.bundle_id LIKE ?) " + s := genLike(searchText) + queryList = []interface{}{s, s, s} + switch platform { + case entity.BINGING_PLATFORM_OPER: + query += " AND binding.platform = ? and binding.group_id = ?" + queryList = append(queryList, platform) + queryList = append(queryList, "") + case entity.BINGING_PLATFORM_ORGAN: + query += " AND binding.platform = ?" + queryList = append(queryList, platform) + default: + query += " AND ( ( binding.platform = ? AND binding.group_id = ? ) OR ( binding.platform = ? ) )" + queryList = append(queryList, entity.BINGING_PLATFORM_OPER) + queryList = append(queryList, "") + queryList = append(queryList, entity.BINGING_PLATFORM_ORGAN) + } + } + resultArr := []BindingsResult{} + /*err := mysql.MysqlDB.Table(dao.SDK_DATA_OPEN_INFO_C_NAME).Debug().Select("sum(app_open_count) as app_open_count, sum(total_app_stay_time) as total_app_stay_time, sum(app_close_count) as app_close_count, day_time"). + Where(query, args...).Group("day_time").Order("day_time"). + Scan(&resultArr).Error*/ + + err := DB.Debug().Model(&BindingMysql{}). + Joins("LEFT JOIN `bundle_info` ON `binding`.`binding_id` = `bundle_info`.`binding_id` "). + Select("binding.binding_id"). + Where(query, queryList...). + Group("binding.binding_id"). + Scan(&resultArr).Error + + /*err := DB.Debug().Model(&BindingMysql{}).Preload("BundleInfos"). + Joins("LEFT JOIN `bundle_info` `BundleInfos` ON `binding`.`binding_id` = `BundleInfos`.`binding_id` "). + Select("binding.*,GROUP_CONCAT(BundleInfos.bundle_id) AS `bundle_ids`"). + Group("binding.binding_id"). + Having(query, queryList...). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error*/ + if err != nil { + return nil, 0, err + } + + fmt.Printf("resultArr = %s\n", utility.InterfaceToJsonString(resultArr)) + /*t := DB.Model(&BindingMysql{}).Joins("LEFT JOIN `bundle_info` `BundleInfos` ON `binding`.`binding_id` = `BundleInfos`.`binding_id`"). + Select("binding.*,GROUP_CONCAT(BundleInfos.bundle_id) AS `bundle_ids`"). + Group("binding.binding_id"). + Having(query, queryList...) + err = DB.Debug().Table("(?) t", t).Count(&total).Error*/ + + t := DB.Model(&BindingMysql{}).Joins("LEFT JOIN `bundle_info` ON `binding`.`binding_id` = `bundle_info`.`binding_id`"). + Select("binding.binding_id"). + Where(query, queryList...). + Group("binding.binding_id") + err = DB.Debug().Table("(?) t", t).Count(&total).Error + if err != nil { + return nil, 0, err + } + + bindingIds := []string{} + for _, id := range resultArr { + bindingIds = append(bindingIds, id.BindingId) + } + query = "binding_id in (?)" + queryList = []interface{}{bindingIds} + + err = DB.Model(&BindingMysql{}). + //Preload("BundleInfos"). + Where(query, queryList...). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + } + + bindings := make([]entity.Binding, 0) + for _, v := range list { + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, v.BindingID) + if len(linkAppInfos) > 0 { + v.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + v.BundleInfos = bundleInfos + } + bindings = append(bindings, convertBindingMysqlToBinding(v)) + } + return bindings, int(total), nil +} + +func (b BindingByMysqlRepo) GetBindingsByAppId(ctx context.Context, pageSize int, pageNo int, appId string) ([]entity.Binding, int, error) { + list := make([]BindingMysql, 0) + var total int64 + + err := DB.Debug().Model(&BindingMysql{}). + //Preload("BundleInfos").Preload("AppInfos"). + Where("link_app_infos.app_id = ?", appId). + Select("DISTINCT(binding.id), binding.*"). + Joins("left join bundle_info on binding.binding_id = bundle_info.binding_id"). + Joins("left join link_app_infos on binding.binding_id = link_app_infos.binding_id"). + Order("binding.created_info_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + + err = DB.Debug().Model(&BindingMysql{}). + //Preload("BundleInfos").Preload("AppInfos"). + Where("link_app_infos.app_id = ?", appId). + Select("DISTINCT(binding.id), binding.*"). + Joins("left join bundle_info on binding.binding_id = bundle_info.binding_id"). + Joins("left join link_app_infos on binding.binding_id = link_app_infos.binding_id"). + Order("binding.created_info_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Count(&total).Error + if err != nil { + return nil, 0, err + } + + bindings := make([]entity.Binding, 0) + for _, v := range list { + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, v.BindingID) + if len(linkAppInfos) > 0 { + v.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + v.BundleInfos = bundleInfos + } + bindings = append(bindings, convertBindingMysqlToBinding(v)) + } + return bindings, int(total), nil +} + +func (b BindingByMysqlRepo) GetDevListBinding(ctx context.Context, pageSize int, pageNo int, sort string, searchText string, pullType string, groupId string, bindStatus string, platform int) ([]entity.Binding, int, error) { + bindingMysqls := make([]BindingMysql, 0) + var sortColumn string + switch sort { + case "-created": + sortColumn = "created_info_at DESC" //按创建时间排序 + case "-expire": + sortColumn = "expire DESC" //按过期时间倒序排序 + case "expire": + sortColumn = "expire ASC" //按过期时间正序排序 + default: + sortColumn = "created_info_at DESC" //按创建时间倒序排序 + } + + query := "group_id = ? " + args := []interface{}{groupId} + + switch pullType { + case "recently-expire": + beginData := time.Now().UnixNano() / 1e6 + endData := time.Now().AddDate(0, 0, 30).UnixNano() / 1e6 + query = query + "AND expire > ? and expire < ? " + args = append(args, beginData, endData) + } + + switch bindStatus { + case "Valid": + query = query + "AND cooperate_status_value = ? " + args = append(args, entity.StBindValid) + case "Invalid": + query = query + "AND cooperate_status_value = ? " + args = append(args, entity.StBindInvalid) + } + + if searchText != "" { + query += "AND name LIKE ? " + args = append(args, "%"+searchText+"%") + } + + switch platform { + case entity.BINGING_PLATFORM_OPER: + query += "AND platform = ? " + args = append(args, platform) + case entity.BINGING_PLATFORM_ORGAN: + query += "AND platform = ? " + args = append(args, platform) + default: + query += "AND ( ( platform = ? ) OR ( platform = ? ) ) " + args = append(args, entity.BINGING_PLATFORM_OPER) + args = append(args, entity.BINGING_PLATFORM_ORGAN) + } + + var total int64 + err := DB.Model(&BindingMysql{}). + Where(query, args...). + //Preload("BundleInfos"). + //Preload("AppInfos"). + Count(&total). + Order(sortColumn). + Offset((pageNo - 1) * pageSize).Limit(pageSize). + Find(&bindingMysqls).Error + if err != nil { + return nil, 0, err + } + + bindings := make([]entity.Binding, 0) + for _, bindingMysql := range bindingMysqls { + + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, bindingMysql.BindingID) + + if len(linkAppInfos) > 0 { + bindingMysql.AppInfos = linkAppInfos + } + + if len(bundleInfos) > 0 { + bindingMysql.BundleInfos = bundleInfos + } + + bindings = append(bindings, convertBindingMysqlToBinding(bindingMysql)) + } + + return bindings, int(total), err +} + +func (b BindingByMysqlRepo) GetBundleInfoAndLinkAppInfo(ctx context.Context, bindingId string) ([]BundleInfo, []LinkAppInfo, error) { + tmpQuery := "binding_id = ?" + tmpArgs := []interface{}{bindingId} + + var bundleInfos []BundleInfo + err := DB.Model(&BundleInfo{}).Where(tmpQuery, tmpArgs...).Find(&bundleInfos).Error + + var linkAppInfos []LinkAppInfo + err = DB.Model(&LinkAppInfo{}).Where(tmpQuery, tmpArgs...).Find(&linkAppInfos).Error + + return bundleInfos, linkAppInfos, err +} + +func (b BindingByMysqlRepo) GetBindingBySdkKey(ctx context.Context, sdkKey string) (*entity.Binding, error) { + query := "sdk_key = ?" + args := []interface{}{sdkKey} + + bundleInfoMysql := BundleInfo{} + err := DB.Model(&BundleInfo{}).Where(query, args...).First(&bundleInfoMysql).Error + if err != nil { + return nil, err + } + + return b.GetInfo(ctx, bundleInfoMysql.BindingId) +} + +func (b BindingByMysqlRepo) ListAutoBindAppBinding(ctx context.Context, groupId string) ([]string, error) { + query := "auto_bind = ? and platform = ? and group_id = ?" + args := []interface{}{1, entity.BINGING_PLATFORM_OPER, groupId} + + bindingMysqls := make([]BindingMysql, 0) + err := DB.Model(&BindingMysql{}).Where(query, args...).Find(&bindingMysqls).Error + if err != nil { + return nil, err + } + result := []string{} + for _, binding := range bindingMysqls { + result = append(result, binding.BindingID) + } + return result, nil +} + +func (b BindingByMysqlRepo) ListCopyOperBinding(ctx context.Context, bindingId string) ([]string, []entity.Binding, error) { + query := "platform = ? and from_binding_id = ?" + args := []interface{}{entity.BINGING_PLATFORM_OPER, bindingId} + + bindingMysqls := make([]BindingMysql, 0) + err := DB.Model(&BindingMysql{}).Where(query, args...).Find(&bindingMysqls).Error + if err != nil { + return nil, nil, err + } + bindings := make([]entity.Binding, 0) + result := []string{} + for _, binding := range bindingMysqls { + result = append(result, binding.BindingID) + bindings = append(bindings, convertBindingMysqlToBinding(binding)) + } + return result, bindings, nil +} + +func (b BindingByMysqlRepo) ListBindings(ctx context.Context, groupId string, searchText string, pageNo int, pageSize int) ([]entity.Binding, int, error) { + log.Infof("ListBindings req,groupId:[%s],searchText:[%s],pageNo:[%d],pageSize:[%d]", searchText, groupId, pageNo, pageSize) + var ( + sortColumn = "binding.created_info_at DESC" + list = make([]BindingMysql, 0) + total int64 + ) + + if searchText == "" { + if groupId != "" { + err := DB.Debug(). + Where("binding.group_id=?", groupId). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + err = DB.Model(&BindingMysql{}). + Where("binding.group_id=?", groupId). + Count(&total).Error + if err != nil { + return nil, 0, err + } + } else { + err := DB.Debug(). + Where("binding.group_id <> ?", ""). + //Preload("BundleInfos"). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + err = DB.Model(&BindingMysql{}). + Where("binding.group_id <> ?", ""). + Count(&total).Error + if err != nil { + return nil, 0, err + } + } + } else { + query := "(binding.name LIKE ? OR binding.group_name LIKE ? OR bundle_ids LIKE ?) " + s := genLike(searchText) + queryList := []interface{}{s, s, s} + if groupId != "" { + query += " AND binding.group_id=? " + queryList = append(queryList, groupId) + } else { + query += " AND binding.group_id <> ? " + queryList = append(queryList, "") + } + + err := DB.Debug().Model(&BindingMysql{}). + //Select("select * from binding"). + //Preload("BundleInfos"). + Joins("LEFT JOIN `bundle_info` ON `binding`.`binding_id` = `bundle_info`.`binding_id` "). + Where("binding.name LIKE ? OR binding.group_name LIKE ? OR bundle_info.bundle_id LIKE ?", s, s, s). + //Select("binding.*,GROUP_CONCAT(bundle_id.bundle_id) AS `bundle_ids`"). + Group("binding.id"). + //Having(query, queryList...). + Order(sortColumn). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return nil, 0, err + } + t := DB.Model(&BindingMysql{}). + Joins("LEFT JOIN `bundle_info` ON `binding`.`binding_id` = `bundle_info`.`binding_id`"). + //Select("binding.*,GROUP_CONCAT(bundle_info.bundle_id) AS `bundle_ids`"). + Group("binding.id"). + Where("binding.name LIKE ? OR binding.group_name LIKE ? OR bundle_info.bundle_id LIKE ?", s, s, s) + //Having(query, queryList...) + err = DB.Debug().Table("(?) t", t).Count(&total).Error + if err != nil { + return nil, 0, err + } + } + + bindings := make([]entity.Binding, 0) + for _, v := range list { + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, v.BindingID) + if len(linkAppInfos) > 0 { + v.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + v.BundleInfos = bundleInfos + } + bindings = append(bindings, convertBindingMysqlToBinding(v)) + } + return bindings, int(total), nil + // + //db := DB.Model(&BindingMysql{}) + //if groupId != "" { + // db = db.Where("binding.group_id = ?", groupId) + //} + // + //if searchText != "" { + // db = db.Where("binding.name LIKE ?", searchText). + // Or("binding.group_name LIKE ?", searchText). + // Or("bundle_info.bundle_id LIKE ?", searchText) + //} + // + //var total int + //bindingMysqls := make([]BindingMysql, 0) + //db = db. + // Select("DISTINCT(binding.id), binding.*"). + // Joins("LEFT JOIN bundle_info on binding.binding_id = bundle_info.binding_id"). + // Joins("LEFT JOIN link_app_infos on binding.binding_id = link_app_infos.binding_id"). + // Find(&bindingMysqls) + //total = len(bindingMysqls) + // + //err := db.Order("created_info_at desc").Offset((pageNo - 1) * pageSize).Limit(pageSize).Find(&bindingMysqls).Error + //if err != nil { + // return nil, 0, err + //} + //bindings := make([]entity.Binding, 0) + //for _, bindingMysql := range bindingMysqls { + // bindings = append(bindings, convertBindingMysqlToBinding(bindingMysql)) + //} + //return bindings, int(total), nil +} + +func (b BindingByMysqlRepo) GetAllAssBinds(ctx context.Context, appId string) ([]entity.Binding, error) { + //bindings := make([]BindingMongo, 0) + //err := bindingTable.OnlyGetAll(ctx, bson.M{"app_infos.app_id": appId}, []string{}, &bindings) + //if err != nil { + // return nil, err + //} + //result := make([]entity.Binding, 0) + //for _, bindingMongo := range bindings { + // result = append(result, convertBindingMongoToBinding(bindingMongo)) + //} + //return result, nil + list := make([]BindingMysql, 0) + err := DB.Debug().Model(&BindingMysql{}). + //Preload("BundleInfos").Preload("AppInfos"). + Where("link_app_infos.app_id = ?", appId). + Select("DISTINCT(binding.id), binding.*"). + Joins("left join bundle_info on binding.binding_id = bundle_info.binding_id"). + Joins("left join link_app_infos on binding.binding_id = link_app_infos.binding_id"). + Find(&list).Error + if err != nil { + return nil, err + } + bindings := make([]entity.Binding, 0) + for _, v := range list { + bundleInfos, linkAppInfos, _ := b.GetBundleInfoAndLinkAppInfo(ctx, v.BindingID) + if len(linkAppInfos) > 0 { + v.AppInfos = linkAppInfos + } + if len(bundleInfos) > 0 { + v.BundleInfos = bundleInfos + } + bindings = append(bindings, convertBindingMysqlToBinding(v)) + } + return bindings, nil +} + +func (b BindingByMysqlRepo) UpdateRelatedBindingCooperate(ctx context.Context, bindingId string, status entity.Status, specificStatus entity.SpecificStatus, cooperate bool) error { + query := "from_binding_id = ? and platform = ?" + args := []interface{}{bindingId, entity.BINGING_PLATFORM_OPER} + params := map[string]interface{}{} + if cooperate { + params = map[string]interface{}{ + "cooperate_status_value": status.Value, + "cooperate_status_last_updated": status.LastUpdated, + "cooperate_status_modified_by": status.ModifiedBy, + "cooperate_valid_status_last_updated": specificStatus.LastUpdated, + "cooperate_valid_status_modified_by": specificStatus.ModifiedBy, + } + } else { + params = map[string]interface{}{ + "cooperate_status_value": status.Value, + "cooperate_status_last_updated": status.LastUpdated, + "cooperate_status_modified_by": status.ModifiedBy, + "cooperate_invalid_status_last_updated": specificStatus.LastUpdated, + "cooperate_invalid_status_modified_by": specificStatus.ModifiedBy, + } + } + err := DB.Model(&BindingMysqlV2{}).Debug(). + Where(query, args...). + Updates(params).Error + if err != nil { + return err + } + return nil +} + +func (b BindingByMysqlRepo) UpdateBundleIdIsForbidden(ctx context.Context, bundleId string) error { + query := "binary bundle_id= ?" + args := []interface{}{bundleId} + + params := map[string]interface{}{ + "is_forbidden": 1, + } + err := DB.Model(&BundleInfo{}).Debug(). + Where(query, args...). + Updates(params).Error + if err != nil { + return err + } + return nil +} + +func (b BindingByMysqlRepo) UpdateBundleIdPlatform(ctx context.Context, bundleId, platform string) error { + query := "binary bundle_id= ?" + args := []interface{}{bundleId} + + params := map[string]interface{}{ + "remark": platform, + } + err := DB.Model(&BundleInfo{}).Debug(). + Where(query, args...). + Updates(params).Error + if err != nil { + return err + } + return nil +} + +func (b BindingByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound || errors.Is(err, gorm.ErrRecordNotFound) +} + +func (b BindingByMysqlRepo) UpdateBundleBindingId(ctx context.Context, bundleId, bindingId, toBindingId string) error { + query := "binding_id = ? and bundle_id= ?" + args := []interface{}{bindingId, bundleId} + + params := map[string]interface{}{ + "binding_id": toBindingId, + } + err := DB.Model(&BundleInfo{}).Debug(). + Where(query, args...). + Updates(params).Error + if err != nil { + return err + } + return nil +} + +func convertBindingMysqlToBinding(info BindingMysql) entity.Binding { + result := entity.Binding{} + + bundleInfos := make([]entity.BundleInfo, 0) + for _, v := range info.BundleInfos { + item := entity.BundleInfo{ + //Id: v.Id, + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + IsReview: v.IsReview, + } + + bundleInfos = append(bundleInfos, item) + } + + createInfo := entity.CreatedInfo{ + CreatedBy: info.CreatedInfoBy, + CreatedAt: info.CreatedInfoAt, + CreatedAccount: info.CreatedInfoAccount, + } + + cooperateStatus := entity.Status{ + Value: info.CooperateStatusValue, + Reason: info.CooperateStatusReason, + LastUpdated: info.CooperateStatusLastUpdated, + ModifiedBy: info.CooperateStatusModifiedBy, + } + + cooperateValidStatus := entity.SpecificStatus{ + Reason: info.CooperateValidStatusReason, + LastUpdated: info.CooperateValidStatusLastUpdated, + ModifiedBy: info.CooperateValidStatusModifiedBy, + } + + cooperateInvalidStatus := entity.SpecificStatus{ + Reason: info.CooperateInvalidStatusReason, + LastUpdated: info.CooperateInvalidStatusLastUpdated, + ModifiedBy: info.CooperateInvalidStatusModifiedBy, + } + + //var appInfos []entity.AppInfo + //json.Unmarshal([]byte(bindingMysql.AppInfos), &appInfos) + + result.BindingID = info.BindingID + result.Name = info.Name + result.BundleInfos = bundleInfos + result.CreatedInfo = createInfo + result.GroupID = info.GroupID + result.GroupName = info.GroupName + result.CooperateStatus = cooperateStatus + result.CooperateValidStatus = cooperateValidStatus + result.CooperateInvalidStatus = cooperateInvalidStatus + //result.AppInfos = appInfos + result.Owner = info.Owner + result.Expire = info.Expire + result.ApiServer = info.ApiServer + result.AppInfos = make([]entity.AppInfo, 0) + for _, v := range info.AppInfos { + item := entity.AppInfo{ + //Id: v.Id, + AppID: v.AppId, + AssociatedAt: v.AssociatedAt, + AssociatedBy: v.AssociatedBy, + } + result.AppInfos = append(result.AppInfos, item) + } + + result.GroupID = info.GroupID + result.PlatForm = info.PlatForm + result.AutoBind = info.AutoBind + result.HiddenBundle = info.HiddenBundle + result.FromBindingID = info.FromBindingID + return result +} + +func convertBindingToBindingMysql(binding *entity.Binding) BindingMysql { + result := BindingMysql{} + + result.BindingID = binding.BindingID + result.Name = binding.Name + result.CreatedInfoBy = binding.CreatedInfo.CreatedBy + result.CreatedInfoAt = binding.CreatedInfo.CreatedAt + result.CreatedInfoAccount = binding.CreatedInfo.CreatedAccount + result.GroupID = binding.GroupID + result.GroupName = binding.GroupName + result.CooperateStatusValue = binding.CooperateStatus.Value + result.CooperateStatusReason = binding.CooperateStatus.Reason + result.CooperateStatusLastUpdated = binding.CooperateStatus.LastUpdated + result.CooperateStatusModifiedBy = binding.CooperateStatus.ModifiedBy + result.CooperateValidStatusReason = binding.CooperateValidStatus.Reason + result.CooperateValidStatusLastUpdated = binding.CooperateValidStatus.LastUpdated + result.CooperateValidStatusModifiedBy = binding.CooperateValidStatus.ModifiedBy + result.CooperateInvalidStatusReason = binding.CooperateInvalidStatus.Reason + result.CooperateInvalidStatusLastUpdated = binding.CooperateInvalidStatus.LastUpdated + result.CooperateInvalidStatusModifiedBy = binding.CooperateInvalidStatus.ModifiedBy + result.AppInfos = make([]LinkAppInfo, 0) + for _, v := range binding.AppInfos { + item := LinkAppInfo{ + //Id: v.Id, + BindingId: binding.BindingID, + AppId: v.AppID, + AssociatedAt: v.AssociatedAt, + AssociatedBy: v.AssociatedBy, + } + result.AppInfos = append(result.AppInfos, item) + } + result.BundleInfos = make([]BundleInfo, 0) + for _, v := range binding.BundleInfos { + item := BundleInfo{ + //Id: v.Id, + BindingId: binding.BindingID, + GroupID: binding.GroupID, + BundleID: v.BundleID, + Remark: v.Remark, + SDKKey: v.SDKKey, + SDKID: v.SDKID, + IsFirstCreate: v.IsFirstCreate, + CreatedAt: v.CreatedAt, + CreatedAccount: v.CreatedAccount, + CreatedBy: v.CreatedBy, + IsForbidden: v.IsForbidden, + IsReview: v.IsReview, + } + result.BundleInfos = append(result.BundleInfos, item) + } + result.Owner = binding.Owner + result.Expire = binding.Expire + result.ApiServer = binding.ApiServer + result.GroupID = binding.GroupID + result.PlatForm = binding.PlatForm + result.AutoBind = binding.AutoBind + result.HiddenBundle = binding.HiddenBundle + result.FromBindingID = binding.FromBindingID + return result +} + +func convertBindingMysqlToBindingMysqlV2(binding *BindingMysql) BindingMysqlV2 { + result := BindingMysqlV2{} + + result.BindingID = binding.BindingID + result.Name = binding.Name + result.CreatedInfoBy = binding.CreatedInfoBy + result.CreatedInfoAt = binding.CreatedInfoAt + result.CreatedInfoAccount = binding.CreatedInfoAccount + result.GroupID = binding.GroupID + result.GroupName = binding.GroupName + result.CooperateStatusValue = binding.CooperateStatusValue + result.CooperateStatusReason = binding.CooperateStatusReason + result.CooperateStatusLastUpdated = binding.CooperateStatusLastUpdated + result.CooperateStatusModifiedBy = binding.CooperateStatusModifiedBy + result.CooperateValidStatusReason = binding.CooperateValidStatusReason + result.CooperateValidStatusLastUpdated = binding.CooperateValidStatusLastUpdated + result.CooperateValidStatusModifiedBy = binding.CooperateValidStatusModifiedBy + result.CooperateInvalidStatusReason = binding.CooperateInvalidStatusReason + result.CooperateInvalidStatusLastUpdated = binding.CooperateInvalidStatusLastUpdated + result.CooperateInvalidStatusModifiedBy = binding.CooperateInvalidStatusModifiedBy + result.Owner = binding.Owner + result.Expire = binding.Expire + result.ApiServer = binding.ApiServer + result.GroupID = binding.GroupID + result.PlatForm = binding.PlatForm + result.AutoBind = binding.AutoBind + result.HiddenBundle = binding.HiddenBundle + result.FromBindingID = binding.FromBindingID + return result +} + +func convertBundleInfoToBundleInfoMysql(bindId, groupId string, bundleInfo entity.BundleInfo) BundleInfo { + result := BundleInfo{} + + result.BindingId = bindId + result.GroupID = groupId + result.BundleID = bundleInfo.BundleID + result.Remark = bundleInfo.Remark + result.SDKKey = bundleInfo.SDKKey + result.SDKID = bundleInfo.SDKID + result.IsFirstCreate = bundleInfo.IsFirstCreate + result.CreatedAt = bundleInfo.CreatedAt + result.CreatedAccount = bundleInfo.CreatedAccount + result.CreatedBy = bundleInfo.CreatedBy + result.IsForbidden = bundleInfo.IsForbidden + return result +} + +func convertBundleInfoMysqlToBundleInfo(bundleInfoMysql BundleInfo) entity.BundleInfo { + result := entity.BundleInfo{} + + result.BundleID = bundleInfoMysql.BundleID + result.Remark = bundleInfoMysql.Remark + result.SDKKey = bundleInfoMysql.SDKKey + result.SDKID = bundleInfoMysql.SDKID + result.IsFirstCreate = bundleInfoMysql.IsFirstCreate + result.CreatedAt = bundleInfoMysql.CreatedAt + result.CreatedAccount = bundleInfoMysql.CreatedAccount + result.CreatedBy = bundleInfoMysql.CreatedBy + + return result +} diff --git a/infrastructure/db/repo/mysql/bundle.go b/infrastructure/db/repo/mysql/bundle.go new file mode 100644 index 0000000..6ec8b52 --- /dev/null +++ b/infrastructure/db/repo/mysql/bundle.go @@ -0,0 +1,214 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + + "gorm.io/gorm" +) + +var _ repository.IBundleRepo = new(BundleByMysqlRepo) + +type BundleByMysqlRepo struct { +} + +type BundleMysql struct { + Id uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + BundleID string `json:"bundleId" gorm:"column:bundle_id;type:varchar(512);default:'';comment:bundleId"` + Remark string `json:"remark" gorm:"column:remark;type:varchar(512);default:'';comment:类型"` + SDKKey string `json:"SDKKey" gorm:"column:sdk_key;type:varchar(512);default:'';comment:sdkkey"` + SDKID string `json:"SDKID" gorm:"column:sdk_id;type:varchar(64);default:'';comment:secert"` + IsFirstCreate bool `json:"isFirstCreate" gorm:"column:is_first_create;type:bool;default:false;comment:是否第一次创建"` //是否第一次创建 + CreatedAt int64 `json:"createdAt" gorm:"column:created_at;type:BIGINT(16);default:0;comment:创建时间"` + CreatedAccount string `json:"createdAccount" bson:"created_account" gorm:"column:created_account;type:varchar(64);default:'';comment:创建账号"` + CreatedBy string `json:"createdBy" bson:"created_by" gorm:"column:created_by;type:varchar(64);default:'';comment:创建人"` + IsForbidden int `json:"isForbidden" bson:"is_forbidden" gorm:"column:is_forbidden;type:tinyint(1);default:0;comment:是否禁用"` //是否禁用 0:可用 1:禁用 +} + +func (BundleMysql) TableName() string { + return "bundle" +} + +func (b BundleByMysqlRepo) Insert(ctx context.Context, bundles []entity.Bundle) error { + return DB.Transaction(func(tx *gorm.DB) error { + var err error + for _, v := range bundles { + info := convertBundleToBundleMysql(v) + err = DB.WithContext(ctx).Model(&BundleMysql{}).Debug().Create(&info).Error + } + return err + }) +} + +func (b BundleByMysqlRepo) GetListByBundleId(ctx context.Context, ids []string, pageNo int, pageSize int) (int, []entity.Bundle, error) { + query := "binary bundle_id in ?" + args := []interface{}{ids} + + bundleMysqls := make([]BundleMysql, 0) + err := DB.Model(&BundleMysql{}).Where(query, args...).Offset((pageNo - 1) * pageSize). + Limit(pageSize).Find(&bundleMysqls).Error + if b.NotFound(err) { + return 0, []entity.Bundle{}, nil + } + + var count int64 + err = DB.Model(&BundleMysql{}).Count(&count).Error + if err != nil { + return 0, []entity.Bundle{}, nil + } + + bundles := make([]entity.Bundle, 0) + for _, bundleMysql := range bundleMysqls { + bundles = append(bundles, convertBundleMysqlToBundle(bundleMysql)) + } + + return int(count), bundles, err +} + +func (b BundleByMysqlRepo) GetListByBundleIds(ctx context.Context, ids []string) ([]entity.Bundle, error) { + bundles := make([]BundleMysql, 0) + err := DB.WithContext(ctx).Debug(). + Model(&BundleMysql{}). + Where("binary bundle_id IN (?)", ids).Find(&bundles).Error + if err != nil { + if b.NotFound(err) { + return []entity.Bundle{}, nil + } + } + result := make([]entity.Bundle, 0) + for _, v := range bundles { + result = append(result, convertBundleMysqlToBundle(v)) + } + return result, err +} + +func (b BundleByMysqlRepo) ExistBundleId(ctx context.Context, bundleId string) (bool, error) { + var ( + total int64 + err error + ) + err = DB.Model(&BundleMysql{}).Where("binary bundle_id=?", bundleId).Count(&total).Error + if err != nil { + return false, err + } + return total > 0, nil +} + +func (b BundleByMysqlRepo) GetInfoByBundleId(ctx context.Context, bundleId string) (entity.Bundle, error) { + info := BundleMysql{} + err := DB.Debug().Model(&BundleMysql{}).Where("binary bundle_id=?", bundleId).First(&info).Error + if err != nil { + return entity.Bundle{}, err + } + return convertBundleMysqlToBundle(info), err +} + +func (b BundleByMysqlRepo) ListAllBundleInfos(ctx context.Context, searchText string, selectType, pageNo int, pageSize int) (int, []entity.Bundle, error) { + var ( + err error + total int64 + list = make([]BundleMysql, 0) + ) + query := "" + args := []interface{}{} + if searchText != "" { + query += "bundle_id LIKE ? " + args = []interface{}{searchText} + } + if selectType == 1 { + if query == "" { + query += " is_forbidden=? " + } else { + query += " and is_forbidden=? " + + } + args = append(args, 0) + } + if selectType == 2 { + if query == "" { + query += " is_forbidden=? " + } else { + query += " and is_forbidden=? " + + } + args = append(args, 1) + } + /*if searchText != "" { + err = DB.WithContext(ctx).Model(&BundleMysql{}). + Where("bundle_id LIKE ?", genLike(searchText)). + Count(&total). + Order("created_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + }*/ + err = DB.WithContext(ctx).Model(&BundleMysql{}).Debug().Where(query, args...). + Count(&total). + Order("created_at DESC"). + Offset(genOffset(pageNo, pageSize)).Limit(pageSize). + Find(&list).Error + if err != nil { + return 0, nil, err + } + result := make([]entity.Bundle, 0) + for _, v := range list { + temp := v + result = append(result, convertBundleMysqlToBundle(temp)) + } + return int(total), result, nil +} + +func (b BundleByMysqlRepo) AllCount(ctx context.Context) (int, error) { + var total int64 + err := DB.Model(&BundleMysql{}).Where("is_forbidden=?", 0).Count(&total).Error + return int(total), err +} + +func (b BundleByMysqlRepo) UpdateBundleForbidden(ctx context.Context, bundleId string, IsForbidden int) error { + params := map[string]interface{}{ + "is_forbidden": IsForbidden, + } + return DB.Model(&BundleMysql{}).Where("binary bundle_id=?", bundleId).Updates(params).Error +} + +func (b BundleByMysqlRepo) UpdateBundlePlatform(ctx context.Context, bundleId, remark string) error { + params := map[string]interface{}{ + "remark": remark, + } + return DB.Model(&BundleMysql{}).Where("binary bundle_id=?", bundleId).Updates(params).Error +} + +func (b BundleByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertBundleToBundleMysql(bundleInfo entity.Bundle) BundleMysql { + result := BundleMysql{} + + result.BundleID = bundleInfo.BundleID + result.Remark = bundleInfo.Remark + result.SDKKey = bundleInfo.SDKKey + result.SDKID = bundleInfo.SDKID + result.IsFirstCreate = bundleInfo.IsFirstCreate + result.CreatedAt = bundleInfo.CreatedAt + result.CreatedAccount = bundleInfo.CreatedAccount + result.CreatedBy = bundleInfo.CreatedBy + result.IsForbidden = bundleInfo.IsForbidden + + return result +} + +func convertBundleMysqlToBundle(bundleMysql BundleMysql) entity.Bundle { + result := entity.Bundle{} + + result.BundleID = bundleMysql.BundleID + result.Remark = bundleMysql.Remark + result.SDKKey = bundleMysql.SDKKey + result.SDKID = bundleMysql.SDKID + result.IsFirstCreate = bundleMysql.IsFirstCreate + result.CreatedAt = bundleMysql.CreatedAt + result.CreatedAccount = bundleMysql.CreatedAccount + result.CreatedBy = bundleMysql.CreatedBy + result.IsForbidden = bundleMysql.IsForbidden + return result +} diff --git a/infrastructure/db/repo/mysql/link_audit.go b/infrastructure/db/repo/mysql/link_audit.go new file mode 100644 index 0000000..e70f6f8 --- /dev/null +++ b/infrastructure/db/repo/mysql/link_audit.go @@ -0,0 +1,48 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/repository" + + "gorm.io/gorm" +) + +var _ repository.ILinkAuditRepo = new(LinkAuditByMysqlRepo) + +type LinkAuditByMysqlRepo struct { +} + +type LinkAuditMysql struct { + Id uint `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + AuditId string `json:"auditId" gorm:"column:audit_id;type:varchar(64);comment:id"` + Version int `json:"version" gorm:"column:version;type:INT(4);comment:审核序号"` + AppId string `json:"appId" gorm:"column:app_id;type:varchar(64);comment:小程序Id"` + AppName string `json:"appName" gorm:"column:app_name;type:varchar(64);comment:小程序名称"` + BindingId string `json:"bindingId" gorm:"column:binding_id;type:varchar(64);comment:应用Id"` + BindingName string `json:"bindingName" gorm:"column:binding_name;type:varchar(64);comment:应用名称"` + GroupID string `json:"groupId" gorm:"column:group_id;type:varchar(64);comment:企业ID"` + Owner string `json:"owner" gorm:"column:owner;type:varchar(64);comment:所属企业"` + ApplyBy string `json:"applyBy" gorm:"column:apply_by;type:varchar(64);comment:申请人"` + ApplyStatus string `json:"applyStatus" gorm:"column:apply_status;type:varchar(64);comment:审核状态"` + ApplyAt int64 `json:"applyAt" gorm:"column:apply_at;type:BIGINT(16);comment:timestamp"` + AuditBy string `json:"auditBy" gorm:"column:audit_by;type:varchar(64);comment:审核人"` + AuditAt int64 `json:"auditAt" gorm:"column:audit_at;type:BIGINT(16);comment:审核人"` + AssociateStatus string `json:"associateStatus" gorm:"column:associate_status;type:varchar(64);comment:绑定状态"` + Reason string `json:"reason" gorm:"column:reason;type:varchar(64);comment:原因"` +} + +func (LinkAuditMysql) TableName() string { + return "link_audit" +} + +func (l LinkAuditByMysqlRepo) Count(ctx context.Context, appID string, groupId string, bindingID string, stLinkAudit string) (int, error) { + query := "app_id = ? and group_id = ? and binding_id = ? and apply_status = ?" + args := []interface{}{appID, groupId, bindingID, stLinkAudit} + var count int64 + err := DB.Model(&LinkAuditMysql{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (l LinkAuditByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} diff --git a/infrastructure/db/repo/mysql/menu_info.go b/infrastructure/db/repo/mysql/menu_info.go new file mode 100644 index 0000000..0085012 --- /dev/null +++ b/infrastructure/db/repo/mysql/menu_info.go @@ -0,0 +1,201 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto/apiproto" + "finclip-app-manager/domain/repository" + + "gorm.io/gorm" +) + +var _ repository.IMenuInfoRepo = new(MenuInfoByMysqlRepo) + +type MenuInfoByMysqlRepo struct { +} + +type MenuInfoMysql struct { + Id uint `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + TraceId string `json:"traceId" gorm:"column:trace_id;type:varchar(64);comment:唯一Id"` + Name string `json:"name" gorm:"column:name;type:varchar(64);comment:名称"` + InfoId string `json:"infoId" gorm:"column:info_id;type:varchar(64);comment:id"` + ImageUrl string `json:"imageUrl" gorm:"column:image_url;type:varchar(256);comment:图片地址"` + SortNum int `json:"sortNum" gorm:"column:sort_num;type:INT(4);comment:排序"` + CreateTime int64 `json:"createTime" gorm:"column:create_time;type:BIGINT(16);comment:创建时间"` + UpdateTime int64 `json:"updateTime" gorm:"column:update_time;type:BIGINT(16);comment:更新时间"` + UpdateOperator string `json:"updateOperator" gorm:"column:update_operator;type:varchar(64);comment:更新人"` +} + +func (MenuInfoMysql) TableName() string { + return "menu_info" +} + +func (b MenuInfoByMysqlRepo) GetInfoByTraceId(ctx context.Context, id string) (*entity.MenuInfo, error) { + query := "trace_id = ?" + args := []interface{}{id} + + menuInfoMysql := MenuInfoMysql{} + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).First(&menuInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertMenuInfoMysqlToMenuInfo(menuInfoMysql) + return &result, err +} + +func (b MenuInfoByMysqlRepo) GetAllMenuList(ctx context.Context, sort []string) ([]entity.MenuInfo, int, error) { + query := "" + args := []interface{}{} + + menuInfoMysqls := make([]MenuInfoMysql, 0) + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Order("sort_num").Find(&menuInfoMysqls).Error + if b.NotFound(err) { + return []entity.MenuInfo{}, 0, nil + } + + var count int64 + err = DB.Model(&MenuInfoMysql{}).Count(&count).Error + if err != nil { + return []entity.MenuInfo{}, 0, nil + } + + menuInfos := make([]entity.MenuInfo, 0) + for _, menuInfoMysql := range menuInfoMysqls { + menuInfos = append(menuInfos, convertMenuInfoMysqlToMenuInfo(menuInfoMysql)) + } + + return menuInfos, int(count), err +} + +func (b MenuInfoByMysqlRepo) Add(ctx context.Context, info *entity.MenuInfo) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + query := "info_id = ? or name = ?" + args := []interface{}{info.InfoId, info.Name} + var count int64 + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Count(&count).Error + if err != nil { + return err + } + if count > 0 { + return entity.MenuIdOrNameExiErr + } + + nextSortNum, err := b.GetNextSortNum(ctx) + if err != nil { + return err + } + + info.SortNum = nextSortNum + + return DB.Model(&MenuInfoMysql{}).Create(convertMenuInfoToMenuInfoMysql(info)).Error +} + +func (b MenuInfoByMysqlRepo) GetNextSortNum(ctx context.Context) (int, error) { + query := "" + args := []interface{}{} + + menuInfoMysql := MenuInfoMysql{} + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Order("sort_num desc").First(&menuInfoMysql).Error + if b.NotFound(err) { + return 1, nil + } + + return menuInfoMysql.SortNum + 1, nil +} + +func (b MenuInfoByMysqlRepo) DelByTraceId(ctx context.Context, id string) error { + query := "trace_id = ?" + args := []interface{}{id} + return DB.Model(&MenuInfoMysql{}).Where(query, args...).Delete(&MenuInfoMysql{}).Error +} + +func (b MenuInfoByMysqlRepo) UpdateInfo(ctx context.Context, id string, info *entity.MenuInfo) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + menuInfoMysqls := make([]MenuInfoMysql, 0) + query := "info_id = ? or name = ?" + args := []interface{}{info.InfoId, info.Name} + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Find(&menuInfoMysqls).Error + if err != nil && !b.NotFound(err) { + return err + } + + for _, m := range menuInfoMysqls { + if m.TraceId != id { + return entity.MenuIdOrNameExiErr + } + } + + query = "trace_id = ?" + args = []interface{}{id} + return DB.Model(&MenuInfoMysql{}).Where(query, args...).Updates(convertMenuInfoToMenuInfoMysql(info)).Error +} + +func (b MenuInfoByMysqlRepo) AllCount(ctx context.Context) (int, error) { + query := "" + args := []interface{}{} + var count int64 + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (b MenuInfoByMysqlRepo) Sort(ctx context.Context, req *apiproto.MenuSortReq) error { + //if err := repository.Lock(ctx, 1*time.Minute); err != nil { + // return err + //} + //defer repository.Unlock(ctx) + + var resError error + for _, v := range req.List { + query := "trace_id = ?" + args := []interface{}{v.TraceId} + err := DB.Model(&MenuInfoMysql{}).Where(query, args...).Update("sort_num", v.SortNum).Error + if err != nil { + resError = err + } + } + + return resError +} + +func (b MenuInfoByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertMenuInfoMysqlToMenuInfo(menuInfoMysql MenuInfoMysql) entity.MenuInfo { + result := entity.MenuInfo{} + + result.TraceId = menuInfoMysql.TraceId + result.Name = menuInfoMysql.Name + result.InfoId = menuInfoMysql.InfoId + result.ImageUrl = menuInfoMysql.ImageUrl + result.SortNum = menuInfoMysql.SortNum + result.CreateTime = menuInfoMysql.CreateTime + result.UpdateTime = menuInfoMysql.UpdateTime + result.UpdateOperator = menuInfoMysql.UpdateOperator + + return result +} + +func convertMenuInfoToMenuInfoMysql(menuInfo *entity.MenuInfo) *MenuInfoMysql { + result := MenuInfoMysql{} + + result.TraceId = menuInfo.TraceId + result.Name = menuInfo.Name + result.InfoId = menuInfo.InfoId + result.ImageUrl = menuInfo.ImageUrl + result.SortNum = menuInfo.SortNum + result.CreateTime = menuInfo.CreateTime + result.UpdateTime = menuInfo.UpdateTime + result.UpdateOperator = menuInfo.UpdateOperator + + return &result +} diff --git a/infrastructure/db/repo/mysql/mysql.go b/infrastructure/db/repo/mysql/mysql.go new file mode 100644 index 0000000..b53da82 --- /dev/null +++ b/infrastructure/db/repo/mysql/mysql.go @@ -0,0 +1,139 @@ +package mysql + +import ( + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/db/entity/sql" + "finclip-app-manager/infrastructure/logger" + "fmt" + + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +var ( + log = logger.GetLogger() + DB *gorm.DB +) + +func StartUp(url string) { + var err error + /*dbConfig := &gorm.Config{} + DB, err = gorm.Open(mysql.Open(url), dbConfig) + if err != nil { + panic(err) + }*/ + DB, err = gorm.Open(mysql.New(mysql.Config{ + DriverName: config.Cfg.DriverName, + DSN: url, // data source name, refer https://github.com/go-sql-driver/mysql#dsn-data-source-name + }), &gorm.Config{}) + if err != nil { + panic(err) + } + DB.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1;") + if !DB.Debug().Migrator().HasTable(&sql.AppV2{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.AppV2{}) + } + + if !DB.Debug().Migrator().HasTable(&sql.AppVersionV2{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.AppVersionV2{}) + //DB.Model(&sql.AppVersion{}).AddUniqueIndex("idx_user_name", "name") + } + + if !DB.Debug().Migrator().HasTable(&sql.AppStatusInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.AppStatusInfo{}) + } + + if !DB.Debug().Migrator().HasTable(&sql.AppBuildInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.AppBuildInfo{}) + } + if !DB.Debug().Migrator().HasTable(&sql.AppVersionStatusInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.AppVersionStatusInfo{}) + } + + if !DB.Debug().Migrator().HasTable(&BundleInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&BundleInfo{}) + } + + if !DB.Debug().Migrator().HasTable(&LinkAppInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&LinkAppInfo{}) + } + + if !DB.Debug().Migrator().HasTable(&BindingMysqlV2{}) { + err = DB.Omit("Languages").AutoMigrate(&BindingMysqlV2{}) + } + + if !DB.Debug().Migrator().HasTable(&Bundle{}) { + err = DB.Omit("Languages").AutoMigrate(&Bundle{}) + } + + if !DB.Debug().Migrator().HasTable(&LinkAuditMysql{}) { + err = DB.Omit("Languages").AutoMigrate(&LinkAuditMysql{}) + } + if !DB.Debug().Migrator().HasTable(&MenuInfoMysql{}) { + err = DB.Omit("Languages").AutoMigrate(&MenuInfoMysql{}) + } + if !DB.Debug().Migrator().HasTable(&QrCodeInfoMysql{}) { + err = DB.Omit("Languages").AutoMigrate(&QrCodeInfoMysql{}) + } + if !DB.Debug().Migrator().HasTable(&TypeConfigMysql{}) { + err = DB.Omit("Languages").AutoMigrate(&TypeConfigMysql{}) + } + + if !DB.Debug().Migrator().HasTable(&AppTempInfoMysql{}) { + err = DB.Omit("Languages").AutoMigrate(&AppTempInfoMysql{}) + } + + if !DB.Debug().Migrator().HasTable(&sql.PrivacySettingInfo{}) { + err = DB.Omit("Languages").AutoMigrate(&sql.PrivacySettingInfo{}) + } + + if !DB.Debug().Migrator().HasTable(&repository.AppOperConfig{}) { + err = DB.Omit("Languages").AutoMigrate(&repository.AppOperConfig{}) + } + + // + + /*err = DB.Debug().AutoMigrate( + &sql.App{}, + &sql.AppStatusInfo{}, + &sql.AppVersion{}, + &sql.AppBuildInfo{}, + &sql.AppVersionStatusInfo{}, + &AppTempInfoMysql{}, + &BindingMysql{}, + &BundleInfo{}, + &LinkAppInfo{}, + &LinkAuditMysql{}, + &MenuInfoMysql{}, + &QrCodeInfoMysql{}, + &TypeConfigMysql{}, + &BundleMysql{}, + ) + if err != nil { + panic(err) + }*/ + + fmt.Println("start up mysql success ...") +} + +func DbNotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func genQuery(searchStr, assKey, cond string) string { + if searchStr != "" { + searchStr += " " + assKey + " " + cond + } else { + searchStr = cond + } + return searchStr +} + +func genLike(searchText string) string { + return "%" + searchText + "%" +} + +func genOffset(pageNo, pageSize int) int { + return (pageNo - 1) * pageSize +} diff --git a/infrastructure/db/repo/mysql/privacy_setting_info.go b/infrastructure/db/repo/mysql/privacy_setting_info.go new file mode 100644 index 0000000..b7f3ffb --- /dev/null +++ b/infrastructure/db/repo/mysql/privacy_setting_info.go @@ -0,0 +1,80 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/db/entity/sql" + "gorm.io/gorm" +) + +var _ repository.IPrivacySettingRepo = new(PrivacySettingRepoMysqlRepo) + +type PrivacySettingRepoMysqlRepo struct { +} + +func NewPrivacySettingRepoMysqlRepo() *PrivacySettingRepoMysqlRepo { + return &PrivacySettingRepoMysqlRepo{} +} + +func (a *PrivacySettingRepoMysqlRepo) Insert(ctx context.Context, item entity.PrivacySettingInfo) error { + err := DB.Model(&sql.PrivacySettingInfo{}).Create(tr.CovertPrivacySettingInfoToSql(&item)).Error + return err +} + +func (a *PrivacySettingRepoMysqlRepo) Count(ctx context.Context, appId string) (int, error) { + query := "app_id = ?" + args := []interface{}{appId} + var count int64 + err := DB.Model(&sql.PrivacySettingInfo{}).Where(query, args...).Count(&count).Error + return int(count), err +} + +func (a *PrivacySettingRepoMysqlRepo) GetInfoByAppId(ctx context.Context, appId string) (*entity.PrivacySettingInfo, error) { + query := "app_id = ?" + args := []interface{}{appId} + + privacySettingInfoMysql := sql.PrivacySettingInfo{} + err := DB.Model(&sql.PrivacySettingInfo{}).Where(query, args...).First(&privacySettingInfoMysql).Error + if err != nil { + return nil, err + } + result := tr.CovertPrivacySettingInfoToEntity(&privacySettingInfoMysql) + return result, err +} + +func (a *PrivacySettingRepoMysqlRepo) UpdateInfo(ctx context.Context, info entity.PrivacySettingInfo) error { + query := "app_id = ?" + args := []interface{}{info.AppId} + params := map[string]interface{}{ + "app_id": info.AppId, + "commit_type": info.CommitType, + "user_message_type": info.UserMessageType, + "sdk_message": info.SdkMessage, + "contact_info_phone": info.ContactInfoPhone, + "contact_info_email": info.ContactInfoEmail, + "contact_info_wechat": info.ContactInfoWeChat, + "contact_info_other": info.ContactInfoOther, + "fixed_storage_time": info.FixedStorageTime, + "is_shortest_time": info.IsShortestTime, + "additional_doc_name": info.AdditionalDocName, + "additional_doc_net_disk_id": info.AdditionalDocNetDiskId, + "additional_doc_content": info.AdditionalDocContent, + "is_first_save": info.IsFirstSave, + "effective_time": info.EffectiveTime, + "create_time": info.CreateTime, + "update_time": info.UpdateTime, + } + + return DB.Model(&sql.PrivacySettingInfo{}).Where(query, args...).Updates(params).Error +} + +func (a PrivacySettingRepoMysqlRepo) DelInfoByAppId(ctx context.Context, appId string) error { + query := "app_id = ?" + args := []interface{}{appId} + return DB.Model(&sql.PrivacySettingInfo{}).Where(query, args...).Delete(&sql.PrivacySettingInfo{}).Error +} + +func (a PrivacySettingRepoMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} diff --git a/infrastructure/db/repo/mysql/public.go b/infrastructure/db/repo/mysql/public.go new file mode 100644 index 0000000..6becca3 --- /dev/null +++ b/infrastructure/db/repo/mysql/public.go @@ -0,0 +1,7 @@ +package mysql + +import "finclip-app-manager/infrastructure/db/translator" + +var ( + tr = translator.NewSqlTranslator() +) diff --git a/infrastructure/db/repo/mysql/qr_code_info.go b/infrastructure/db/repo/mysql/qr_code_info.go new file mode 100644 index 0000000..5d3d2ae --- /dev/null +++ b/infrastructure/db/repo/mysql/qr_code_info.go @@ -0,0 +1,274 @@ +package mysql + +import ( + "context" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "finclip-app-manager/infrastructure/logger" + "gorm.io/gorm" + "time" +) + +var _ repository.IQrCodeInfoRepo = new(QrCodeInfoByMysqlRepo) + +type QrCodeInfoByMysqlRepo struct { +} + +type QrCodeInfoMysql struct { + //Id uint `bson:"id" gorm:"primary_key;column:id" sql:"auto_increment;primary_key;unique"` + ID uint64 `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + Type string `json:"type" gorm:"column:type;type:varchar(64);comment:二维码的类型"` + Uuid string `json:"uuid" gorm:"column:uuid;type:varchar(64);comment:标识该二维码"` + AppId string `json:"appId" gorm:"column:app_id;type:varchar(64);comment:小程序Id"` + Sequence int `json:"sequence" gorm:"column:sequence;type:int(6);comment:小程序序列号"` + ApiServer string `json:"apiServer" gorm:"column:api_server;type:varchar(256);comment:小程序apiServer"` + CodeId string `json:"codeId" gorm:"column:code_id;type:varchar(64);comment:标识某个编译版本的id"` + PathAndQuery string `json:"pathAndQuery" gorm:"column:path_and_query;type:varchar(512);comment:小程序启动参数"` + ExpireTime int64 `json:"expireTime" gorm:"column:expire_time;type:BIGINT(16);comment:过期时间"` + CreateTime int64 `json:"createTime" gorm:"column:create_time;type:BIGINT(16);comment:创建时间"` + UpdateTime int64 `json:"updateTime" gorm:"column:update_time;type:BIGINT(16);comment:更新时间"` + DeleteTime int64 `json:"deleteTime" gorm:"column:delete_time;type:BIGINT(16);comment:删除时间"` + DebugInfo string `json:"debugInfo" gorm:"column:debug_info;type:text;comment:扩展数据"` +} + +func (QrCodeInfoMysql) TableName() string { + return "qr_code_info" +} + +func (q QrCodeInfoByMysqlRepo) Insert(ctx context.Context, info *entity.QrCodeInfo) error { + sqlInfo := convertQrCodeInfoToQrCodeInfoMysql(info) + return DB.Model(&QrCodeInfoMysql{}).Create(&sqlInfo).Error +} + +func (q QrCodeInfoByMysqlRepo) GenInfo(ctx context.Context, info *entity.QrCodeInfo) error { + switch info.Type { + case entity.QrCodeTypeReview: + query := "type = ? and app_id = ? and sequence = ?" + args := []interface{}{info.Type, info.AppId, info.Sequence} + var count int64 + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Count(&count).Error + if err != nil { + return err + } + //如果存在就不再进行插入 + if count > 0 { + return nil + } + case entity.QrCodeTypeRelease: + query := "type = ? and app_id = ?" + args := []interface{}{info.Type, info.AppId} + var count int64 + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Count(&count).Error + if err != nil { + return err + } + //如果已经存在,更新就好 + if count > 0 { + query := "type = ? and app_id = ?" + args := []interface{}{info.Type, info.AppId} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Update("update_time", time.Now().UnixNano()/1e6).Error + } + case entity.QrCodeTypeTrial: + query := "type = ? and app_id = ?" + args := []interface{}{info.Type, info.AppId} + var count int64 + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Count(&count).Error + if err != nil { + return err + } + if count > 0 { + query := "type = ? and app_id = ?" + args := []interface{}{info.Type, info.AppId} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Updates(map[string]interface{}{"path_and_query": "", "code_id": info.CodeId, "update_time": time.Now().UnixNano() / 1e6}).Error + } + case entity.QrCodeTypeTemporary: + //直接插入 + default: + return errors.New("info type err") + } + //不存在就插入 + sqlInfo := convertQrCodeInfoToQrCodeInfoMysql(info) + return DB.Debug().Model(&QrCodeInfoMysql{}).Create(&sqlInfo).Error +} + +func (q QrCodeInfoByMysqlRepo) GetInfoByUuid(ctx context.Context, uuid string) (*entity.QrCodeInfo, error) { + query := "uuid = ?" + args := []interface{}{uuid} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetInfoByCodeId(ctx context.Context, codeId string) (*entity.QrCodeInfo, error) { + query := "code_id = ?" + args := []interface{}{codeId} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetReviewInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + query := "type = ? and app_id = ? and sequence = ?" + args := []interface{}{entity.QrCodeTypeReview, appId, seq} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetReleaseInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) { + query := "type = ? and app_id = ?" + args := []interface{}{entity.QrCodeTypeRelease, appId} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetTrialInfo(ctx context.Context, appId string) (*entity.QrCodeInfo, error) { + query := "type = ? and app_id = ?" + args := []interface{}{entity.QrCodeTypeTrial, appId} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetTemporaryInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + query := "type = ? and app_id = ? and sequence = ?" + args := []interface{}{entity.QrCodeTypeTemporary, appId, seq} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) GetRemoteDebugInfo(ctx context.Context, appId string, seq int) (*entity.QrCodeInfo, error) { + query := "type = ? and app_id = ? and sequence = ?" + args := []interface{}{entity.QrCodeTypeRomoteDebug, appId, seq} + + qrCodeInfoMysql := QrCodeInfoMysql{} + err := DB.Model(&QrCodeInfoMysql{}).Where(query, args...).First(&qrCodeInfoMysql).Error + if err != nil { + return nil, err + } + + result := convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql) + return &result, err +} + +func (q QrCodeInfoByMysqlRepo) UpdateTrialStartParams(ctx context.Context, codeId string, p entity.AppStartParams) error { + query := "type = ? and code_id = ?" + args := []interface{}{entity.QrCodeTypeTrial, codeId} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Update("path_and_query", p.PathAndQuery).Error +} + +func (q QrCodeInfoByMysqlRepo) UpdateStartParamsByUuid(ctx context.Context, uuid string, p entity.AppStartParams) error { + query := "uuid = ?" + args := []interface{}{uuid} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Update("path_and_query", p.PathAndQuery).Error +} +func (q QrCodeInfoByMysqlRepo) UpdateApiServer(ctx context.Context, uuid string, apiServer string) error { + query := "uuid = ?" + args := []interface{}{uuid} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).Update("api_server", apiServer).Error +} + +func (q QrCodeInfoByMysqlRepo) UpdateInfo(ctx context.Context, uuid string, upInfo map[string]interface{}) error { + query := "uuid = ?" + args := []interface{}{uuid} + return DB.Model(&QrCodeInfoMysql{}).Where(query, args...).UpdateColumns(upInfo).Error +} + +func (q QrCodeInfoByMysqlRepo) GenReviewQrCodeInfo(ctx context.Context, info *entity.QrCodeInfo) error { + return nil +} + +func (q QrCodeInfoByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertQrCodeInfoToQrCodeInfoMysql(qrCodeInfo *entity.QrCodeInfo) QrCodeInfoMysql { + result := QrCodeInfoMysql{} + + result.Type = qrCodeInfo.Type + result.Uuid = qrCodeInfo.Uuid + result.AppId = qrCodeInfo.AppId + result.Sequence = qrCodeInfo.Sequence + result.ApiServer = qrCodeInfo.ApiServer + result.CodeId = qrCodeInfo.CodeId + result.PathAndQuery = qrCodeInfo.StartParams.PathAndQuery + result.ExpireTime = qrCodeInfo.ExpireTime + result.CreateTime = qrCodeInfo.CreateTime + result.UpdateTime = qrCodeInfo.UpdateTime + result.DeleteTime = qrCodeInfo.DeleteTime + b, err := json.Marshal(qrCodeInfo.DebugInfo) + if err != nil { + logger.GetLogger().Errorf("convertQrCodeInfoToQrCodeInfoMysql json.Marshal err:%s", err.Error()) + result.DebugInfo = "{}" + } else { + result.DebugInfo = string(b) + } + return result +} + +func convertQrCodeInfoMysqlToQrCodeInfo(qrCodeInfoMysql QrCodeInfoMysql) entity.QrCodeInfo { + result := entity.QrCodeInfo{} + + appStartParams := entity.AppStartParams{ + PathAndQuery: qrCodeInfoMysql.PathAndQuery, + } + + result.Type = qrCodeInfoMysql.Type + result.Uuid = qrCodeInfoMysql.Uuid + result.AppId = qrCodeInfoMysql.AppId + result.Sequence = qrCodeInfoMysql.Sequence + result.ApiServer = qrCodeInfoMysql.ApiServer + result.CodeId = qrCodeInfoMysql.CodeId + result.StartParams = appStartParams + result.ExpireTime = qrCodeInfoMysql.ExpireTime + result.CreateTime = qrCodeInfoMysql.CreateTime + result.UpdateTime = qrCodeInfoMysql.UpdateTime + result.DeleteTime = qrCodeInfoMysql.DeleteTime + debugInfo := make(map[string]interface{}) + err := json.Unmarshal([]byte(qrCodeInfoMysql.DebugInfo), &debugInfo) + if err != nil { + logger.GetLogger().Errorf("convertQrCodeInfoMysqlToQrCodeInfo json.Unmarshal err:%s", err.Error()) + } + result.DebugInfo = debugInfo + return result +} diff --git a/infrastructure/db/repo/mysql/red_dot.go b/infrastructure/db/repo/mysql/red_dot.go new file mode 100644 index 0000000..9678ce8 --- /dev/null +++ b/infrastructure/db/repo/mysql/red_dot.go @@ -0,0 +1,53 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + "gorm.io/gorm" + "time" +) + +var _ repository.IRedDotRepo = new(RedDotByMysqlRepo) + +type RedDotByMysqlRepo struct { +} + +type RedDotReadRecordMysql struct { + Id uint `bson:"id" gorm:"primary_key;column:id" sql:"auto_increment;primary_key;unique"` + Type string `json:"type" gorm:"column:type;type:varchar(64);comment:红点类型"` + TraceId string `json:"traceId" gorm:"column:trace_id;type:varchar(64);comment:红点唯一标识"` + AccountId string `json:"accountId" gorm:"column:account_id;type:varchar(64);comment:已经阅读的账户Id"` + CreateTime int64 `json:"createTime" gorm:"column:create_time;type:BIGINT(16);comment:创建时间"` + UpdateTime int64 `json:"updateTime" gorm:"column:update_time;type:BIGINT(16);comment:更新时间"` +} + +func (RedDotReadRecordMysql) TableName() string { + return "red_dot_read_record" +} + +func (r RedDotByMysqlRepo) ReadTrialQr(ctx context.Context, readDotType string, id string, userId string) error { + info := entity.RedDotReadRecord{ + Type: readDotType, + TraceId: id, + AccountId: userId, + CreateTime: time.Now().UnixNano() / 1e6, + } + return DB.Model(&RedDotReadRecordMysql{}).Create(convertRedDotReadRecordToRedDotReadRecordMysql(&info)).Error +} + +func (r RedDotByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertRedDotReadRecordToRedDotReadRecordMysql(redDotReadRecord *entity.RedDotReadRecord) RedDotReadRecordMysql { + result := RedDotReadRecordMysql{} + + result.Type = redDotReadRecord.Type + result.TraceId = redDotReadRecord.TraceId + result.AccountId = redDotReadRecord.AccountId + result.CreateTime = redDotReadRecord.CreateTime + result.UpdateTime = redDotReadRecord.UpdateTime + + return result +} diff --git a/infrastructure/db/repo/mysql/type_config.go b/infrastructure/db/repo/mysql/type_config.go new file mode 100644 index 0000000..4e5de12 --- /dev/null +++ b/infrastructure/db/repo/mysql/type_config.go @@ -0,0 +1,163 @@ +package mysql + +import ( + "context" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/repository" + + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "gorm.io/gorm" +) + +var _ repository.ITypeConfigRepo = new(TypeConfigByMysqlRepo) + +type TypeConfigByMysqlRepo struct { +} + +func NewTypeConfigByMysqlRepo() *TypeConfigByMysqlRepo { + return &TypeConfigByMysqlRepo{} +} + +type TypeConfigMysql struct { + Id uint `json:"id" gorm:"primary_key;column:id;type:BIGINT(16) AUTO_INCREMENT;comment:'自增id'" sql:"auto_increment;primary_key"` + TypeConfigID string `json:"typeConfigId" gorm:"column:type_config_id;type:varchar(64);comment:唯一Id"` + Namespace string `json:"namespace" gorm:"column:namespace;type:varchar(64);comment:空间"` + Value string `json:"value" gorm:"column:value;type:varchar(64);comment:值"` + MarketID string `json:"marketId" gorm:"column:market_id;type:varchar(64);comment:应用市场id"` + //CustomData string `json:"customData" gorm:"column:customData;type:varchar(64);comment:''"` + Chinese string `json:"chinese" gorm:"column:chinese;type:varchar(64);comment:中文"` + SortNum int `json:"sortNum" gorm:"column:sort_num;type:INT(4);comment:排序值"` +} + +func (TypeConfigMysql) TableName() string { + return "type_config" +} + +func (t TypeConfigByMysqlRepo) Insert(ctx context.Context, typeConfig *entity.TypeConfig) error { + return DB.Model(&TypeConfigMysql{}).Debug().Create(convertTypeConfigToTypeConfigMysql(typeConfig)).Error +} + +func (t TypeConfigByMysqlRepo) GetOne(ctx context.Context, filter bson.M) error { + panic("implement me") +} + +func (t TypeConfigByMysqlRepo) Exist(ctx context.Context, namespace string, value string) (bool, error) { + query := "namespace = ? and value = ?" + args := []interface{}{namespace, value} + + typeConfigMysql := TypeConfigMysql{} + err := DB.Model(&TypeConfigMysql{}).Where(query, args...).First(&typeConfigMysql).Error + if err != nil && t.NotFound(err) { + return false, err + } + + return true, err +} + +func (t TypeConfigByMysqlRepo) Update(ctx context.Context, selector bson.M, update bson.M) error { + panic("implement me") +} + +func (t TypeConfigByMysqlRepo) GetSome(ctx context.Context, pageSize, pageNo int) (int, []entity.TypeConfig, error) { + query := "" + args := []interface{}{} + + typeConfigMysqls := make([]TypeConfigMysql, 0) + err := DB.Model(&TypeConfigMysql{}).Debug(). + Where(query, args...). + Offset((pageNo - 1) * pageSize).Limit(pageSize). + Find(&typeConfigMysqls).Error + if err != nil { + return 0, nil, err + } + + var total int64 + DB.Model(&TypeConfigMysql{}).Debug().Where(query, args...).Count(&total) + + typeConfigs := make([]entity.TypeConfig, 0) + for _, typeConfigMysql := range typeConfigMysqls { + typeConfig := convertTypeConfigMysqlToTypeConfig(typeConfigMysql) + typeConfigs = append(typeConfigs, typeConfig) + } + + return int(total), typeConfigs, err +} + +func (t TypeConfigByMysqlRepo) GetAll(ctx context.Context) (int, []entity.TypeConfig, error) { + query := "" + args := []interface{}{} + + typeConfigMysqls := make([]TypeConfigMysql, 0) + err := DB.Model(&TypeConfigMysql{}).Debug(). + Where(query, args...). + Find(&typeConfigMysqls).Error + if err != nil { + return 0, nil, err + } + + var total int64 + DB.Model(&TypeConfigMysql{}).Debug().Where(query, args...).Count(&total) + + typeConfigs := make([]entity.TypeConfig, 0) + for _, typeConfigMysql := range typeConfigMysqls { + typeConfig := convertTypeConfigMysqlToTypeConfig(typeConfigMysql) + typeConfigs = append(typeConfigs, typeConfig) + } + + return int(total), typeConfigs, err +} + +func (t TypeConfigByMysqlRepo) Delete(ctx context.Context, typeConfigId string) error { + query := "type_config_id = ?" + args := []interface{}{typeConfigId} + return DB.Model(&TypeConfigMysql{}).Delete(query, args...).Error +} + +func (t TypeConfigByMysqlRepo) GetNowSortNumInfo(ctx context.Context) (*entity.TypeConfig, error) { + query := "sort_num < ?" + args := []interface{}{99990000} + + typeConfigMysql := TypeConfigMysql{} + err := DB.Model(&TypeConfigMysql{}).Where(query, args...).Order("sort_num desc").First(&typeConfigMysql).Error + if err != nil { + return nil, err + } + + result := convertTypeConfigMysqlToTypeConfig(typeConfigMysql) + + return &result, err +} + +func (t TypeConfigByMysqlRepo) NotFound(err error) bool { + return err == gorm.ErrRecordNotFound +} + +func convertTypeConfigMysqlToTypeConfig(typeConfigMysql TypeConfigMysql) entity.TypeConfig { + result := entity.TypeConfig{} + + //var customData entity.TypeConfigCustomData + //json.Unmarshal([]byte(typeConfigMysql.CustomData), &customData) + + result.TypeConfigID = typeConfigMysql.TypeConfigID + result.Namespace = typeConfigMysql.Namespace + result.Value = typeConfigMysql.Value + result.MarketID = typeConfigMysql.MarketID + result.CustomData.Chinese = typeConfigMysql.Chinese + result.SortNum = typeConfigMysql.SortNum + + return result +} + +func convertTypeConfigToTypeConfigMysql(typeConfig *entity.TypeConfig) *TypeConfigMysql { + result := TypeConfigMysql{} + + result.TypeConfigID = typeConfig.TypeConfigID + result.Namespace = typeConfig.Namespace + result.Value = typeConfig.Value + result.MarketID = typeConfig.MarketID + //result.CustomData = utility.InterfaceToJsonString(typeConfig.CustomData) + result.Chinese = typeConfig.CustomData.Chinese + result.SortNum = typeConfig.SortNum + + return &result +} diff --git a/infrastructure/db/repo/pg/pg.go b/infrastructure/db/repo/pg/pg.go new file mode 100644 index 0000000..d8295ec --- /dev/null +++ b/infrastructure/db/repo/pg/pg.go @@ -0,0 +1,5 @@ +package pg + +func init() { + /*初始化pg*/ +} diff --git a/infrastructure/db/translator/mongo.go b/infrastructure/db/translator/mongo.go new file mode 100644 index 0000000..cbf358e --- /dev/null +++ b/infrastructure/db/translator/mongo.go @@ -0,0 +1,498 @@ +package translator + +import ( + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/db/entity/mongo" +) + +type MgoTranslator struct { +} + +func NewMgoTranslator() *MgoTranslator { + return &MgoTranslator{} +} + +func (mtr *MgoTranslator) CovertAppToMgo(info *entity.App) *mongo.App { + if info == nil { + return nil + } + return &mongo.App{ + AppID: info.AppID, + Name: info.Name, + Sequence: info.Sequence, + AppClass: info.AppClass, + AppTag: info.AppTag, + AppType: info.AppType, + Status: mtr.CovertStatusToMgo(info.Status), + //todo 这是个啥 + //ApplyStatus: + PublishedStatus: mtr.CovertSpecificStatusToMgo(info.PublishedStatus), + UnpublishedStatus: mtr.CovertSpecificStatusToMgo(info.UnpublishedStatus), + ActionStatus: mtr.CovertSpecificStatusToMgo(info.ActionStatus), + DeveloperID: info.DeveloperID, + GroupID: info.GroupID, + Created: info.Created, + CreatedBy: info.CreatedBy, + DetailDescription: info.CustomData.DetailDescription, + CoreDescription: info.CoreDescription, + Logo: info.Logo, + Expire: info.Expire, + IsForbidden: info.IsForbidden, + PrivacySettingType: info.PrivacySettingType, + ProjectType: info.ProjectType, + } +} + +func (mtr *MgoTranslator) CovertAppToEntity(info *mongo.App) *entity.App { + if info == nil { + return nil + } + return &entity.App{ + AppID: info.AppID, + Name: info.Name, + Version: info.Version, + Sequence: info.Sequence, + AppClass: info.AppClass, + AppTag: info.AppTag, + AppType: info.AppType, + Status: mtr.CovertStatusToEntity(info.Status), + //todo 这是个啥 + //ApplyStatus: + PublishedStatus: mtr.CovertSpecificStatusToEntity(info.PublishedStatus), + UnpublishedStatus: mtr.CovertSpecificStatusToEntity(info.UnpublishedStatus), + ActionStatus: mtr.CovertSpecificStatusToEntity(info.ActionStatus), + DeveloperID: info.DeveloperID, + GroupID: info.GroupID, + Created: info.Created, + CreatedBy: info.CreatedBy, + CustomData: entity.CustomDataInfo{ + DetailDescription: info.DetailDescription, + SourceFile: make([]entity.CustomDataSourceFile, 0), + }, + CoreDescription: info.CoreDescription, + Logo: info.Logo, + Expire: info.Expire, + IsForbidden: info.IsForbidden, + PrivacySettingType: info.PrivacySettingType, + ProjectType: info.ProjectType, + } +} + +func (mtr *MgoTranslator) CovertAppVerToMgo(info *entity.AppVersion) *mongo.AppVersion { + if info == nil { + return nil + } + return &mongo.AppVersion{ + AppID: info.AppID, + Name: info.Name, + AppClass: info.AppClass, + AppTag: info.AppTag, + AppType: info.AppType, + Status: mtr.CovertStatusToMgo(info.Status), + PublishingStatus: mtr.CovertSpecificStatusToMgo(info.PublishingStatus), + //todo 这是个啥 + //ApplyStatus: + PublishingApprovalStatus: mtr.CovertSpecificStatusToMgo(info.PublishingApprovalStatus), + UnpublishingApprovalStatus: mtr.CovertSpecificStatusToMgo(info.UnpublishingApprovalStatus), + PublishedStatus: mtr.CovertSpecificStatusToMgo(info.PublishedStatus), + UnpublishedStatus: mtr.CovertUnpublishedStatusToMgo(info.UnpublishedStatus), + ApprovalStatus: mtr.CovertSpecificStatusToMgo(info.ApprovalStatus), + ActionStatus: mtr.CovertSpecificStatusToMgo(info.ActionStatus), + DeveloperID: info.DeveloperID, + GroupID: info.GroupID, + Created: info.Created, + CreatedBy: info.CreatedBy, + CustomData: mtr.CovertCustomDataToMgo(info.CustomData), + Version: info.Version, + Sequence: info.Sequence, + CorporationID: info.CorporationID, + CoreDescription: info.CoreDescription, + Logo: info.Logo, + TestInfo: mtr.CovertTestInfoToMgo(info.TestInfo), + NeedAutoPub: info.NeedAutoPub, + InGrayRelease: info.InGrayRelease, + Expire: info.Expire, + AppBuildID: info.AppBuildID, + } +} + +func (mtr *MgoTranslator) CovertAppVerToEntity(info *mongo.AppVersion) *entity.AppVersion { + if info == nil { + return nil + } + return &entity.AppVersion{ + AppID: info.AppID, + Name: info.Name, + AppClass: info.AppClass, + AppTag: info.AppTag, + AppType: info.AppType, + Status: mtr.CovertStatusToEntity(info.Status), + PublishingStatus: mtr.CovertSpecificStatusToEntity(info.PublishingStatus), + //todo 这是个啥 + //ApplyStatus: + PublishingApprovalStatus: mtr.CovertSpecificStatusToEntity(info.PublishingApprovalStatus), + UnpublishingApprovalStatus: mtr.CovertSpecificStatusToEntity(info.UnpublishingApprovalStatus), + PublishedStatus: mtr.CovertSpecificStatusToEntity(info.PublishedStatus), + UnpublishedStatus: mtr.CovertUnpublishedStatusToEntity(info.UnpublishedStatus), + ApprovalStatus: mtr.CovertSpecificStatusToEntity(info.ApprovalStatus), + ActionStatus: mtr.CovertSpecificStatusToEntity(info.ActionStatus), + DeveloperID: info.DeveloperID, + GroupID: info.GroupID, + Created: info.Created, + CreatedBy: info.CreatedBy, + CustomData: mtr.CovertCustomDataToEntity(info.CustomData), + Version: info.Version, + Sequence: info.Sequence, + CorporationID: info.CorporationID, + CoreDescription: info.CoreDescription, + Logo: info.Logo, + TestInfo: mtr.CovertTestInfoToEntity(info.TestInfo), + NeedAutoPub: info.NeedAutoPub, + InGrayRelease: info.InGrayRelease, + IsRollback: info.IsRollback, + Expire: info.Expire, + AppBuildID: info.AppBuildID, + } +} + +func (mtr *MgoTranslator) CovertStatusToMgo(info entity.Status) mongo.Status { + return mongo.Status{ + Value: info.Value, + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + } +} + +func (mtr *MgoTranslator) CovertStatusToEntity(info mongo.Status) entity.Status { + return entity.Status{ + Value: info.Value, + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + } +} +func (mtr *MgoTranslator) CovertSpecificStatusToMgo(info entity.SpecificStatus) mongo.SpecificStatus { + return mongo.SpecificStatus{ + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + } +} +func (mtr *MgoTranslator) CovertSpecificStatusToEntity(info mongo.SpecificStatus) entity.SpecificStatus { + return entity.SpecificStatus{ + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + } +} + +func (mtr *MgoTranslator) CovertUnpublishedStatusToMgo(info entity.UnpublishedStatus) mongo.UnpublishedStatus { + return mongo.UnpublishedStatus{ + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + Type: info.Type, + } +} + +func (mtr *MgoTranslator) CovertUnpublishedStatusToEntity(info mongo.UnpublishedStatus) entity.UnpublishedStatus { + return entity.UnpublishedStatus{ + Reason: info.Reason, + LastUpdated: info.LastUpdated, + ModifiedBy: info.ModifiedBy, + Type: info.Type, + } +} + +func (mtr *MgoTranslator) CovertTestInfoToMgo(info entity.TestInfo) mongo.TestInfo { + return mongo.TestInfo{ + Account: info.Account, + Password: info.Password, + Description: info.Description, + Images: info.Images, + } +} + +func (mtr *MgoTranslator) CovertTestInfoToEntity(info mongo.TestInfo) entity.TestInfo { + return entity.TestInfo{ + Account: info.Account, + Password: info.Password, + Description: info.Description, + Images: info.Images, + } +} + +func (mtr *MgoTranslator) CovertCustomDataToMgo(info entity.CustomDataInfo) mongo.CustomDataInfo { + result := mongo.CustomDataInfo{ + DetailDescription: info.DetailDescription, + SourceFile: make([]mongo.CustomDataSourceFile, 0), + VersionDescription: info.VersionDescription, + Developer: info.Developer, + } + for _, v := range info.SourceFile { + customInfo := mongo.CustomDataSourceFile{ + FileMd5: v.FileMd5, + Name: v.Name, + SourceFileUrl: v.SourceFileUrl, + UploadDate: v.UploadDate, + Url: v.Url, + EncryptedUrl: v.EncryptedUrl, + EncryptedFileMd5: v.EncryptedFileMd5, + EncryptedFileSha256: v.EncryptedFileSha256, + BasicPackVer: v.BasicPackVer, + Packages: make([]mongo.Package, 0), + EncryptPackages: make([]mongo.Package, 0), + } + for _, p := range v.Packages { + customInfo.Packages = append(customInfo.Packages, mongo.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + for _, p := range v.EncryptPackages { + customInfo.EncryptPackages = append(customInfo.EncryptPackages, mongo.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + result.SourceFile = append(result.SourceFile, customInfo) + } + return result +} + +func (mtr *MgoTranslator) CovertCustomDataToEntity(info mongo.CustomDataInfo) entity.CustomDataInfo { + result := entity.CustomDataInfo{ + DetailDescription: info.DetailDescription, + SourceFile: make([]entity.CustomDataSourceFile, 0), + VersionDescription: info.VersionDescription, + Developer: info.Developer, + } + for _, v := range info.SourceFile { + customInfo := entity.CustomDataSourceFile{ + FileMd5: v.FileMd5, + Name: v.Name, + SourceFileUrl: v.SourceFileUrl, + UploadDate: v.UploadDate, + Url: v.Url, + EncryptedUrl: v.EncryptedUrl, + EncryptedFileMd5: v.EncryptedFileMd5, + EncryptedFileSha256: v.EncryptedFileSha256, + BasicPackVer: v.BasicPackVer, + Packages: make([]entity.Package, 0), + EncryptPackages: make([]entity.Package, 0), + } + for _, p := range v.Packages { + customInfo.Packages = append(customInfo.Packages, entity.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + for _, p := range v.EncryptPackages { + customInfo.EncryptPackages = append(customInfo.EncryptPackages, entity.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + result.SourceFile = append(result.SourceFile, customInfo) + } + return result +} + +func (mtr *MgoTranslator) CovertAppBuildInfoToMgo(info *entity.AppBuildInfo) *mongo.AppBuildInfo { + result := &mongo.AppBuildInfo{ + Id: info.Id, + BuildInfoId: info.BuildInfoId, + Source: info.Source, + AppID: info.AppID, + GroupID: info.GroupID, + Created: info.Created, + UserId: info.UserId, + CreatedBy: info.CreatedBy, + CustomData: mongo.CustomDataInfo{ + Developer: info.CustomData.Developer, + SourceFile: make([]mongo.CustomDataSourceFile, 0), + VersionDescription: info.CustomData.VersionDescription, + DetailDescription: info.CustomData.DetailDescription, + }, + Version: info.Version, + StartParams: mongo.AppStartParams{ + PathAndQuery: info.StartParams.PathAndQuery, + }, + Status: info.Status, + } + for _, v := range info.CustomData.SourceFile { + item := mongo.CustomDataSourceFile{ + FileMd5: v.FileMd5, + Name: v.Name, + SourceFileUrl: v.SourceFileUrl, + UploadDate: info.Created, + Url: v.Url, + EncryptedUrl: v.EncryptedUrl, + EncryptedFileMd5: v.EncryptedFileMd5, + EncryptedFileSha256: v.EncryptedFileSha256, + BasicPackVer: v.BasicPackVer, + Packages: make([]mongo.Package, 0), + EncryptPackages: make([]mongo.Package, 0), + } + for _, p := range v.Packages { + item.Packages = append(item.Packages, mongo.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + for _, p := range v.EncryptPackages { + item.EncryptPackages = append(item.EncryptPackages, mongo.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + result.CustomData.SourceFile = append(result.CustomData.SourceFile, item) + } + return result +} + +func (mtr *MgoTranslator) CovertAppBuildInfoToEntity(info *mongo.AppBuildInfo) *entity.AppBuildInfo { + result := &entity.AppBuildInfo{ + Id: info.Id, + BuildInfoId: info.BuildInfoId, + Source: info.Source, + AppID: info.AppID, + GroupID: info.GroupID, + Created: info.Created, + UserId: info.UserId, + CreatedBy: info.CreatedBy, + CustomData: entity.CustomDataInfo{ + Developer: info.CustomData.Developer, + SourceFile: make([]entity.CustomDataSourceFile, 0), + VersionDescription: info.CustomData.VersionDescription, + DetailDescription: info.CustomData.DetailDescription, + }, + Version: info.Version, + StartParams: entity.AppStartParams{ + PathAndQuery: info.StartParams.PathAndQuery, + }, + Status: info.Status, + } + for _, v := range info.CustomData.SourceFile { + item := entity.CustomDataSourceFile{ + FileMd5: v.FileMd5, + Name: v.Name, + SourceFileUrl: v.SourceFileUrl, + UploadDate: v.UploadDate, + Url: v.Url, + EncryptedUrl: v.EncryptedUrl, + EncryptedFileMd5: v.EncryptedFileMd5, + EncryptedFileSha256: v.EncryptedFileSha256, + BasicPackVer: v.BasicPackVer, + Packages: make([]entity.Package, 0), + EncryptPackages: make([]entity.Package, 0), + } + for _, p := range v.Packages { + item.Packages = append(item.Packages, entity.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + for _, p := range v.EncryptPackages { + item.EncryptPackages = append(item.EncryptPackages, entity.Package{ + Root: p.Root, + Name: p.Name, + Pages: p.Pages, + Independent: p.Independent, + Filename: p.Filename, + FileUrl: p.FileUrl, + FileMd5: p.FileMd5, + }) + } + result.CustomData.SourceFile = append(result.CustomData.SourceFile, item) + } + return result +} + +func (mtr *MgoTranslator) CovertPrivacySettingInfoToEntity(info *mongo.PrivacySettingInfoMongo) *entity.PrivacySettingInfo { + if info == nil { + return nil + } + result := entity.PrivacySettingInfo{ + AppId: info.AppId, + CommitType: info.CommitType, + UserMessageType: info.UserMessageType, + SdkMessage: info.SdkMessage, + ContactInfoPhone: info.ContactInfoPhone, + ContactInfoEmail: info.ContactInfoEmail, + ContactInfoWeChat: info.ContactInfoWeChat, + ContactInfoOther: info.ContactInfoOther, + FixedStorageTime: info.FixedStorageTime, + IsShortestTime: info.IsShortestTime, + AdditionalDocName: info.AdditionalDocName, + AdditionalDocNetDiskId: info.AdditionalDocNetDiskId, + AdditionalDocContent: info.AdditionalDocContent, + IsFirstSave: info.IsFirstSave, + EffectiveTime: info.EffectiveTime, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + } + return &result +} + +func (mtr *MgoTranslator) CovertPrivacySettingInfoToMongo(info *entity.PrivacySettingInfo) *mongo.PrivacySettingInfoMongo { + if info == nil { + return nil + } + result := mongo.PrivacySettingInfoMongo{ + AppId: info.AppId, + CommitType: info.CommitType, + UserMessageType: info.UserMessageType, + SdkMessage: info.SdkMessage, + ContactInfoPhone: info.ContactInfoPhone, + ContactInfoEmail: info.ContactInfoEmail, + ContactInfoWeChat: info.ContactInfoWeChat, + ContactInfoOther: info.ContactInfoOther, + FixedStorageTime: info.FixedStorageTime, + IsShortestTime: info.IsShortestTime, + AdditionalDocName: info.AdditionalDocName, + AdditionalDocNetDiskId: info.AdditionalDocNetDiskId, + AdditionalDocContent: info.AdditionalDocContent, + IsFirstSave: info.IsFirstSave, + EffectiveTime: info.EffectiveTime, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + } + return &result +} diff --git a/infrastructure/db/translator/sql.go b/infrastructure/db/translator/sql.go new file mode 100644 index 0000000..e45942b --- /dev/null +++ b/infrastructure/db/translator/sql.go @@ -0,0 +1,481 @@ +package translator + +import ( + "encoding/json" + "finclip-app-manager/domain/entity" + "finclip-app-manager/infrastructure/db/entity/sql" + "strings" +) + +type SqlTranslator struct { +} + +func NewSqlTranslator() *SqlTranslator { + return &SqlTranslator{} +} + +func (mtr *SqlTranslator) CovertAppToSql(info *entity.App) *sql.App { + if info == nil { + return nil + } + return &sql.App{ + AppId: info.AppID, + Name: info.Name, + AppClass: info.AppClass, + AppTag: strings.Join(info.AppTag, ","), + AppType: info.AppType, + StatusInfo: sql.AppStatusInfo{ + AppId: info.AppID, + StatusValue: info.Status.Value, + StatusReason: info.Status.Reason, + StatusUpdateTime: info.Status.LastUpdated, + StatusUpdater: info.Status.ModifiedBy, + PublishedReason: info.PublishedStatus.Reason, + PublishedUpdateTime: info.PublishedStatus.LastUpdated, + PublishedUpdater: info.PublishedStatus.ModifiedBy, + UnpublishedReason: info.UnpublishedStatus.Reason, + UnpublishedUpdateTime: info.UnpublishedStatus.LastUpdated, + UnpublishedUpdater: info.UnpublishedStatus.ModifiedBy, + ActionReason: info.ActionStatus.Reason, + ActionUpdater: info.ActionStatus.ModifiedBy, + ActionUpdateTime: info.ActionStatus.LastUpdated, + }, + //Status: mtr.CovertStatusToMgo(info.Status), + //todo 这是个啥 + //ApplyStatus: + DeveloperId: info.DeveloperID, + GroupId: info.GroupID, + CreatedBy: info.CreatedBy, + Desc: info.CoreDescription, + DetailDesc: info.CustomData.DetailDescription, + Logo: info.Logo, + Expire: info.Expire, + IsForbidden: info.IsForbidden, + PrivacySettingType: info.PrivacySettingType, + ProjectType: info.ProjectType, + CreateTime: info.Created, + } +} + +func (mtr *SqlTranslator) CovertAppToEntity(info *sql.App) *entity.App { + if info == nil { + return nil + } + return &entity.App{ + AppID: info.AppId, + Name: info.Name, + AppClass: info.AppClass, + AppTag: strings.Split(info.AppTag, ","), + AppType: info.AppType, + Status: entity.Status{ + Value: info.StatusInfo.StatusValue, + Reason: info.StatusInfo.StatusReason, + LastUpdated: info.StatusInfo.StatusUpdateTime, + ModifiedBy: info.StatusInfo.StatusUpdater, + }, + PublishedStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.PublishedReason, + LastUpdated: info.StatusInfo.PublishedUpdateTime, + ModifiedBy: info.StatusInfo.PublishedUpdater, + }, + UnpublishedStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.UnpublishedReason, + LastUpdated: info.StatusInfo.UnpublishedUpdateTime, + ModifiedBy: info.StatusInfo.UnpublishedUpdater, + }, + ActionStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.ActionReason, + LastUpdated: info.StatusInfo.ActionUpdateTime, + ModifiedBy: info.StatusInfo.ActionUpdater, + }, + //todo 这是个啥 + //ApplyStatus: + DeveloperID: info.DeveloperId, + GroupID: info.GroupId, + CreatedBy: info.CreatedBy, + CustomData: entity.CustomDataInfo{ + DetailDescription: info.DetailDesc, + SourceFile: make([]entity.CustomDataSourceFile, 0), + }, + CoreDescription: info.Desc, + Logo: info.Logo, + Expire: info.Expire, + IsForbidden: info.IsForbidden, + PrivacySettingType: info.PrivacySettingType, + ProjectType: info.ProjectType, + Created: info.CreateTime, + } +} + +func (mtr *SqlTranslator) CovertAppToAppV2(info *sql.App) *sql.AppV2 { + if info == nil { + return nil + } + return &sql.AppV2{ + AppId: info.AppId, + Name: info.Name, + AppClass: info.AppClass, + AppTag: info.AppTag, + AppType: info.AppType, + Class: info.Class, + DeveloperId: info.DeveloperId, + GroupId: info.GroupId, + CreatedBy: info.CreatedBy, + Desc: info.Desc, + DetailDesc: info.DetailDesc, + Logo: info.Logo, + Expire: info.Expire, + Ext: info.Ext, + IsForbidden: info.IsForbidden, + PrivacySettingType: info.PrivacySettingType, + ProjectType: info.ProjectType, + IsRollback: info.IsRollback, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + } +} + +func (mtr *SqlTranslator) CovertAppVerToSql(info *entity.AppVersion) *sql.AppVersion { + if info == nil { + return nil + } + + result := &sql.AppVersion{ + AppId: info.AppID, + Sequence: info.Sequence, + Name: info.Name, + Logo: info.Logo, + Version: info.Version, + Desc: info.CoreDescription, + DetailDesc: info.CustomData.DetailDescription, + Class: info.AppClass, + Tag: strings.Join(info.AppTag, ","), + AppType: info.AppType, + DeveloperId: info.DeveloperID, + GroupId: info.GroupID, + AutoPub: info.NeedAutoPub, + InGrayRelease: info.InGrayRelease, + BuildInfoId: info.AppBuildID, + StatusInfo: sql.AppVersionStatusInfo{ + AppId: info.AppID, + Sequence: info.Sequence, + StatusReason: info.Status.Reason, + StatusValue: info.Status.Value, + StatusUpdateTime: info.Status.LastUpdated, + StatusUpdater: info.Status.ModifiedBy, + PublishingReason: info.PublishingStatus.Reason, + PublishingUpdateTime: info.PublishingStatus.LastUpdated, + PublishingUpdater: info.PublishingStatus.ModifiedBy, + PublishedReason: info.PublishedStatus.Reason, + PublishedUpdateTime: info.PublishedStatus.LastUpdated, + PublishedUpdater: info.PublishedStatus.ModifiedBy, + UnpublishedReason: info.UnpublishedStatus.Reason, + UnpublishedUpdateTime: info.UnpublishedStatus.LastUpdated, + UnpublishedUpdater: info.UnpublishedStatus.ModifiedBy, + UnpublishedType: info.UnpublishedStatus.Type, + ApprovalReason: info.ApprovalStatus.Reason, + ApprovalUpdateTime: info.ApprovalStatus.LastUpdated, + ApprovalUpdater: info.ApprovalStatus.ModifiedBy, + ActionReason: info.ActionStatus.Reason, + ActionUpdater: info.ActionStatus.ModifiedBy, + ActionUpdateTime: info.ActionStatus.LastUpdated, + PublishingApprovalReason: info.PublishingApprovalStatus.Reason, + PublishingApprovalUpdateTime: info.PublishingApprovalStatus.LastUpdated, + PublishingApprovalUpdater: info.PublishingApprovalStatus.ModifiedBy, + CreateTime: info.Created, + }, + CreatedBy: info.CreatedBy, + IsRollback: info.IsRollback, + ExpireTime: info.Expire, + CreateTime: info.Created, + TestInfo: "", + } + testInfoByte, _ := json.Marshal(info.TestInfo) + result.TestInfo = string(testInfoByte) + return result +} + +func (mtr *SqlTranslator) CovertAppVerToEntity(info *sql.AppVersion) *entity.AppVersion { + if info == nil { + return nil + } + result := &entity.AppVersion{ + AppID: info.AppId, + Name: info.Name, + AppClass: info.Class, + AppTag: strings.Split(info.Tag, ","), + AppType: info.AppType, + Version: info.Version, + Sequence: info.Sequence, + Logo: info.Logo, + Status: entity.Status{ + Value: info.StatusInfo.StatusValue, + Reason: info.StatusInfo.StatusReason, + LastUpdated: info.StatusInfo.StatusUpdateTime, + ModifiedBy: info.StatusInfo.StatusUpdater, + }, + PublishingStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.PublishingReason, + LastUpdated: info.StatusInfo.PublishingUpdateTime, + ModifiedBy: info.StatusInfo.PublishingUpdater, + }, + UnpublishingStatus: entity.SpecificStatus{}, + PublishingApprovalStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.PublishingApprovalReason, + LastUpdated: info.StatusInfo.PublishingApprovalUpdateTime, + ModifiedBy: info.StatusInfo.PublishingApprovalUpdater, + }, + UnpublishingApprovalStatus: entity.SpecificStatus{}, + PublishedStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.PublishedReason, + LastUpdated: info.StatusInfo.PublishedUpdateTime, + ModifiedBy: info.StatusInfo.PublishedUpdater, + }, + UnpublishedStatus: entity.UnpublishedStatus{ + Reason: info.StatusInfo.UnpublishedReason, + LastUpdated: info.StatusInfo.UnpublishedUpdateTime, + ModifiedBy: info.StatusInfo.UnpublishedUpdater, + Type: info.StatusInfo.UnpublishedType, + }, + RequestStatus: entity.SpecificStatus{}, + ApprovalStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.ApprovalReason, + LastUpdated: info.StatusInfo.ApprovalUpdateTime, + ModifiedBy: info.StatusInfo.ApprovalUpdater, + }, + ActionStatus: entity.SpecificStatus{ + Reason: info.StatusInfo.ActionReason, + LastUpdated: info.StatusInfo.ActionUpdateTime, + ModifiedBy: info.StatusInfo.ActionUpdater, + }, + //todo 这是个啥 + //ApplyStatus: + DeveloperID: info.DeveloperId, + GroupID: info.GroupId, + Created: info.CreateTime, + CreatedBy: info.CreatedBy, + CustomData: *mtr.CovertBuildInfoToCustomDataInfoEntity(&info.BuildInfo, info.DetailDesc), + CoreDescription: info.Desc, + Expire: info.ExpireTime, + IsRollback: info.IsRollback, + TestInfo: entity.TestInfo{}, + NeedAutoPub: info.AutoPub, + InGrayRelease: info.InGrayRelease, + AppBuildID: info.BuildInfoId, + } + json.Unmarshal([]byte(info.TestInfo), &result.TestInfo) + return result +} + +func (mtr *SqlTranslator) CovertAppVerToAppVerV2(info *sql.AppVersion) *sql.AppVersionV2 { + if info == nil { + return nil + } + result := &sql.AppVersionV2{ + AppId: info.AppId, + Name: info.Name, + Class: info.Class, + Tag: info.Tag, + AppType: info.AppType, + Version: info.Version, + Sequence: info.Sequence, + Logo: info.Logo, + DeveloperId: info.DeveloperId, + GroupId: info.GroupId, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + CreatedBy: info.CreatedBy, + Desc: info.Desc, + DetailDesc: info.DetailDesc, + ExpireTime: info.ExpireTime, + IsRollback: info.IsRollback, + TestInfo: info.TestInfo, + AutoPub: info.AutoPub, + InGrayRelease: info.InGrayRelease, + BuildInfoId: info.BuildInfoId, + Ext: info.Ext, + } + + return result +} + +func (mtr *SqlTranslator) CovertBuildInfoToEntity(info *sql.AppBuildInfo) *entity.AppBuildInfo { + if info == nil { + return nil + } + result := entity.AppBuildInfo{ + Id: info.TraceId, + BuildInfoId: info.BuildInfoId, + Source: info.Source, + AppID: info.AppId, + GroupID: info.GroupID, + Created: info.CreateTime, + UserId: info.UserId, + CreatedBy: info.CreatedBy, + CustomData: entity.CustomDataInfo{ + DetailDescription: "", + VersionDescription: info.VersionDescription, + Developer: info.CreatedBy, + SourceFile: []entity.CustomDataSourceFile{}, + }, + Version: info.Version, + //VersionDescription: info.VersionDescription, + StartParams: entity.AppStartParams{ + PathAndQuery: info.PathAndQuery, + }, + Status: info.Status, + } + result.CustomData.SourceFile = make([]entity.CustomDataSourceFile, 0) + item := entity.CustomDataSourceFile{ + FileMd5: info.FileMd5, + Name: info.Name, + SourceFileUrl: info.SourceFileUrl, + UploadDate: info.CreateTime, + Url: info.Url, + EncryptedUrl: info.EncryptedUrl, + EncryptedFileMd5: info.EncryptedFileMd5, + EncryptedFileSha256: info.EncryptedFileSha256, + BasicPackVer: info.BasicPackVer, + } + if info.Packages != "" { + json.Unmarshal([]byte(info.Packages), &item.Packages) + } else { + item.Packages = make([]entity.Package, 0) + } + if info.EncryptPackages != "" { + json.Unmarshal([]byte(info.EncryptPackages), &item.EncryptPackages) + } else { + item.EncryptPackages = make([]entity.Package, 0) + } + result.CustomData.SourceFile = append(result.CustomData.SourceFile, item) + return &result +} + +func (mtr *SqlTranslator) CovertBuildInfoToSql(info *entity.AppBuildInfo) *sql.AppBuildInfo { + if info == nil { + return nil + } + result := sql.AppBuildInfo{ + TraceId: info.Id, + BuildInfoId: info.BuildInfoId, + Source: info.Source, + AppId: info.AppID, + GroupID: info.GroupID, + UserId: info.UserId, + CreatedBy: info.CreatedBy, + CreateTime: info.Created, + Status: info.Status, + Version: info.Version, + VersionDescription: info.CustomData.VersionDescription, + } + var item = entity.CustomDataSourceFile{} + if len(info.CustomData.SourceFile) > 0 { + item = info.CustomData.SourceFile[0] + } + result.FileMd5 = item.FileMd5 + result.Name = item.Name + result.SourceFileUrl = item.SourceFileUrl + result.Url = item.Url + result.EncryptedUrl = item.EncryptedUrl + result.EncryptedFileMd5 = item.EncryptedFileMd5 + result.EncryptedFileSha256 = item.EncryptedFileSha256 + result.BasicPackVer = item.BasicPackVer + + packagesByte, _ := json.Marshal(item.Packages) + result.Packages = string(packagesByte) + + encryptPackagesByte, _ := json.Marshal(item.EncryptPackages) + result.EncryptPackages = string(encryptPackagesByte) + + result.PathAndQuery = info.StartParams.PathAndQuery + + return &result +} + +func (mtr *SqlTranslator) CovertBuildInfoToCustomDataInfoEntity(info *sql.AppBuildInfo, DetailDesc string) *entity.CustomDataInfo { + if info == nil { + return nil + } + result := entity.CustomDataInfo{ + DetailDescription: DetailDesc, + SourceFile: make([]entity.CustomDataSourceFile, 0), + VersionDescription: info.VersionDescription, + Developer: info.CreatedBy, + } + result.SourceFile = make([]entity.CustomDataSourceFile, 0) + item := entity.CustomDataSourceFile{ + FileMd5: info.FileMd5, + Name: info.Name, + SourceFileUrl: info.SourceFileUrl, + UploadDate: info.CreateTime, + Url: info.Url, + EncryptedUrl: info.EncryptedUrl, + EncryptedFileMd5: info.EncryptedFileMd5, + EncryptedFileSha256: info.EncryptedFileSha256, + BasicPackVer: info.BasicPackVer, + } + if info.Packages != "" { + json.Unmarshal([]byte(info.Packages), &item.Packages) + } else { + item.Packages = make([]entity.Package, 0) + } + if info.EncryptPackages != "" { + json.Unmarshal([]byte(info.EncryptPackages), &item.EncryptPackages) + } else { + item.EncryptPackages = make([]entity.Package, 0) + } + result.SourceFile = append(result.SourceFile, item) + return &result +} + +func (mtr *SqlTranslator) CovertPrivacySettingInfoToSql(info *entity.PrivacySettingInfo) *sql.PrivacySettingInfo { + if info == nil { + return nil + } + result := sql.PrivacySettingInfo{ + AppId: info.AppId, + CommitType: info.CommitType, + UserMessageType: info.UserMessageType, + SdkMessage: info.SdkMessage, + ContactInfoPhone: info.ContactInfoPhone, + ContactInfoEmail: info.ContactInfoEmail, + ContactInfoWeChat: info.ContactInfoWeChat, + ContactInfoOther: info.ContactInfoOther, + FixedStorageTime: info.FixedStorageTime, + IsShortestTime: info.IsShortestTime, + AdditionalDocName: info.AdditionalDocName, + AdditionalDocNetDiskId: info.AdditionalDocNetDiskId, + AdditionalDocContent: info.AdditionalDocContent, + IsFirstSave: info.IsFirstSave, + EffectiveTime: info.EffectiveTime, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + } + return &result +} + +func (mtr *SqlTranslator) CovertPrivacySettingInfoToEntity(info *sql.PrivacySettingInfo) *entity.PrivacySettingInfo { + if info == nil { + return nil + } + result := entity.PrivacySettingInfo{ + AppId: info.AppId, + CommitType: info.CommitType, + UserMessageType: info.UserMessageType, + SdkMessage: info.SdkMessage, + ContactInfoPhone: info.ContactInfoPhone, + ContactInfoEmail: info.ContactInfoEmail, + ContactInfoWeChat: info.ContactInfoWeChat, + ContactInfoOther: info.ContactInfoOther, + FixedStorageTime: info.FixedStorageTime, + IsShortestTime: info.IsShortestTime, + AdditionalDocName: info.AdditionalDocName, + AdditionalDocNetDiskId: info.AdditionalDocNetDiskId, + AdditionalDocContent: info.AdditionalDocContent, + IsFirstSave: info.IsFirstSave, + EffectiveTime: info.EffectiveTime, + CreateTime: info.CreateTime, + UpdateTime: info.UpdateTime, + } + return &result +} diff --git a/infrastructure/go-resty/go_resty.go b/infrastructure/go-resty/go_resty.go new file mode 100644 index 0000000..3dd29e8 --- /dev/null +++ b/infrastructure/go-resty/go_resty.go @@ -0,0 +1,37 @@ +package goResty + +import ( + "net" + "net/http" + "time" + + "github.com/go-resty/resty/v2" +) + +var headers = map[string]string{ + "Accept": "application/json, text/plain, */*", + "Content-Type": "application/json", +} + +var RestyClient = resty.NewWithClient(&http.Client{ + Transport: createTransport(nil), +}) + +func createTransport(localAddr net.Addr) *http.Transport { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + if localAddr != nil { + dialer.LocalAddr = localAddr + } + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer.DialContext, + MaxIdleConns: 200, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + MaxIdleConnsPerHost: 200, + } +} diff --git a/infrastructure/infrastructure.go b/infrastructure/infrastructure.go new file mode 100644 index 0000000..d7602fe --- /dev/null +++ b/infrastructure/infrastructure.go @@ -0,0 +1,23 @@ +package infrastructure + +/** + * DDD: infrastructure 基础实施层是最底层(但与所有层进行交互)。 + * 向其他层提供通用的技术能力(比如工具类,第三方库类支持,常用基本配置,数据访问底层实现) + * 基础实施层主要包含以下的内容: + * 为应用层传递消息(比如通知) + * 为领域层提供持久化机制(最底层的实现) + * 为用户界面层提供组件配置 + * 基础设施层还能够通过架构框架来支持四个层次间的交互模式。 + **/ + +/** +* 1、站在领域层更过关心领域逻辑的层面,仓储作为领域层和基础结构层的连接组件, +* 使得领域层不必过多的关注存储细节。在设计时,将仓储接口放在领域层, +* 而将仓储的具体实现放在基础结构层,领域层通过接口访问数据存储, +* 而不必过多的关注仓储存储数据的细节(也就是说领域层不必关心你用mongo还是pg来存储数据), +* 这样使得领域层将更多的关注点放在领域逻辑上面。 + +* 2、仓储解耦了领域层和ORM之间的联系,这一点也就是很多人设计仓储模式的原因, +* 比如我们要更换存储框架,我们只需要改变仓储的实现即可(例如:mongo改成pg), +* 对于领域层和仓储的接口基本不需要做任何改变。 +**/ diff --git a/infrastructure/kafka/consumer.go b/infrastructure/kafka/consumer.go new file mode 100644 index 0000000..bb79020 --- /dev/null +++ b/infrastructure/kafka/consumer.go @@ -0,0 +1,97 @@ +package kafka + +import ( + "context" + "finclip-app-manager/infrastructure/config" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/Shopify/sarama" + cluster "github.com/bsm/sarama-cluster" + "gitlab.finogeeks.club/finclip-backend/apm" +) + +type ConsumerCallbackHandler func(ctx context.Context, input []byte) error //使用者需要自定义该回调函数实现体 + +func StartKafakClusterClient(kafkaAddr, topic, group string, handler ConsumerCallbackHandler) { + version, err := sarama.ParseKafkaVersion(config.GetConfig().KafkaVersion) + if err != nil { + log.Errorln("kafka err:" + err.Error()) + return + } + kafkaConfig := cluster.NewConfig() + kafkaConfig.Consumer.Return.Errors = true + kafkaConfig.Group.Return.Notifications = true + kafkaConfig.Consumer.Offsets.Initial = sarama.OffsetNewest //OffsetOldest OffsetNewest + kafkaConfig.Consumer.Offsets.CommitInterval = 1 * time.Second + kafkaConfig.Version = version + if config.GetConfig().KafkaUser != "" && config.GetConfig().KafkaPwd != "" { + kafkaConfig.Net.SASL.Enable = true + kafkaConfig.Net.SASL.User = config.Cfg.KafkaUser + kafkaConfig.Net.SASL.Password = config.Cfg.KafkaPwd + kafkaConfig.Net.SASL.Handshake = true + if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA256 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA256} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256 + } else if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA512 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA512} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512 + } else { + kafkaConfig.Net.SASL.Mechanism = sarama.SASLMechanism(config.GetConfig().KafkaMechanism) + } + } + var consumer *cluster.Consumer + for { + var err error + consumer, err = cluster.NewConsumer(strings.Split(kafkaAddr, ","), group, strings.Split(topic, ","), kafkaConfig) + if err != nil { + log.Errorln("Failed to start kafka consumer,err:" + err.Error()) + time.Sleep(time.Millisecond * 5000) + continue + } else { + break + } + } + + defer consumer.Close() + + // Create signal channel + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) + + log.Debugln("Sarama consumer up and running!...") + + // Consume all channels, wait for signal to exit + for { + select { + case msg, more := <-consumer.Messages(): + if more { + func() { + span, ctx := apm.ApmClient().CreateKafkaEntrySpan(context.Background(), msg.Topic, "handler", msg) + defer span.End() + consumer.MarkOffset(msg, "") + log.Debugf("Message claimed: value = %s, timestamp = %v, topic = %s", string(msg.Value), msg.Timestamp, msg.Topic) + if err = handler(ctx, msg.Value); err != nil { + log.Errorln("Callback handler err:" + err.Error()) + } + }() + } + case ntf, more := <-consumer.Notifications(): + if more { + log.Debugf("Rebalanced: %+v", ntf) + } + case err, more := <-consumer.Errors(): + if more { + log.Debugln("Error:" + err.Error()) + } + case <-sigchan: + { + log.Debugln("Exit signal!") + } + return + } + } +} diff --git a/infrastructure/kafka/kafka.go b/infrastructure/kafka/kafka.go new file mode 100644 index 0000000..29cdd7e --- /dev/null +++ b/infrastructure/kafka/kafka.go @@ -0,0 +1,67 @@ +package kafka + +import ( + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/logger" + "github.com/Shopify/sarama" + cluster "github.com/bsm/sarama-cluster" +) + +var ( + log = logger.GetLogger() + producer sarama.SyncProducer + consumerConfig *cluster.Config +) + +func Start() { + + if config.GetConfig().KafkaAddr == "" { + return + } + + version, err := sarama.ParseKafkaVersion(config.GetConfig().KafkaVersion) + if err != nil { + log.Errorln("kafka err:" + err.Error()) + panic(err) + } + + kafkaConfig := sarama.NewConfig() + // 等待服务器所有副本都保存成功后的响应 + kafkaConfig.Producer.RequiredAcks = sarama.WaitForAll + // 随机的分区类型:返回一个分区器,该分区器每次选择一个随机分区 + kafkaConfig.Producer.Partitioner = sarama.NewRandomPartitioner + // 是否等待成功和失败后的响应 + kafkaConfig.Producer.Return.Successes = true + kafkaConfig.Producer.Return.Errors = true + kafkaConfig.Version = version + + if config.GetConfig().KafkaUser != "" && config.GetConfig().KafkaPwd != "" { + kafkaConfig.Net.SASL.Enable = true + kafkaConfig.Net.SASL.User = config.Cfg.KafkaUser + kafkaConfig.Net.SASL.Password = config.Cfg.KafkaPwd + kafkaConfig.Net.SASL.Handshake = true + if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA256 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA256} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256 + } else if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA512 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA512} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512 + } else { + kafkaConfig.Net.SASL.Mechanism = sarama.SASLMechanism(config.GetConfig().KafkaMechanism) + } + } + // 使用给定代理地址和配置创建一个同步生产者 + producer, err = sarama.NewSyncProducer([]string{config.GetConfig().KafkaAddr}, kafkaConfig) + if err != nil { + log.Errorln("kafka err:" + err.Error()) + panic(err) + return + } + + // 消费者共同配置 + consumerConfig = cluster.NewConfig() + consumerConfig.Consumer.Return.Errors = true + consumerConfig.Group.Return.Notifications = true + consumerConfig.Consumer.Offsets.Initial = sarama.OffsetOldest + consumerConfig.Version = version +} diff --git a/infrastructure/kafka/notify.go b/infrastructure/kafka/notify.go new file mode 100644 index 0000000..928d7d8 --- /dev/null +++ b/infrastructure/kafka/notify.go @@ -0,0 +1,52 @@ +package kafka + +import ( + "context" + "encoding/json" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + uuid "github.com/satori/go.uuid" + "strings" +) + +//通知中心 +type NotifyContent struct { + Msg string `json:"msg"` + Result string `json:"result"` + Reason string `json:"reason"` + Title string `json:"title"` +} + +func GenNotifyData(ctx context.Context, organId string, t int, content NotifyContent) error { + data := make(map[string]interface{}) + data["organTraceId"] = organId + data["tab"] = "work" + data["type"] = t //1000-1999:应用市场使用,2000-2999:企业端使用,3000-3999:运营端使用 + data["content"] = content + data["id"] = uuid.NewV4().String() + + jsonBytes, _ := json.Marshal(data) + + if producer == nil { + req := &httpcall.AddNotifyReq{} + req.Id = uuid.NewV4().String() + req.Type = t + req.Content = content + req.OrganId = organId + req.Tab = "system" + err := hCaller.AddNotify(ctx, req) + return err + } + + return sendMsg(ctx, config.GetConfig().KafkaNotifyTopic, string(jsonBytes)) + +} + +func getAddrIp(address string) string { + ipArry := strings.Split(address, ",") + if len(ipArry) == 0 { + return "" + } else { + return ipArry[0] + } +} diff --git a/infrastructure/kafka/operate_log.go b/infrastructure/kafka/operate_log.go new file mode 100644 index 0000000..4575d3b --- /dev/null +++ b/infrastructure/kafka/operate_log.go @@ -0,0 +1,188 @@ +package kafka + +import ( + "context" + "encoding/json" + "finclip-app-manager/infrastructure/client/httpcall" + "finclip-app-manager/infrastructure/config" + "finclip-app-manager/infrastructure/utils" + "fmt" + "github.com/bitly/go-simplejson" + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "io/ioutil" + "strings" + "time" +) + +var ( + hCaller = httpcall.NewClient() +) + +//应用管理日志 +const ( + BIND_ADD_LOG = "新增合作应用(%s)" //新增合作应用 + BIND_UP_LOG = "修改合作应用名称(由%s修改为%s)" //修改 + BIND_STOP_COOP_LOG = "停止合作(%s)" //停止合作 + BIND_RECOVE_COOP_LOG = "恢复合作(%s)" //恢复合作 + BIND_ASS_APP_LOG = "合作应用 %s 新增关联小程序" //关联小程序 + BIND_CANCEL_ASS_APP_LOG = "合作应用 %s 取消关联小程序" //取消关联 + BIND_AUDIT_APPLY_LOG = "合作应用 %s 申请关联小程序" //关联小程序 +) + +//小程序管理日志 +const ( + APP_ADD_LOG = "创建小程序(%s-%s)" //创建小程序 + APP_SUB_REVIEW_LOG = "提交小程序审核(%s-%s)" //提交审核 + APP_CANCEL_REVIEW_LOG = "撤销小程序审核(%s-%s)" //撤销审核 + APP_PUB_LOG = "上架小程序(%s-%s,开发版本号%d)" //上架 + APP_DOWN_LOG = "下架小程序(%s-%s,开发版本号%d)" //下架 + APP_EDIT_INFO_LOG = "修改小程序详情信息成功(%s-%s)" //基本信息-编辑 + APP_EDIT_TEST_DIREC_LOG = "修改小程序测试说明成功(%s-%s)" //测试说明-编辑 +) + +func GenContent(s string, v ...interface{}) string { + return fmt.Sprintf(s, v...) +} + +//关联/取消关连小程序 +func GenContentAssApp(s string, bindName string, m map[string]string) string { + str := fmt.Sprintf(s, bindName) + mLen := len(m) + i := 1 + for k, v := range m { + if i != mLen { + i += 1 + str += fmt.Sprintf("%s-%s、", v, k) + } else { + str += fmt.Sprintf("%s-%s", v, k) + } + } + return str +} + +type OperateData struct { + Id string `json:"id"` + CreateTime int64 `json:"createTime"` + Operator string `json:"operator"` + IP string `json:"IP"` + Content string `json:"content"` + Url string `json:"url"` + OrganId string `json:"organId"` + Header interface{} `json:"header"` + Body interface{} `json:"body"` + Query interface{} `json:"query"` + Extra interface{} `json:"extra"` +} + +//操作日志 +func GenOperateData(ctx context.Context, c *gin.Context, organId, content string, extra interface{}, oper string) error { + if producer == nil { + return nil + } + var data OperateData + data.Id = uuid.NewV4().String() + data.CreateTime = time.Now().UnixNano() / 1000000 + data.Operator = oper + if data.Operator == "" { + account, err := utils.DesEcbDecrypt(c.GetHeader("user-account")) + if err != nil || account == "" { + data.Operator = c.GetHeader("user-account") + } else { + data.Operator = account + } + } + data.IP = c.Request.Header.Get("X-Real-Ip") + + if data.IP == "" { + ip := strings.Split(c.Request.RemoteAddr, ":") + fmt.Println("ip", ip) + if len(ip) != 0 { + data.IP = ip[0] + } + } + data.Content = content + data.Url = c.Request.RequestURI + data.OrganId = organId + data.Header = c.Request.Header + body, _ := ioutil.ReadAll(c.Request.Body) + data.Body, _ = simplejson.NewJson(body) + data.Extra = extra + fmt.Println("data", data) + + jsonBytes, _ := json.Marshal(data) + return sendMsg(ctx, config.GetConfig().KafkaDataLogTopic, string(jsonBytes)) + +} + +//操作日志 +type GenOperateDataV2Req struct { + OrganId string + Content string + Extra interface{} + Oper string + AccountId string + IsDev bool +} + +func GenOperateDataV2(ctx context.Context, c *gin.Context, req GenOperateDataV2Req) error { + if producer == nil { + return nil + } + var data OperateData + data.Id = uuid.NewV4().String() + data.CreateTime = time.Now().UnixNano() / 1000000 + if req.AccountId != "" { + account, err := getAccountById(ctx, req.AccountId, req.IsDev) + if err == nil { + data.Operator = account + } + } + if data.Operator == "" { + data.Operator = req.Oper + if data.Operator == "" { + account, err := utils.DesEcbDecrypt(c.GetHeader("user-account")) + if err != nil || account == "" { + data.Operator = c.GetHeader("user-account") + } else { + data.Operator = account + } + //data.Operator = c.GetHeader("user-account") + } + } + //data.IP = getAddrIp(c.Request.Header.Get("X-Forwarded-For")) + data.IP = c.Request.Header.Get("X-Real-Ip") + if data.IP == "" { + ip := strings.Split(c.Request.RemoteAddr, ":") + if len(ip) != 0 { + data.IP = ip[0] + } + } + data.Content = req.Content + data.Url = c.Request.RequestURI + data.OrganId = req.OrganId + data.Header = c.Request.Header + body, _ := ioutil.ReadAll(c.Request.Body) + data.Body, _ = simplejson.NewJson(body) + data.Extra = req.Extra + + jsonBytes, _ := json.Marshal(data) + + //return sendMsg("mop_operation_log", string(jsonBytes)) + return sendMsg(ctx, config.GetConfig().KafkaDataLogTopic, string(jsonBytes)) + +} + +func getAccountById(ctx context.Context, id string, isDev bool) (string, error) { + if isDev { + accountInfo, err := hCaller.GetAccountInfo(ctx, id) + if accountInfo != nil { + return accountInfo.Account, err + } + } + accountInfo, err := hCaller.GetAdminAccountInfo(ctx, id) + if accountInfo == nil { + return "", err + } + return accountInfo.Account, err +} diff --git a/infrastructure/kafka/producer.go b/infrastructure/kafka/producer.go new file mode 100644 index 0000000..cf47b57 --- /dev/null +++ b/infrastructure/kafka/producer.go @@ -0,0 +1,76 @@ +package kafka + +import ( + "context" + "sync" + + "finclip-app-manager/infrastructure/config" + + "github.com/Shopify/sarama" + + "gitlab.finogeeks.club/finclip-backend/apm" +) + +var ( + once sync.Once +) + +func initProducerKafka() { + version, err := sarama.ParseKafkaVersion(config.GetConfig().KafkaVersion) + if err != nil { + log.Errorln("kafka err:" + err.Error()) + return + } + + kafkaConfig := sarama.NewConfig() + // 等待服务器所有副本都保存成功后的响应 + kafkaConfig.Producer.RequiredAcks = sarama.WaitForAll + // 随机的分区类型:返回一个分区器,该分区器每次选择一个随机分区 + kafkaConfig.Producer.Partitioner = sarama.NewRandomPartitioner + // 是否等待成功和失败后的响应 + kafkaConfig.Producer.Return.Successes = true + kafkaConfig.Version = version + if config.GetConfig().KafkaUser != "" && config.GetConfig().KafkaPwd != "" { + kafkaConfig.Net.SASL.Enable = true + kafkaConfig.Net.SASL.User = config.Cfg.KafkaUser + kafkaConfig.Net.SASL.Password = config.Cfg.KafkaPwd + kafkaConfig.Net.SASL.Handshake = true + if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA256 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA256} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256 + } else if config.GetConfig().KafkaMechanism == sarama.SASLTypeSCRAMSHA512 { + kafkaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA512} } + kafkaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512 + } else { + kafkaConfig.Net.SASL.Mechanism = sarama.SASLMechanism(config.GetConfig().KafkaMechanism) + } + } + // 使用给定代理地址和配置创建一个同步生产者 + producer, err = sarama.NewSyncProducer([]string{config.GetConfig().KafkaAddr}, kafkaConfig) + if err != nil { + panic(err) + } +} + +func sendMsg(ctx context.Context, topic, value string) error { + once.Do(initProducerKafka) + + msg := &sarama.ProducerMessage{ + Topic: topic, + } + + span := apm.ApmClient().CreateKafkaExitSpan(ctx, topic, "SendKafkaMsg", config.GetConfig().KafkaAddr, msg) + defer span.End() + + //将字符串转换为字节数组 + msg.Value = sarama.ByteEncoder(value) + _, _, err := producer.SendMessage(msg) + + if err != nil { + log.Errorf("Send kafka[%s] message[%s], err:%s,", topic, value, err.Error()) + return err + } + + log.Infof("Send kafka[%s] message success, msg=%s", topic, value) + return nil +} diff --git a/infrastructure/kafka/scram_client.go b/infrastructure/kafka/scram_client.go new file mode 100644 index 0000000..1657458 --- /dev/null +++ b/infrastructure/kafka/scram_client.go @@ -0,0 +1,37 @@ +package kafka + +import ( + "crypto/sha256" + "crypto/sha512" + + "github.com/xdg-go/scram" +) + +var ( + SHA256 scram.HashGeneratorFcn = sha256.New + SHA512 scram.HashGeneratorFcn = sha512.New +) + +type XDGSCRAMClient struct { + *scram.Client + *scram.ClientConversation + scram.HashGeneratorFcn +} + +func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) { + x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID) + if err != nil { + return err + } + x.ClientConversation = x.Client.NewConversation() + return nil +} + +func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) { + response, err = x.ClientConversation.Step(challenge) + return +} + +func (x *XDGSCRAMClient) Done() bool { + return x.ClientConversation.Done() +} diff --git a/infrastructure/kafka/tam.go b/infrastructure/kafka/tam.go new file mode 100644 index 0000000..dd377c9 --- /dev/null +++ b/infrastructure/kafka/tam.go @@ -0,0 +1,56 @@ +package kafka + +import ( + "context" + "encoding/json" + "finclip-app-manager/infrastructure/config" + uuid "github.com/satori/go.uuid" + "time" +) + +//tam备案 +type TamRecordContent struct { + OrganId string `json:"organId"` //机构id + OrganName string `json:"organName"` //机构名称 + SocialCreditCode string `json:"socialCreditCode"` //社会信用代码 + OrganType string `json:"organType"` //机构类型 + OrganProperty string `json:"organProperty"` //机构性质 + Address string `json:"address"` //地址 + Phone string `json:"phone"` //电话 + Email string `json:"email"` //email + Website string `json:"website"` //网址 + Foundation string `json:"foundation"` //成立时间 +} + +type TamBaseContent struct { + Id string `json:"id"` //业务层防止重复消费 + DataType int `json:"dataType"` //数据类型,1:备案;2:异常数据上报 + Data TamRecordContent `json:"data"` +} + +func GenTamRecordContentData(ctx context.Context, organId, owner, socialCreditCode string) error { + if producer == nil { + return nil + } + + var tamBaseContent TamBaseContent + tamBaseContent.Id = uuid.NewV4().String() + tamBaseContent.DataType = 1 + tamBaseContent.Data.OrganId = organId + tamBaseContent.Data.OrganName = owner + tamBaseContent.Data.SocialCreditCode = socialCreditCode //需要改造成应用所属企业社会编码 + tamBaseContent.Data.OrganType = "2" + tamBaseContent.Data.OrganProperty = "1" + tamBaseContent.Data.Address = "深圳市南山区侨香路4080号·侨城坊1栋26~33楼" + tamBaseContent.Data.Phone = "0755-8318 3333" + tamBaseContent.Data.Email = "ccs@sscc.com" + tamBaseContent.Data.Website = "https://open.fdep.cn/#/" + + nowTime := time.Now().UnixNano() / 1000000 + timeFormat := "2006-01-02 15:04:05" + tamBaseContent.Data.Foundation = time.Unix(nowTime/1000, 0).Format(timeFormat) + + jsonBytes, _ := json.Marshal(tamBaseContent) + + return sendMsg(ctx, config.GetConfig().KafkaTamTopic, string(jsonBytes)) +} diff --git a/infrastructure/logger/log.go b/infrastructure/logger/log.go new file mode 100644 index 0000000..f761cad --- /dev/null +++ b/infrastructure/logger/log.go @@ -0,0 +1,326 @@ +package logger + +import ( + "encoding/json" + "fmt" + "log" + "os" + "runtime" + "strconv" + "strings" + "time" + + "finclip-app-manager/infrastructure/config" + "github.com/Shopify/sarama" +) + +var logProducer sarama.AsyncProducer + +type LogContent struct { + LogName string `json:"logger_name"` + LogLevel string `json:"loglevel"` + Message string `json:"message"` + Class string `json:"class"` + Host string `json:"host"` + File string `json:"file"` + Method string `json:"method"` + LineNumber string `json:"line_number"` + ThreadName string `json:"thread_name"` + AppName string `json:"Appname"` + ProjectName string `json:"projectname"` + Timestamp string `json:"timestamp"` +} + +func init() { + if config.GetConfig().OpenKafkaLog { + kafkaConfig := sarama.NewConfig() + kafkaConfig.Producer.RequiredAcks = sarama.WaitForLocal + kafkaConfig.Producer.Compression = sarama.CompressionSnappy + kafkaConfig.Producer.Flush.Frequency = 500 * time.Millisecond + + var err error + addrs := strings.Split(config.GetConfig().KafkaAddr, ",") + logProducer, err = sarama.NewAsyncProducer(addrs, kafkaConfig) + if err != nil { + panic(err) + } + fmt.Println("log kafka init succ ...") + } +} + +func getLogInfo() (string, string, string) { + _, file, line, ok := runtime.Caller(3) + if !ok { + file = "???" + line = 0 + } else { + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break + } + } + file = short + } + + pc := make([]uintptr, 1) + runtime.Callers(4, pc) + f := runtime.FuncForPC(pc[0]) + return file, f.Name(), strconv.Itoa(line) +} + +func getLogUtcTime() string { + t := time.Now().Format("2006-01-02 15:04:05") + loc, _ := time.ParseInLocation("2006-01-02 15:04:05", t, time.Local) + return loc.UTC().Format("2006-01-02T15:04:05.000Z") +} + +func pullLogToKafka(logStr, logLevel string) error { + if config.GetConfig().OpenKafkaLog { + file, function, line := getLogInfo() + content := LogContent{} + content.LogName = config.GetConfig().ServerName + ".log" + content.LogLevel = logLevel + content.Message = logStr + content.Class = "test_class" + content.Host = "127.0.0.1" + content.File = file + content.Method = function + content.LineNumber = line + content.ThreadName = "test_thread_name" + content.AppName = config.GetConfig().ServerName + content.ProjectName = config.GetConfig().ServerName + content.Timestamp = getLogUtcTime() + + valueByte, _ := json.Marshal(content) + + logProducer.Input() <- &sarama.ProducerMessage{ + Topic: config.GetConfig().LogTopic, + Value: sarama.ByteEncoder(string(valueByte)), + } + } + return nil +} + +// Logger is the server logger +type Logger struct { + logger *log.Logger + debug bool + trace bool + file bool + infoLabel string + errorLabel string + fatalLabel string + debugLabel string + traceLabel string +} + +// NewStdLogger creates a logger with output directed to Stderr +func NewStdLogger(time, file, debug, trace, colors, pid bool) *Logger { + flags := 0 + if time { + flags = log.LstdFlags | log.Lmicroseconds + } + + pre := "" + if pid { + pre = pidPrefix() + } + + l := &Logger{ + logger: log.New(os.Stdout, pre, flags), + debug: debug, + trace: trace, + file: file, + } + + if colors { + setColoredLabelFormats(l) + } else { + setPlainLabelFormats(l) + } + + return l +} + +// NewFileLogger creates a logger with output directed to a file +func NewFileLogger(filename string, time, file, debug, trace, pid bool) *Logger { + fileflags := os.O_WRONLY | os.O_APPEND | os.O_CREATE + f, err := os.OpenFile(filename, fileflags, 0660) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + + flags := 0 + if time { + flags = log.LstdFlags | log.Lmicroseconds + } + + pre := "" + if pid { + pre = pidPrefix() + } + + l := &Logger{ + logger: log.New(f, pre, flags), + debug: debug, + trace: trace, + file: file, + } + + setPlainLabelFormats(l) + return l +} + +// Generate the pid prefix string +func pidPrefix() string { + return fmt.Sprintf("[%d] ", os.Getpid()) +} + +func setPlainLabelFormats(l *Logger) { + l.infoLabel = "[INF]" + l.debugLabel = "[DBG]" + l.errorLabel = "[ERR]" + l.fatalLabel = "[FTL]" + l.traceLabel = "[TRC]" +} + +func setColoredLabelFormats(l *Logger) { + colorFormat := "[\x1b[%dm%s\x1b[0m]" + l.infoLabel = fmt.Sprintf(colorFormat, 32, "INF") + l.debugLabel = fmt.Sprintf(colorFormat, 36, "DBG") + l.errorLabel = fmt.Sprintf(colorFormat, 31, "ERR") + l.fatalLabel = fmt.Sprintf(colorFormat, 31, "FTL") + l.traceLabel = fmt.Sprintf(colorFormat, 33, "TRC") +} + +// copy from go/src/log/log.go and modify by guojuntao, 2017/09/21 +// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. +func itoa(i int, wid int) string { + // Assemble decimal in reverse order. + var b [20]byte + bp := len(b) - 1 + for i >= 10 || wid > 1 { + wid-- + q := i / 10 + b[bp] = byte('0' + i - q*10) + bp-- + i = q + } + // i < 10 + b[bp] = byte('0' + i) + return string(b[bp:]) +} + +func (l *Logger) getFileLineFormat(calldepth int) string { + if l.file { + _, file, line, ok := runtime.Caller(calldepth) + if !ok { + file = "???" + line = 0 + } + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break + } + } + file = short + return " " + file + ":" + itoa(line, -1) + ":" + } + return "" +} + +// Noticef logs a notice statement +func (l *Logger) Noticef(format string, v ...interface{}) { + pullLogToKafka(fmt.Sprintf(format, v...), "NOTICE") + l.logger.Printf(l.infoLabel+l.getFileLineFormat(2)+" "+format, v...) +} + +func (l *Logger) Noticeln(v ...interface{}) { + pullLogToKafka(fmt.Sprint(v...), "NOTICE") + l.logger.Println(append([]interface{}{l.infoLabel + l.getFileLineFormat(2)}, v...)...) +} + +// Warf logs an error statement +func (l *Logger) Warf(format string, v ...interface{}) { + pullLogToKafka(fmt.Sprintf(format, v...), "WARNING") + l.logger.Printf(l.errorLabel+l.getFileLineFormat(2)+" "+format, v...) +} + +// Errorf logs an error statement +func (l *Logger) Errorf(format string, v ...interface{}) { + pullLogToKafka(fmt.Sprintf(format, v...), "ERROR") + l.logger.Printf(l.errorLabel+l.getFileLineFormat(2)+" "+format, v...) +} + +func (l *Logger) Errorln(v ...interface{}) { + pullLogToKafka(fmt.Sprint(v...), "ERROR") + l.logger.Println(append([]interface{}{l.errorLabel + l.getFileLineFormat(2)}, v...)...) +} + +// Fatalf logs a fatal error +func (l *Logger) Fatalf(format string, v ...interface{}) { + pullLogToKafka(fmt.Sprintf(format, v...), "FATAL") + l.logger.Fatalf(l.fatalLabel+l.getFileLineFormat(2)+" "+format, v...) +} + +func (l *Logger) Fatalln(v ...interface{}) { + pullLogToKafka(fmt.Sprint(v...), "FATAL") + l.logger.Fatalln(append([]interface{}{l.fatalLabel + l.getFileLineFormat(2)}, v...)...) +} + +// Debugf logs a debug statement +func (l *Logger) Debugf(format string, v ...interface{}) { + if l.debug { + pullLogToKafka(fmt.Sprintf(format, v...), "DEBUG") + l.logger.Printf(l.debugLabel+l.getFileLineFormat(2)+" "+format, v...) + } +} + +func (l *Logger) Debugln(v ...interface{}) { + if l.debug { + pullLogToKafka(fmt.Sprint(v...), "DEBUG") + l.logger.Println(append([]interface{}{l.debugLabel + l.getFileLineFormat(2)}, v...)...) + } +} + +// Infof logs a debug statement +func (l *Logger) Infof(format string, v ...interface{}) { + if l.debug { + pullLogToKafka(fmt.Sprintf(format, v...), "INFO") + l.logger.Printf(l.debugLabel+l.getFileLineFormat(2)+" "+format, v...) + } +} + +func (l *Logger) Infoln(v ...interface{}) { + if l.debug { + pullLogToKafka(fmt.Sprint(v...), "INFO") + l.logger.Println(append([]interface{}{l.debugLabel + l.getFileLineFormat(2)}, v...)...) + } +} + +// Tracef logs a trace statement +func (l *Logger) Tracef(format string, v ...interface{}) { + if l.trace { + pullLogToKafka(fmt.Sprintf(format, v...), "TRACE") + l.logger.Printf(l.traceLabel+l.getFileLineFormat(2)+" "+format, v...) + } +} + +func (l *Logger) Traceln(v ...interface{}) { + if l.trace { + pullLogToKafka(fmt.Sprint(v...), "TRACE") + l.logger.Println(append([]interface{}{l.traceLabel + l.getFileLineFormat(2)}, v...)...) + } +} + +func (l *Logger) IsDebugEnabled() bool { + return l.debug +} + +func (l *Logger) IsTraceEnabled() bool { + return l.trace +} diff --git a/infrastructure/logger/logger.go b/infrastructure/logger/logger.go new file mode 100644 index 0000000..2b7a91d --- /dev/null +++ b/infrastructure/logger/logger.go @@ -0,0 +1,41 @@ +package logger + +import ( + "encoding/json" + + "finclip-app-manager/infrastructure/config" +) + +var l *Logger + +func init() { + cfg := config.GetConfig() + + time := true + file := true + debug := cfg.DebugLog + trace := cfg.TraceLog + colors := true + pid := false + + if cfg.LogFile == "" { + l = NewStdLogger(time, file, debug, trace, colors, pid) + } else { + l = NewFileLogger(cfg.LogFile, time, file, debug, trace, pid) + } +} + +func GetLogger() *Logger { + return l +} + +type Fields map[string]interface{} + +func IJS(obj Fields) string { + jsonBytes, err := json.MarshalIndent(obj, "", " ") + if err == nil { + return string(jsonBytes) + } + + return "" +} diff --git a/infrastructure/protobuf/golang/common.pb.go b/infrastructure/protobuf/golang/common.pb.go new file mode 100644 index 0000000..fdb8dd0 --- /dev/null +++ b/infrastructure/protobuf/golang/common.pb.go @@ -0,0 +1,165 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: common.proto + +package pb + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type CommonResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error"` + Errcode string `protobuf:"bytes,2,opt,name=errcode,proto3" json:"errcode"` + Httpcode int32 `protobuf:"varint,3,opt,name=httpcode,proto3" json:"httpcode"` +} + +func (x *CommonResult) Reset() { + *x = CommonResult{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommonResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommonResult) ProtoMessage() {} + +func (x *CommonResult) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommonResult.ProtoReflect.Descriptor instead. +func (*CommonResult) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +func (x *CommonResult) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *CommonResult) GetErrcode() string { + if x != nil { + return x.Errcode + } + return "" +} + +func (x *CommonResult) GetHttpcode() int32 { + if x != nil { + return x.Httpcode + } + return 0 +} + +var File_common_proto protoreflect.FileDescriptor + +var file_common_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, + 0x70, 0x62, 0x22, 0x5a, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x74, 0x74, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x07, + 0x5a, 0x05, 0x2e, 0x2f, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_proto_rawDescOnce sync.Once + file_common_proto_rawDescData = file_common_proto_rawDesc +) + +func file_common_proto_rawDescGZIP() []byte { + file_common_proto_rawDescOnce.Do(func() { + file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData) + }) + return file_common_proto_rawDescData +} + +var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_common_proto_goTypes = []interface{}{ + (*CommonResult)(nil), // 0: pb.CommonResult +} +var file_common_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_common_proto_init() } +func file_common_proto_init() { + if File_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommonResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_proto_goTypes, + DependencyIndexes: file_common_proto_depIdxs, + MessageInfos: file_common_proto_msgTypes, + }.Build() + File_common_proto = out.File + file_common_proto_rawDesc = nil + file_common_proto_goTypes = nil + file_common_proto_depIdxs = nil +} diff --git a/infrastructure/protobuf/golang/mop_account_system_organ_request.pb.go b/infrastructure/protobuf/golang/mop_account_system_organ_request.pb.go new file mode 100644 index 0000000..07d4966 --- /dev/null +++ b/infrastructure/protobuf/golang/mop_account_system_organ_request.pb.go @@ -0,0 +1,983 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: mop_account_system_organ_request.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +//接口一 +type QueryOrganInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccountId string `protobuf:"bytes,1,opt,name=accountId,proto3" json:"accountId"` +} + +func (x *QueryOrganInfoReq) Reset() { + *x = QueryOrganInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoReq) ProtoMessage() {} + +func (x *QueryOrganInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoReq.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoReq) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{0} +} + +func (x *QueryOrganInfoReq) GetAccountId() string { + if x != nil { + return x.AccountId + } + return "" +} + +type QueryOrganInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *QueryOrganInfoRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *QueryOrganInfoRsp) Reset() { + *x = QueryOrganInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoRsp) ProtoMessage() {} + +func (x *QueryOrganInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoRsp.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryOrganInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *QueryOrganInfoRsp) GetData() *QueryOrganInfoRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +//接口二 +type GetBusinessInfoByIdReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrganTraceId string `protobuf:"bytes,1,opt,name=organTraceId,proto3" json:"organTraceId"` +} + +func (x *GetBusinessInfoByIdReq) Reset() { + *x = GetBusinessInfoByIdReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBusinessInfoByIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBusinessInfoByIdReq) ProtoMessage() {} + +func (x *GetBusinessInfoByIdReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBusinessInfoByIdReq.ProtoReflect.Descriptor instead. +func (*GetBusinessInfoByIdReq) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{2} +} + +func (x *GetBusinessInfoByIdReq) GetOrganTraceId() string { + if x != nil { + return x.OrganTraceId + } + return "" +} + +type GetBusinessInfoByIdRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *GetBusinessInfoByIdRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *GetBusinessInfoByIdRsp) Reset() { + *x = GetBusinessInfoByIdRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBusinessInfoByIdRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBusinessInfoByIdRsp) ProtoMessage() {} + +func (x *GetBusinessInfoByIdRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBusinessInfoByIdRsp.ProtoReflect.Descriptor instead. +func (*GetBusinessInfoByIdRsp) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{3} +} + +func (x *GetBusinessInfoByIdRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetBusinessInfoByIdRsp) GetData() *GetBusinessInfoByIdRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type QueryOrganInfoRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccountTraceId string `protobuf:"bytes,1,opt,name=accountTraceId,proto3" json:"accountTraceId"` + OrganTraceId string `protobuf:"bytes,2,opt,name=organTraceId,proto3" json:"organTraceId"` + AccountInfo *QueryOrganInfoRsp_DATA_ACCOUNT_INFO `protobuf:"bytes,3,opt,name=accountInfo,proto3" json:"accountInfo"` + OrganInfo *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS `protobuf:"bytes,4,opt,name=organInfo,proto3" json:"organInfo"` + AdminInfo *QueryOrganInfoRsp_DATA_ADMIN_INFO `protobuf:"bytes,5,opt,name=adminInfo,proto3" json:"adminInfo"` +} + +func (x *QueryOrganInfoRsp_DATA) Reset() { + *x = QueryOrganInfoRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoRsp_DATA) ProtoMessage() {} + +func (x *QueryOrganInfoRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoRsp_DATA.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *QueryOrganInfoRsp_DATA) GetAccountTraceId() string { + if x != nil { + return x.AccountTraceId + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA) GetOrganTraceId() string { + if x != nil { + return x.OrganTraceId + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA) GetAccountInfo() *QueryOrganInfoRsp_DATA_ACCOUNT_INFO { + if x != nil { + return x.AccountInfo + } + return nil +} + +func (x *QueryOrganInfoRsp_DATA) GetOrganInfo() *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS { + if x != nil { + return x.OrganInfo + } + return nil +} + +func (x *QueryOrganInfoRsp_DATA) GetAdminInfo() *QueryOrganInfoRsp_DATA_ADMIN_INFO { + if x != nil { + return x.AdminInfo + } + return nil +} + +type QueryOrganInfoRsp_DATA_ACCOUNT_INFO struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account"` + Phone string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone"` + CreateTime int64 `protobuf:"varint,3,opt,name=createTime,proto3" json:"createTime"` +} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) Reset() { + *x = QueryOrganInfoRsp_DATA_ACCOUNT_INFO{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoRsp_DATA_ACCOUNT_INFO) ProtoMessage() {} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoRsp_DATA_ACCOUNT_INFO.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoRsp_DATA_ACCOUNT_INFO) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{1, 0, 0} +} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) GetPhone() string { + if x != nil { + return x.Phone + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ACCOUNT_INFO) GetCreateTime() int64 { + if x != nil { + return x.CreateTime + } + return 0 +} + +type QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name"` + SocialCreditCode string `protobuf:"bytes,2,opt,name=socialCreditCode,proto3" json:"socialCreditCode"` + LicenseNetdiskId string `protobuf:"bytes,3,opt,name=licenseNetdiskId,proto3" json:"licenseNetdiskId"` + AuthorizationNetdiskId string `protobuf:"bytes,4,opt,name=authorizationNetdiskId,proto3" json:"authorizationNetdiskId"` + ReviewStatus int32 `protobuf:"varint,5,opt,name=reviewStatus,proto3" json:"reviewStatus"` +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) Reset() { + *x = QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) ProtoMessage() {} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{1, 0, 1} +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) GetSocialCreditCode() string { + if x != nil { + return x.SocialCreditCode + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) GetLicenseNetdiskId() string { + if x != nil { + return x.LicenseNetdiskId + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) GetAuthorizationNetdiskId() string { + if x != nil { + return x.AuthorizationNetdiskId + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS) GetReviewStatus() int32 { + if x != nil { + return x.ReviewStatus + } + return 0 +} + +type QueryOrganInfoRsp_DATA_ADMIN_INFO struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name"` + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity"` + Phone string `protobuf:"bytes,3,opt,name=phone,proto3" json:"phone"` +} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) Reset() { + *x = QueryOrganInfoRsp_DATA_ADMIN_INFO{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryOrganInfoRsp_DATA_ADMIN_INFO) ProtoMessage() {} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryOrganInfoRsp_DATA_ADMIN_INFO.ProtoReflect.Descriptor instead. +func (*QueryOrganInfoRsp_DATA_ADMIN_INFO) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{1, 0, 2} +} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +func (x *QueryOrganInfoRsp_DATA_ADMIN_INFO) GetPhone() string { + if x != nil { + return x.Phone + } + return "" +} + +type GetBusinessInfoByIdRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId string `protobuf:"bytes,1,opt,name=groupId,proto3" json:"groupId"` + GroupName string `protobuf:"bytes,2,opt,name=groupName,proto3" json:"groupName"` + ReviewStatus int32 `protobuf:"varint,3,opt,name=reviewStatus,proto3" json:"reviewStatus"` + SocialCreditCode string `protobuf:"bytes,4,opt,name=socialCreditCode,proto3" json:"socialCreditCode"` +} + +func (x *GetBusinessInfoByIdRsp_DATA) Reset() { + *x = GetBusinessInfoByIdRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_account_system_organ_request_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBusinessInfoByIdRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBusinessInfoByIdRsp_DATA) ProtoMessage() {} + +func (x *GetBusinessInfoByIdRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_account_system_organ_request_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBusinessInfoByIdRsp_DATA.ProtoReflect.Descriptor instead. +func (*GetBusinessInfoByIdRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_account_system_organ_request_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *GetBusinessInfoByIdRsp_DATA) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *GetBusinessInfoByIdRsp_DATA) GetGroupName() string { + if x != nil { + return x.GroupName + } + return "" +} + +func (x *GetBusinessInfoByIdRsp_DATA) GetReviewStatus() int32 { + if x != nil { + return x.ReviewStatus + } + return 0 +} + +func (x *GetBusinessInfoByIdRsp_DATA) GetSocialCreditCode() string { + if x != nil { + return x.SocialCreditCode + } + return "" +} + +var File_mop_account_system_organ_request_proto protoreflect.FileDescriptor + +var file_mop_account_system_organ_request_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x6d, 0x6f, 0x70, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0c, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x31, 0x0a, 0x11, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xba, 0x06, + 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2e, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x62, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xca, 0x05, + 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, + 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x54, 0x72, 0x61, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x49, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x2e, 0x44, + 0x41, 0x54, 0x41, 0x2e, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, + 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4f, 0x0a, + 0x09, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, 0x4f, 0x52, 0x47, + 0x53, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x52, 0x09, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x43, + 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, 0x41, 0x44, + 0x4d, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x1a, 0x5e, 0x0a, 0x0c, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, + 0x4e, 0x46, 0x4f, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x1a, 0xe0, 0x01, 0x0a, 0x16, 0x4f, 0x52, 0x47, 0x53, 0x4e, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, + 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6f, + 0x63, 0x69, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2a, + 0x0a, 0x10, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x65, 0x74, 0x64, 0x69, 0x73, 0x6b, + 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, + 0x65, 0x4e, 0x65, 0x74, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x65, 0x74, 0x64, 0x69, + 0x73, 0x6b, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x65, 0x74, 0x64, 0x69, 0x73, 0x6b, + 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x52, 0x0a, 0x0a, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, + 0x49, 0x4e, 0x46, 0x4f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x22, 0x3c, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x49, + 0x64, 0x52, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x54, 0x72, 0x61, + 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, + 0x6e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x88, 0x02, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x49, 0x64, + 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x33, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, + 0x42, 0x79, 0x49, 0x64, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x1a, 0x8e, 0x01, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x18, 0x0a, 0x07, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x6c, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, + 0x6f, 0x64, 0x65, 0x32, 0xa5, 0x01, 0x0a, 0x10, 0x4d, 0x6f, 0x70, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x40, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x71, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x49, + 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, + 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x42, 0x79, 0x49, 0x64, 0x52, 0x73, 0x70, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, + 0x2f, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_mop_account_system_organ_request_proto_rawDescOnce sync.Once + file_mop_account_system_organ_request_proto_rawDescData = file_mop_account_system_organ_request_proto_rawDesc +) + +func file_mop_account_system_organ_request_proto_rawDescGZIP() []byte { + file_mop_account_system_organ_request_proto_rawDescOnce.Do(func() { + file_mop_account_system_organ_request_proto_rawDescData = protoimpl.X.CompressGZIP(file_mop_account_system_organ_request_proto_rawDescData) + }) + return file_mop_account_system_organ_request_proto_rawDescData +} + +var file_mop_account_system_organ_request_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_mop_account_system_organ_request_proto_goTypes = []interface{}{ + (*QueryOrganInfoReq)(nil), // 0: pb.QueryOrganInfoReq + (*QueryOrganInfoRsp)(nil), // 1: pb.QueryOrganInfoRsp + (*GetBusinessInfoByIdReq)(nil), // 2: pb.GetBusinessInfoByIdReq + (*GetBusinessInfoByIdRsp)(nil), // 3: pb.GetBusinessInfoByIdRsp + (*QueryOrganInfoRsp_DATA)(nil), // 4: pb.QueryOrganInfoRsp.DATA + (*QueryOrganInfoRsp_DATA_ACCOUNT_INFO)(nil), // 5: pb.QueryOrganInfoRsp.DATA.ACCOUNT_INFO + (*QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS)(nil), // 6: pb.QueryOrganInfoRsp.DATA.ORGSN_INFO_WITH_STATUS + (*QueryOrganInfoRsp_DATA_ADMIN_INFO)(nil), // 7: pb.QueryOrganInfoRsp.DATA.ADMIN_INFO + (*GetBusinessInfoByIdRsp_DATA)(nil), // 8: pb.GetBusinessInfoByIdRsp.DATA + (*CommonResult)(nil), // 9: pb.CommonResult +} +var file_mop_account_system_organ_request_proto_depIdxs = []int32{ + 9, // 0: pb.QueryOrganInfoRsp.result:type_name -> pb.CommonResult + 4, // 1: pb.QueryOrganInfoRsp.data:type_name -> pb.QueryOrganInfoRsp.DATA + 9, // 2: pb.GetBusinessInfoByIdRsp.result:type_name -> pb.CommonResult + 8, // 3: pb.GetBusinessInfoByIdRsp.data:type_name -> pb.GetBusinessInfoByIdRsp.DATA + 5, // 4: pb.QueryOrganInfoRsp.DATA.accountInfo:type_name -> pb.QueryOrganInfoRsp.DATA.ACCOUNT_INFO + 6, // 5: pb.QueryOrganInfoRsp.DATA.organInfo:type_name -> pb.QueryOrganInfoRsp.DATA.ORGSN_INFO_WITH_STATUS + 7, // 6: pb.QueryOrganInfoRsp.DATA.adminInfo:type_name -> pb.QueryOrganInfoRsp.DATA.ADMIN_INFO + 0, // 7: pb.MopAccountSystem.QueryOrganInfo:input_type -> pb.QueryOrganInfoReq + 2, // 8: pb.MopAccountSystem.GetBusinessInfoById:input_type -> pb.GetBusinessInfoByIdReq + 1, // 9: pb.MopAccountSystem.QueryOrganInfo:output_type -> pb.QueryOrganInfoRsp + 3, // 10: pb.MopAccountSystem.GetBusinessInfoById:output_type -> pb.GetBusinessInfoByIdRsp + 9, // [9:11] is the sub-list for method output_type + 7, // [7:9] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_mop_account_system_organ_request_proto_init() } +func file_mop_account_system_organ_request_proto_init() { + if File_mop_account_system_organ_request_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_mop_account_system_organ_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBusinessInfoByIdReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBusinessInfoByIdRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoRsp_DATA_ACCOUNT_INFO); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoRsp_DATA_ORGSN_INFO_WITH_STATUS); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryOrganInfoRsp_DATA_ADMIN_INFO); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_account_system_organ_request_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBusinessInfoByIdRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_mop_account_system_organ_request_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mop_account_system_organ_request_proto_goTypes, + DependencyIndexes: file_mop_account_system_organ_request_proto_depIdxs, + MessageInfos: file_mop_account_system_organ_request_proto_msgTypes, + }.Build() + File_mop_account_system_organ_request_proto = out.File + file_mop_account_system_organ_request_proto_rawDesc = nil + file_mop_account_system_organ_request_proto_goTypes = nil + file_mop_account_system_organ_request_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MopAccountSystemClient is the client API for MopAccountSystem service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MopAccountSystemClient interface { + QueryOrganInfo(ctx context.Context, in *QueryOrganInfoReq, opts ...grpc.CallOption) (*QueryOrganInfoRsp, error) + GetBusinessInfoById(ctx context.Context, in *GetBusinessInfoByIdReq, opts ...grpc.CallOption) (*GetBusinessInfoByIdRsp, error) +} + +type mopAccountSystemClient struct { + cc grpc.ClientConnInterface +} + +func NewMopAccountSystemClient(cc grpc.ClientConnInterface) MopAccountSystemClient { + return &mopAccountSystemClient{cc} +} + +func (c *mopAccountSystemClient) QueryOrganInfo(ctx context.Context, in *QueryOrganInfoReq, opts ...grpc.CallOption) (*QueryOrganInfoRsp, error) { + out := new(QueryOrganInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAccountSystem/QueryOrganInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAccountSystemClient) GetBusinessInfoById(ctx context.Context, in *GetBusinessInfoByIdReq, opts ...grpc.CallOption) (*GetBusinessInfoByIdRsp, error) { + out := new(GetBusinessInfoByIdRsp) + err := c.cc.Invoke(ctx, "/pb.MopAccountSystem/GetBusinessInfoById", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MopAccountSystemServer is the server API for MopAccountSystem service. +type MopAccountSystemServer interface { + QueryOrganInfo(context.Context, *QueryOrganInfoReq) (*QueryOrganInfoRsp, error) + GetBusinessInfoById(context.Context, *GetBusinessInfoByIdReq) (*GetBusinessInfoByIdRsp, error) +} + +// UnimplementedMopAccountSystemServer can be embedded to have forward compatible implementations. +type UnimplementedMopAccountSystemServer struct { +} + +func (*UnimplementedMopAccountSystemServer) QueryOrganInfo(context.Context, *QueryOrganInfoReq) (*QueryOrganInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryOrganInfo not implemented") +} +func (*UnimplementedMopAccountSystemServer) GetBusinessInfoById(context.Context, *GetBusinessInfoByIdReq) (*GetBusinessInfoByIdRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBusinessInfoById not implemented") +} + +func RegisterMopAccountSystemServer(s *grpc.Server, srv MopAccountSystemServer) { + s.RegisterService(&_MopAccountSystem_serviceDesc, srv) +} + +func _MopAccountSystem_QueryOrganInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryOrganInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAccountSystemServer).QueryOrganInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAccountSystem/QueryOrganInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAccountSystemServer).QueryOrganInfo(ctx, req.(*QueryOrganInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAccountSystem_GetBusinessInfoById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBusinessInfoByIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAccountSystemServer).GetBusinessInfoById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAccountSystem/GetBusinessInfoById", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAccountSystemServer).GetBusinessInfoById(ctx, req.(*GetBusinessInfoByIdReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _MopAccountSystem_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.MopAccountSystem", + HandlerType: (*MopAccountSystemServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "QueryOrganInfo", + Handler: _MopAccountSystem_QueryOrganInfo_Handler, + }, + { + MethodName: "GetBusinessInfoById", + Handler: _MopAccountSystem_GetBusinessInfoById_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "mop_account_system_organ_request.proto", +} diff --git a/infrastructure/protobuf/golang/mop_app_manage_svr_request.pb.go b/infrastructure/protobuf/golang/mop_app_manage_svr_request.pb.go new file mode 100644 index 0000000..c3f7105 --- /dev/null +++ b/infrastructure/protobuf/golang/mop_app_manage_svr_request.pb.go @@ -0,0 +1,4592 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: mop_app_manage_svr_request.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +//接口一 +type RuleEngineGetAppInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` + AppId string `protobuf:"bytes,2,opt,name=appId,proto3" json:"appId"` + SdkVer string `protobuf:"bytes,3,opt,name=sdkVer,proto3" json:"sdkVer"` +} + +func (x *RuleEngineGetAppInfoReq) Reset() { + *x = RuleEngineGetAppInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuleEngineGetAppInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuleEngineGetAppInfoReq) ProtoMessage() {} + +func (x *RuleEngineGetAppInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuleEngineGetAppInfoReq.ProtoReflect.Descriptor instead. +func (*RuleEngineGetAppInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{0} +} + +func (x *RuleEngineGetAppInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *RuleEngineGetAppInfoReq) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *RuleEngineGetAppInfoReq) GetSdkVer() string { + if x != nil { + return x.SdkVer + } + return "" +} + +type Status struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason"` + LastUpdated int64 `protobuf:"varint,3,opt,name=lastUpdated,proto3" json:"lastUpdated"` + ModifiedBy string `protobuf:"bytes,4,opt,name=modifiedBy,proto3" json:"modifiedBy"` +} + +func (x *Status) Reset() { + *x = Status{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{1} +} + +func (x *Status) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *Status) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Status) GetLastUpdated() int64 { + if x != nil { + return x.LastUpdated + } + return 0 +} + +func (x *Status) GetModifiedBy() string { + if x != nil { + return x.ModifiedBy + } + return "" +} + +type SpecificStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason"` + LastUpdated int64 `protobuf:"varint,2,opt,name=lastUpdated,proto3" json:"lastUpdated"` + ModifiedBy string `protobuf:"bytes,3,opt,name=modifiedBy,proto3" json:"modifiedBy"` +} + +func (x *SpecificStatus) Reset() { + *x = SpecificStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SpecificStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SpecificStatus) ProtoMessage() {} + +func (x *SpecificStatus) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SpecificStatus.ProtoReflect.Descriptor instead. +func (*SpecificStatus) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{2} +} + +func (x *SpecificStatus) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *SpecificStatus) GetLastUpdated() int64 { + if x != nil { + return x.LastUpdated + } + return 0 +} + +func (x *SpecificStatus) GetModifiedBy() string { + if x != nil { + return x.ModifiedBy + } + return "" +} + +type MenuInfoRspDataItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id"` + Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image"` +} + +func (x *MenuInfoRspDataItem) Reset() { + *x = MenuInfoRspDataItem{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MenuInfoRspDataItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MenuInfoRspDataItem) ProtoMessage() {} + +func (x *MenuInfoRspDataItem) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MenuInfoRspDataItem.ProtoReflect.Descriptor instead. +func (*MenuInfoRspDataItem) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{3} +} + +func (x *MenuInfoRspDataItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *MenuInfoRspDataItem) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *MenuInfoRspDataItem) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +type MenuInfoRspData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total"` + List []*MenuInfoRspDataItem `protobuf:"bytes,2,rep,name=list,proto3" json:"list"` +} + +func (x *MenuInfoRspData) Reset() { + *x = MenuInfoRspData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MenuInfoRspData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MenuInfoRspData) ProtoMessage() {} + +func (x *MenuInfoRspData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MenuInfoRspData.ProtoReflect.Descriptor instead. +func (*MenuInfoRspData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{4} +} + +func (x *MenuInfoRspData) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *MenuInfoRspData) GetList() []*MenuInfoRspDataItem { + if x != nil { + return x.List + } + return nil +} + +type ApiInfoRspData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ApiName string `protobuf:"bytes,1,opt,name=apiName,proto3" json:"apiName"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url"` +} + +func (x *ApiInfoRspData) Reset() { + *x = ApiInfoRspData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApiInfoRspData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApiInfoRspData) ProtoMessage() {} + +func (x *ApiInfoRspData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApiInfoRspData.ProtoReflect.Descriptor instead. +func (*ApiInfoRspData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{5} +} + +func (x *ApiInfoRspData) GetApiName() string { + if x != nil { + return x.ApiName + } + return "" +} + +func (x *ApiInfoRspData) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type CustomData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppRuntimeDomain *AppRuntimeDomain `protobuf:"bytes,1,opt,name=appRuntimeDomain,proto3" json:"appRuntimeDomain"` + SourceFile []*SourceFileData `protobuf:"bytes,2,rep,name=sourceFile,proto3" json:"sourceFile"` + VersionDescription string `protobuf:"bytes,3,opt,name=versionDescription,proto3" json:"versionDescription"` + DetailDescription string `protobuf:"bytes,4,opt,name=detailDescription,proto3" json:"detailDescription"` + MenuInfo *MenuInfoRspData `protobuf:"bytes,5,opt,name=menuInfo,proto3" json:"menuInfo"` + ApiInfo []*ApiInfoRspData `protobuf:"bytes,6,rep,name=apiInfo,proto3" json:"apiInfo"` +} + +func (x *CustomData) Reset() { + *x = CustomData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomData) ProtoMessage() {} + +func (x *CustomData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomData.ProtoReflect.Descriptor instead. +func (*CustomData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{6} +} + +func (x *CustomData) GetAppRuntimeDomain() *AppRuntimeDomain { + if x != nil { + return x.AppRuntimeDomain + } + return nil +} + +func (x *CustomData) GetSourceFile() []*SourceFileData { + if x != nil { + return x.SourceFile + } + return nil +} + +func (x *CustomData) GetVersionDescription() string { + if x != nil { + return x.VersionDescription + } + return "" +} + +func (x *CustomData) GetDetailDescription() string { + if x != nil { + return x.DetailDescription + } + return "" +} + +func (x *CustomData) GetMenuInfo() *MenuInfoRspData { + if x != nil { + return x.MenuInfo + } + return nil +} + +func (x *CustomData) GetApiInfo() []*ApiInfoRspData { + if x != nil { + return x.ApiInfo + } + return nil +} + +type WechatLoginInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WechatOriginId string `protobuf:"bytes,1,opt,name=wechatOriginId,proto3" json:"wechatOriginId"` + ProfileUrl string `protobuf:"bytes,2,opt,name=profileUrl,proto3" json:"profileUrl"` + PhoneUrl string `protobuf:"bytes,3,opt,name=phoneUrl,proto3" json:"phoneUrl"` + PaymentUrl string `protobuf:"bytes,4,opt,name=paymentUrl,proto3" json:"paymentUrl"` + ExtUrls []*ExtUrls `protobuf:"bytes,5,rep,name=extUrls,proto3" json:"extUrls"` +} + +func (x *WechatLoginInfo) Reset() { + *x = WechatLoginInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WechatLoginInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WechatLoginInfo) ProtoMessage() {} + +func (x *WechatLoginInfo) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WechatLoginInfo.ProtoReflect.Descriptor instead. +func (*WechatLoginInfo) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{7} +} + +func (x *WechatLoginInfo) GetWechatOriginId() string { + if x != nil { + return x.WechatOriginId + } + return "" +} + +func (x *WechatLoginInfo) GetProfileUrl() string { + if x != nil { + return x.ProfileUrl + } + return "" +} + +func (x *WechatLoginInfo) GetPhoneUrl() string { + if x != nil { + return x.PhoneUrl + } + return "" +} + +func (x *WechatLoginInfo) GetPaymentUrl() string { + if x != nil { + return x.PaymentUrl + } + return "" +} + +func (x *WechatLoginInfo) GetExtUrls() []*ExtUrls { + if x != nil { + return x.ExtUrls + } + return nil +} + +type ExtUrls struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName"` + PageUrl string `protobuf:"bytes,2,opt,name=pageUrl,proto3" json:"pageUrl"` +} + +func (x *ExtUrls) Reset() { + *x = ExtUrls{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtUrls) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtUrls) ProtoMessage() {} + +func (x *ExtUrls) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtUrls.ProtoReflect.Descriptor instead. +func (*ExtUrls) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{8} +} + +func (x *ExtUrls) GetFieldName() string { + if x != nil { + return x.FieldName + } + return "" +} + +func (x *ExtUrls) GetPageUrl() string { + if x != nil { + return x.PageUrl + } + return "" +} + +type AppRuntimeDomain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Business *AppRuntimeDomain_Business `protobuf:"bytes,1,opt,name=business,proto3" json:"business"` + Service *AppRuntimeDomain_Service `protobuf:"bytes,2,opt,name=service,proto3" json:"service"` + Whitelist *AppRuntimeDomain_Whitelist `protobuf:"bytes,3,opt,name=whitelist,proto3" json:"whitelist"` + Blacklist *AppRuntimeDomain_Blacklist `protobuf:"bytes,4,opt,name=blacklist,proto3" json:"blacklist"` +} + +func (x *AppRuntimeDomain) Reset() { + *x = AppRuntimeDomain{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppRuntimeDomain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppRuntimeDomain) ProtoMessage() {} + +func (x *AppRuntimeDomain) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppRuntimeDomain.ProtoReflect.Descriptor instead. +func (*AppRuntimeDomain) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{9} +} + +func (x *AppRuntimeDomain) GetBusiness() *AppRuntimeDomain_Business { + if x != nil { + return x.Business + } + return nil +} + +func (x *AppRuntimeDomain) GetService() *AppRuntimeDomain_Service { + if x != nil { + return x.Service + } + return nil +} + +func (x *AppRuntimeDomain) GetWhitelist() *AppRuntimeDomain_Whitelist { + if x != nil { + return x.Whitelist + } + return nil +} + +func (x *AppRuntimeDomain) GetBlacklist() *AppRuntimeDomain_Blacklist { + if x != nil { + return x.Blacklist + } + return nil +} + +type SourceFileData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FileMd5 string `protobuf:"bytes,1,opt,name=fileMd5,proto3" json:"fileMd5"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"` + UploadDate int64 `protobuf:"varint,3,opt,name=uploadDate,proto3" json:"uploadDate"` + Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url"` + SourceFileUrl string `protobuf:"bytes,5,opt,name=sourceFileUrl,proto3" json:"sourceFileUrl"` + BasicPackVer string `protobuf:"bytes,6,opt,name=basicPackVer,proto3" json:"basicPackVer"` + Packages []*Package `protobuf:"bytes,7,rep,name=packages,proto3" json:"packages"` +} + +func (x *SourceFileData) Reset() { + *x = SourceFileData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SourceFileData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SourceFileData) ProtoMessage() {} + +func (x *SourceFileData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SourceFileData.ProtoReflect.Descriptor instead. +func (*SourceFileData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{10} +} + +func (x *SourceFileData) GetFileMd5() string { + if x != nil { + return x.FileMd5 + } + return "" +} + +func (x *SourceFileData) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SourceFileData) GetUploadDate() int64 { + if x != nil { + return x.UploadDate + } + return 0 +} + +func (x *SourceFileData) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *SourceFileData) GetSourceFileUrl() string { + if x != nil { + return x.SourceFileUrl + } + return "" +} + +func (x *SourceFileData) GetBasicPackVer() string { + if x != nil { + return x.BasicPackVer + } + return "" +} + +func (x *SourceFileData) GetPackages() []*Package { + if x != nil { + return x.Packages + } + return nil +} + +type Package struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Root string `protobuf:"bytes,1,opt,name=root,proto3" json:"root"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name"` + Pages []string `protobuf:"bytes,3,rep,name=pages,proto3" json:"pages"` + Independent bool `protobuf:"varint,4,opt,name=independent,proto3" json:"independent"` + Filename string `protobuf:"bytes,5,opt,name=filename,proto3" json:"filename"` + FileUrl string `protobuf:"bytes,6,opt,name=fileUrl,proto3" json:"fileUrl"` + FileMd5 string `protobuf:"bytes,7,opt,name=fileMd5,proto3" json:"fileMd5"` +} + +func (x *Package) Reset() { + *x = Package{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Package) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Package) ProtoMessage() {} + +func (x *Package) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Package.ProtoReflect.Descriptor instead. +func (*Package) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{11} +} + +func (x *Package) GetRoot() string { + if x != nil { + return x.Root + } + return "" +} + +func (x *Package) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Package) GetPages() []string { + if x != nil { + return x.Pages + } + return nil +} + +func (x *Package) GetIndependent() bool { + if x != nil { + return x.Independent + } + return false +} + +func (x *Package) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *Package) GetFileUrl() string { + if x != nil { + return x.FileUrl + } + return "" +} + +func (x *Package) GetFileMd5() string { + if x != nil { + return x.FileMd5 + } + return "" +} + +type AppInfoRspData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppClass string `protobuf:"bytes,1,opt,name=appClass,proto3" json:"appClass"` + AppId string `protobuf:"bytes,2,opt,name=appId,proto3" json:"appId"` + AppType string `protobuf:"bytes,3,opt,name=appType,proto3" json:"appType"` + CoreDescription string `protobuf:"bytes,4,opt,name=coreDescription,proto3" json:"coreDescription"` + CorporationId string `protobuf:"bytes,5,opt,name=corporationId,proto3" json:"corporationId"` + Created int64 `protobuf:"varint,6,opt,name=created,proto3" json:"created"` + CreatedBy string `protobuf:"bytes,7,opt,name=createdBy,proto3" json:"createdBy"` + CustomData *CustomData `protobuf:"bytes,8,opt,name=customData,proto3" json:"customData"` + DeveloperId string `protobuf:"bytes,9,opt,name=developerId,proto3" json:"developerId"` + GroupId string `protobuf:"bytes,10,opt,name=groupId,proto3" json:"groupId"` + GroupName string `protobuf:"bytes,11,opt,name=groupName,proto3" json:"groupName"` + InGrayRelease bool `protobuf:"varint,12,opt,name=inGrayRelease,proto3" json:"inGrayRelease"` + Logo string `protobuf:"bytes,13,opt,name=logo,proto3" json:"logo"` + Name string `protobuf:"bytes,14,opt,name=name,proto3" json:"name"` + Sequence int32 `protobuf:"varint,15,opt,name=sequence,proto3" json:"sequence"` + Version string `protobuf:"bytes,16,opt,name=version,proto3" json:"version"` + Status *Status `protobuf:"bytes,17,opt,name=status,proto3" json:"status"` + IsTemp bool `protobuf:"varint,18,opt,name=isTemp,proto3" json:"isTemp"` + IsUserLimit bool `protobuf:"varint,19,opt,name=isUserLimit,proto3" json:"isUserLimit"` + NeedCrt bool `protobuf:"varint,20,opt,name=needCrt,proto3" json:"needCrt"` + DeveloperStatus int32 `protobuf:"varint,21,opt,name=developerStatus,proto3" json:"developerStatus"` + WechatLoginInfo *WechatLoginInfo `protobuf:"bytes,22,opt,name=wechatLoginInfo,proto3" json:"wechatLoginInfo"` + AppTag []string `protobuf:"bytes,23,rep,name=appTag,proto3" json:"appTag"` + PrivacySettingType int32 `protobuf:"varint,24,opt,name=privacySettingType,proto3" json:"privacySettingType"` + ProjectType int32 `protobuf:"varint,25,opt,name=projectType,proto3" json:"projectType"` +} + +func (x *AppInfoRspData) Reset() { + *x = AppInfoRspData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppInfoRspData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppInfoRspData) ProtoMessage() {} + +func (x *AppInfoRspData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppInfoRspData.ProtoReflect.Descriptor instead. +func (*AppInfoRspData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{12} +} + +func (x *AppInfoRspData) GetAppClass() string { + if x != nil { + return x.AppClass + } + return "" +} + +func (x *AppInfoRspData) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *AppInfoRspData) GetAppType() string { + if x != nil { + return x.AppType + } + return "" +} + +func (x *AppInfoRspData) GetCoreDescription() string { + if x != nil { + return x.CoreDescription + } + return "" +} + +func (x *AppInfoRspData) GetCorporationId() string { + if x != nil { + return x.CorporationId + } + return "" +} + +func (x *AppInfoRspData) GetCreated() int64 { + if x != nil { + return x.Created + } + return 0 +} + +func (x *AppInfoRspData) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *AppInfoRspData) GetCustomData() *CustomData { + if x != nil { + return x.CustomData + } + return nil +} + +func (x *AppInfoRspData) GetDeveloperId() string { + if x != nil { + return x.DeveloperId + } + return "" +} + +func (x *AppInfoRspData) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *AppInfoRspData) GetGroupName() string { + if x != nil { + return x.GroupName + } + return "" +} + +func (x *AppInfoRspData) GetInGrayRelease() bool { + if x != nil { + return x.InGrayRelease + } + return false +} + +func (x *AppInfoRspData) GetLogo() string { + if x != nil { + return x.Logo + } + return "" +} + +func (x *AppInfoRspData) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AppInfoRspData) GetSequence() int32 { + if x != nil { + return x.Sequence + } + return 0 +} + +func (x *AppInfoRspData) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *AppInfoRspData) GetStatus() *Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *AppInfoRspData) GetIsTemp() bool { + if x != nil { + return x.IsTemp + } + return false +} + +func (x *AppInfoRspData) GetIsUserLimit() bool { + if x != nil { + return x.IsUserLimit + } + return false +} + +func (x *AppInfoRspData) GetNeedCrt() bool { + if x != nil { + return x.NeedCrt + } + return false +} + +func (x *AppInfoRspData) GetDeveloperStatus() int32 { + if x != nil { + return x.DeveloperStatus + } + return 0 +} + +func (x *AppInfoRspData) GetWechatLoginInfo() *WechatLoginInfo { + if x != nil { + return x.WechatLoginInfo + } + return nil +} + +func (x *AppInfoRspData) GetAppTag() []string { + if x != nil { + return x.AppTag + } + return nil +} + +func (x *AppInfoRspData) GetPrivacySettingType() int32 { + if x != nil { + return x.PrivacySettingType + } + return 0 +} + +func (x *AppInfoRspData) GetProjectType() int32 { + if x != nil { + return x.ProjectType + } + return 0 +} + +type RuleEngineGetAppInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *AppInfoRspData `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` //google.protobuf.Any data = 2; +} + +func (x *RuleEngineGetAppInfoRsp) Reset() { + *x = RuleEngineGetAppInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuleEngineGetAppInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuleEngineGetAppInfoRsp) ProtoMessage() {} + +func (x *RuleEngineGetAppInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuleEngineGetAppInfoRsp.ProtoReflect.Descriptor instead. +func (*RuleEngineGetAppInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{13} +} + +func (x *RuleEngineGetAppInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *RuleEngineGetAppInfoRsp) GetData() *AppInfoRspData { + if x != nil { + return x.Data + } + return nil +} + +//接口二 +type RuleEngineGetAppVerInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` + AppId string `protobuf:"bytes,2,opt,name=appId,proto3" json:"appId"` + Version int32 `protobuf:"varint,3,opt,name=version,proto3" json:"version"` + SdkVer string `protobuf:"bytes,4,opt,name=sdkVer,proto3" json:"sdkVer"` +} + +func (x *RuleEngineGetAppVerInfoReq) Reset() { + *x = RuleEngineGetAppVerInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuleEngineGetAppVerInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuleEngineGetAppVerInfoReq) ProtoMessage() {} + +func (x *RuleEngineGetAppVerInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuleEngineGetAppVerInfoReq.ProtoReflect.Descriptor instead. +func (*RuleEngineGetAppVerInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{14} +} + +func (x *RuleEngineGetAppVerInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *RuleEngineGetAppVerInfoReq) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *RuleEngineGetAppVerInfoReq) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *RuleEngineGetAppVerInfoReq) GetSdkVer() string { + if x != nil { + return x.SdkVer + } + return "" +} + +type RuleEngineGetAppVerInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *AppInfoRspData `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` //google.protobuf.Any data = 2; +} + +func (x *RuleEngineGetAppVerInfoRsp) Reset() { + *x = RuleEngineGetAppVerInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RuleEngineGetAppVerInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RuleEngineGetAppVerInfoRsp) ProtoMessage() {} + +func (x *RuleEngineGetAppVerInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RuleEngineGetAppVerInfoRsp.ProtoReflect.Descriptor instead. +func (*RuleEngineGetAppVerInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{15} +} + +func (x *RuleEngineGetAppVerInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *RuleEngineGetAppVerInfoRsp) GetData() *AppInfoRspData { + if x != nil { + return x.Data + } + return nil +} + +//接口三 +type OpenApiGetAppVerInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` + Version int32 `protobuf:"varint,2,opt,name=version,proto3" json:"version"` + SdkKey string `protobuf:"bytes,3,opt,name=sdkKey,proto3" json:"sdkKey"` + SdkVer string `protobuf:"bytes,4,opt,name=sdkVer,proto3" json:"sdkVer"` +} + +func (x *OpenApiGetAppVerInfoReq) Reset() { + *x = OpenApiGetAppVerInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OpenApiGetAppVerInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenApiGetAppVerInfoReq) ProtoMessage() {} + +func (x *OpenApiGetAppVerInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpenApiGetAppVerInfoReq.ProtoReflect.Descriptor instead. +func (*OpenApiGetAppVerInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{16} +} + +func (x *OpenApiGetAppVerInfoReq) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *OpenApiGetAppVerInfoReq) GetVersion() int32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *OpenApiGetAppVerInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *OpenApiGetAppVerInfoReq) GetSdkVer() string { + if x != nil { + return x.SdkVer + } + return "" +} + +type OpenApiGetAppVerInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *AppInfoRspData `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` //google.protobuf.Any data = 2; +} + +func (x *OpenApiGetAppVerInfoRsp) Reset() { + *x = OpenApiGetAppVerInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OpenApiGetAppVerInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenApiGetAppVerInfoRsp) ProtoMessage() {} + +func (x *OpenApiGetAppVerInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpenApiGetAppVerInfoRsp.ProtoReflect.Descriptor instead. +func (*OpenApiGetAppVerInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{17} +} + +func (x *OpenApiGetAppVerInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *OpenApiGetAppVerInfoRsp) GetData() *AppInfoRspData { + if x != nil { + return x.Data + } + return nil +} + +//接口四 +type GetOrganIdBySdkKeyReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` +} + +func (x *GetOrganIdBySdkKeyReq) Reset() { + *x = GetOrganIdBySdkKeyReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganIdBySdkKeyReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganIdBySdkKeyReq) ProtoMessage() {} + +func (x *GetOrganIdBySdkKeyReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganIdBySdkKeyReq.ProtoReflect.Descriptor instead. +func (*GetOrganIdBySdkKeyReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{18} +} + +func (x *GetOrganIdBySdkKeyReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +type GetOrganIdBySdkKeyRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *GetOrganIdBySdkKeyRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *GetOrganIdBySdkKeyRsp) Reset() { + *x = GetOrganIdBySdkKeyRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganIdBySdkKeyRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganIdBySdkKeyRsp) ProtoMessage() {} + +func (x *GetOrganIdBySdkKeyRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganIdBySdkKeyRsp.ProtoReflect.Descriptor instead. +func (*GetOrganIdBySdkKeyRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{19} +} + +func (x *GetOrganIdBySdkKeyRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetOrganIdBySdkKeyRsp) GetData() *GetOrganIdBySdkKeyRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +//接口五,批量获取小程序详情和小程序版本详情 +type BatchGetAppAndVerInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` + AppList []string `protobuf:"bytes,2,rep,name=appList,proto3" json:"appList"` + AppVerList []*BatchGetAppAndVerInfoReq_AppAndVer `protobuf:"bytes,3,rep,name=appVerList,proto3" json:"appVerList"` + SdkVer string `protobuf:"bytes,4,opt,name=sdkVer,proto3" json:"sdkVer"` +} + +func (x *BatchGetAppAndVerInfoReq) Reset() { + *x = BatchGetAppAndVerInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetAppAndVerInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetAppAndVerInfoReq) ProtoMessage() {} + +func (x *BatchGetAppAndVerInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetAppAndVerInfoReq.ProtoReflect.Descriptor instead. +func (*BatchGetAppAndVerInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{20} +} + +func (x *BatchGetAppAndVerInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *BatchGetAppAndVerInfoReq) GetAppList() []string { + if x != nil { + return x.AppList + } + return nil +} + +func (x *BatchGetAppAndVerInfoReq) GetAppVerList() []*BatchGetAppAndVerInfoReq_AppAndVer { + if x != nil { + return x.AppVerList + } + return nil +} + +func (x *BatchGetAppAndVerInfoReq) GetSdkVer() string { + if x != nil { + return x.SdkVer + } + return "" +} + +type BatchGetAppAndVerInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *BatchGetAppAndVerInfoRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *BatchGetAppAndVerInfoRsp) Reset() { + *x = BatchGetAppAndVerInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetAppAndVerInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetAppAndVerInfoRsp) ProtoMessage() {} + +func (x *BatchGetAppAndVerInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetAppAndVerInfoRsp.ProtoReflect.Descriptor instead. +func (*BatchGetAppAndVerInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{21} +} + +func (x *BatchGetAppAndVerInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *BatchGetAppAndVerInfoRsp) GetData() *BatchGetAppAndVerInfoRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type BatchAppsByIdentityReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source"` + IdentityType string `protobuf:"bytes,3,opt,name=identityType,proto3" json:"identityType"` + Apps []*BatchAppsByIdentityAppsItem `protobuf:"bytes,4,rep,name=apps,proto3" json:"apps"` +} + +func (x *BatchAppsByIdentityReq) Reset() { + *x = BatchAppsByIdentityReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchAppsByIdentityReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchAppsByIdentityReq) ProtoMessage() {} + +func (x *BatchAppsByIdentityReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchAppsByIdentityReq.ProtoReflect.Descriptor instead. +func (*BatchAppsByIdentityReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{22} +} + +func (x *BatchAppsByIdentityReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *BatchAppsByIdentityReq) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *BatchAppsByIdentityReq) GetIdentityType() string { + if x != nil { + return x.IdentityType + } + return "" +} + +func (x *BatchAppsByIdentityReq) GetApps() []*BatchAppsByIdentityAppsItem { + if x != nil { + return x.Apps + } + return nil +} + +type BatchAppsByIdentityAppsItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity"` +} + +func (x *BatchAppsByIdentityAppsItem) Reset() { + *x = BatchAppsByIdentityAppsItem{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchAppsByIdentityAppsItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchAppsByIdentityAppsItem) ProtoMessage() {} + +func (x *BatchAppsByIdentityAppsItem) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchAppsByIdentityAppsItem.ProtoReflect.Descriptor instead. +func (*BatchAppsByIdentityAppsItem) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{23} +} + +func (x *BatchAppsByIdentityAppsItem) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *BatchAppsByIdentityAppsItem) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +type BatchAppsByIdentityRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *BatchAppsByIdentityRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *BatchAppsByIdentityRsp) Reset() { + *x = BatchAppsByIdentityRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchAppsByIdentityRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchAppsByIdentityRsp) ProtoMessage() {} + +func (x *BatchAppsByIdentityRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchAppsByIdentityRsp.ProtoReflect.Descriptor instead. +func (*BatchAppsByIdentityRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{24} +} + +func (x *BatchAppsByIdentityRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *BatchAppsByIdentityRsp) GetData() *BatchAppsByIdentityRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type IdentityAppsCheckReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkKey string `protobuf:"bytes,1,opt,name=sdkKey,proto3" json:"sdkKey"` + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source"` + IdentityType string `protobuf:"bytes,3,opt,name=identityType,proto3" json:"identityType"` + Apps []*IdentityAppsCheckAppsItem `protobuf:"bytes,4,rep,name=Apps,proto3" json:"Apps"` +} + +func (x *IdentityAppsCheckReq) Reset() { + *x = IdentityAppsCheckReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckReq) ProtoMessage() {} + +func (x *IdentityAppsCheckReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckReq.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{25} +} + +func (x *IdentityAppsCheckReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *IdentityAppsCheckReq) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *IdentityAppsCheckReq) GetIdentityType() string { + if x != nil { + return x.IdentityType + } + return "" +} + +func (x *IdentityAppsCheckReq) GetApps() []*IdentityAppsCheckAppsItem { + if x != nil { + return x.Apps + } + return nil +} + +type IdentityAppsCheckAppsItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity"` +} + +func (x *IdentityAppsCheckAppsItem) Reset() { + *x = IdentityAppsCheckAppsItem{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckAppsItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckAppsItem) ProtoMessage() {} + +func (x *IdentityAppsCheckAppsItem) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckAppsItem.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckAppsItem) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{26} +} + +func (x *IdentityAppsCheckAppsItem) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *IdentityAppsCheckAppsItem) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +type IdentityAppsCheckRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *IdentityAppsCheckRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *IdentityAppsCheckRsp) Reset() { + *x = IdentityAppsCheckRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckRsp) ProtoMessage() {} + +func (x *IdentityAppsCheckRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckRsp.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{27} +} + +func (x *IdentityAppsCheckRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *IdentityAppsCheckRsp) GetData() *IdentityAppsCheckRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +//接口六 +type OpenApiGetQRcodeAppVerInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RedisKey string `protobuf:"bytes,1,opt,name=redisKey,proto3" json:"redisKey"` + SdkKey string `protobuf:"bytes,2,opt,name=sdkKey,proto3" json:"sdkKey"` +} + +func (x *OpenApiGetQRcodeAppVerInfoReq) Reset() { + *x = OpenApiGetQRcodeAppVerInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OpenApiGetQRcodeAppVerInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenApiGetQRcodeAppVerInfoReq) ProtoMessage() {} + +func (x *OpenApiGetQRcodeAppVerInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OpenApiGetQRcodeAppVerInfoReq.ProtoReflect.Descriptor instead. +func (*OpenApiGetQRcodeAppVerInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{28} +} + +func (x *OpenApiGetQRcodeAppVerInfoReq) GetRedisKey() string { + if x != nil { + return x.RedisKey + } + return "" +} + +func (x *OpenApiGetQRcodeAppVerInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +//接口七 +type GetBuildAppInfoReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type"` + SdkKey string `protobuf:"bytes,2,opt,name=sdkKey,proto3" json:"sdkKey"` + CodeId string `protobuf:"bytes,3,opt,name=codeId,proto3" json:"codeId"` +} + +func (x *GetBuildAppInfoReq) Reset() { + *x = GetBuildAppInfoReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBuildAppInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBuildAppInfoReq) ProtoMessage() {} + +func (x *GetBuildAppInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBuildAppInfoReq.ProtoReflect.Descriptor instead. +func (*GetBuildAppInfoReq) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{29} +} + +func (x *GetBuildAppInfoReq) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *GetBuildAppInfoReq) GetSdkKey() string { + if x != nil { + return x.SdkKey + } + return "" +} + +func (x *GetBuildAppInfoReq) GetCodeId() string { + if x != nil { + return x.CodeId + } + return "" +} + +type GetBuildAppInfoRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *BuildAppInfo `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *GetBuildAppInfoRsp) Reset() { + *x = GetBuildAppInfoRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBuildAppInfoRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBuildAppInfoRsp) ProtoMessage() {} + +func (x *GetBuildAppInfoRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBuildAppInfoRsp.ProtoReflect.Descriptor instead. +func (*GetBuildAppInfoRsp) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{30} +} + +func (x *GetBuildAppInfoRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetBuildAppInfoRsp) GetData() *BuildAppInfo { + if x != nil { + return x.Data + } + return nil +} + +type BuildAppInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CodeId string `protobuf:"bytes,1,opt,name=codeId,proto3" json:"codeId"` + CoreDescription string `protobuf:"bytes,2,opt,name=coreDescription,proto3" json:"coreDescription"` + Created int64 `protobuf:"varint,3,opt,name=created,proto3" json:"created"` + CreatedBy string `protobuf:"bytes,4,opt,name=createdBy,proto3" json:"createdBy"` + CustomData *CustomData `protobuf:"bytes,5,opt,name=customData,proto3" json:"customData"` + GroupId string `protobuf:"bytes,6,opt,name=groupId,proto3" json:"groupId"` + GroupName string `protobuf:"bytes,7,opt,name=groupName,proto3" json:"groupName"` + Logo string `protobuf:"bytes,8,opt,name=logo,proto3" json:"logo"` + Name string `protobuf:"bytes,9,opt,name=name,proto3" json:"name"` + Version string `protobuf:"bytes,10,opt,name=version,proto3" json:"version"` + IsTemp bool `protobuf:"varint,11,opt,name=isTemp,proto3" json:"isTemp"` + AppId string `protobuf:"bytes,12,opt,name=appId,proto3" json:"appId"` + NeedCrt bool `protobuf:"varint,13,opt,name=needCrt,proto3" json:"needCrt"` + DeveloperStatus int32 `protobuf:"varint,14,opt,name=developerStatus,proto3" json:"developerStatus"` + WechatLoginInfo *WechatLoginInfo `protobuf:"bytes,15,opt,name=wechatLoginInfo,proto3" json:"wechatLoginInfo"` + AppTag []string `protobuf:"bytes,16,rep,name=appTag,proto3" json:"appTag"` + PrivacySettingType int32 `protobuf:"varint,17,opt,name=privacySettingType,proto3" json:"privacySettingType"` + ProjectType int32 `protobuf:"varint,18,opt,name=projectType,proto3" json:"projectType"` +} + +func (x *BuildAppInfo) Reset() { + *x = BuildAppInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BuildAppInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BuildAppInfo) ProtoMessage() {} + +func (x *BuildAppInfo) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BuildAppInfo.ProtoReflect.Descriptor instead. +func (*BuildAppInfo) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{31} +} + +func (x *BuildAppInfo) GetCodeId() string { + if x != nil { + return x.CodeId + } + return "" +} + +func (x *BuildAppInfo) GetCoreDescription() string { + if x != nil { + return x.CoreDescription + } + return "" +} + +func (x *BuildAppInfo) GetCreated() int64 { + if x != nil { + return x.Created + } + return 0 +} + +func (x *BuildAppInfo) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *BuildAppInfo) GetCustomData() *CustomData { + if x != nil { + return x.CustomData + } + return nil +} + +func (x *BuildAppInfo) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *BuildAppInfo) GetGroupName() string { + if x != nil { + return x.GroupName + } + return "" +} + +func (x *BuildAppInfo) GetLogo() string { + if x != nil { + return x.Logo + } + return "" +} + +func (x *BuildAppInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *BuildAppInfo) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *BuildAppInfo) GetIsTemp() bool { + if x != nil { + return x.IsTemp + } + return false +} + +func (x *BuildAppInfo) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *BuildAppInfo) GetNeedCrt() bool { + if x != nil { + return x.NeedCrt + } + return false +} + +func (x *BuildAppInfo) GetDeveloperStatus() int32 { + if x != nil { + return x.DeveloperStatus + } + return 0 +} + +func (x *BuildAppInfo) GetWechatLoginInfo() *WechatLoginInfo { + if x != nil { + return x.WechatLoginInfo + } + return nil +} + +func (x *BuildAppInfo) GetAppTag() []string { + if x != nil { + return x.AppTag + } + return nil +} + +func (x *BuildAppInfo) GetPrivacySettingType() int32 { + if x != nil { + return x.PrivacySettingType + } + return 0 +} + +func (x *BuildAppInfo) GetProjectType() int32 { + if x != nil { + return x.ProjectType + } + return 0 +} + +type AppRuntimeDomain_Business struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *AppRuntimeDomain_Business) Reset() { + *x = AppRuntimeDomain_Business{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppRuntimeDomain_Business) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppRuntimeDomain_Business) ProtoMessage() {} + +func (x *AppRuntimeDomain_Business) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppRuntimeDomain_Business.ProtoReflect.Descriptor instead. +func (*AppRuntimeDomain_Business) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{9, 0} +} + +func (x *AppRuntimeDomain_Business) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type AppRuntimeDomain_Service struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Download []string `protobuf:"bytes,1,rep,name=download,proto3" json:"download"` + Request []string `protobuf:"bytes,2,rep,name=request,proto3" json:"request"` + Socket []string `protobuf:"bytes,3,rep,name=socket,proto3" json:"socket"` + Upload []string `protobuf:"bytes,4,rep,name=upload,proto3" json:"upload"` +} + +func (x *AppRuntimeDomain_Service) Reset() { + *x = AppRuntimeDomain_Service{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppRuntimeDomain_Service) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppRuntimeDomain_Service) ProtoMessage() {} + +func (x *AppRuntimeDomain_Service) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppRuntimeDomain_Service.ProtoReflect.Descriptor instead. +func (*AppRuntimeDomain_Service) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *AppRuntimeDomain_Service) GetDownload() []string { + if x != nil { + return x.Download + } + return nil +} + +func (x *AppRuntimeDomain_Service) GetRequest() []string { + if x != nil { + return x.Request + } + return nil +} + +func (x *AppRuntimeDomain_Service) GetSocket() []string { + if x != nil { + return x.Socket + } + return nil +} + +func (x *AppRuntimeDomain_Service) GetUpload() []string { + if x != nil { + return x.Upload + } + return nil +} + +type AppRuntimeDomain_Whitelist struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *AppRuntimeDomain_Whitelist) Reset() { + *x = AppRuntimeDomain_Whitelist{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppRuntimeDomain_Whitelist) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppRuntimeDomain_Whitelist) ProtoMessage() {} + +func (x *AppRuntimeDomain_Whitelist) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppRuntimeDomain_Whitelist.ProtoReflect.Descriptor instead. +func (*AppRuntimeDomain_Whitelist) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{9, 2} +} + +func (x *AppRuntimeDomain_Whitelist) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type AppRuntimeDomain_Blacklist struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *AppRuntimeDomain_Blacklist) Reset() { + *x = AppRuntimeDomain_Blacklist{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppRuntimeDomain_Blacklist) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppRuntimeDomain_Blacklist) ProtoMessage() {} + +func (x *AppRuntimeDomain_Blacklist) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppRuntimeDomain_Blacklist.ProtoReflect.Descriptor instead. +func (*AppRuntimeDomain_Blacklist) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{9, 3} +} + +func (x *AppRuntimeDomain_Blacklist) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetOrganIdBySdkKeyRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrganId string `protobuf:"bytes,1,opt,name=organId,proto3" json:"organId"` + IsWhite bool `protobuf:"varint,2,opt,name=isWhite,proto3" json:"isWhite"` +} + +func (x *GetOrganIdBySdkKeyRsp_DATA) Reset() { + *x = GetOrganIdBySdkKeyRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganIdBySdkKeyRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganIdBySdkKeyRsp_DATA) ProtoMessage() {} + +func (x *GetOrganIdBySdkKeyRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganIdBySdkKeyRsp_DATA.ProtoReflect.Descriptor instead. +func (*GetOrganIdBySdkKeyRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{19, 0} +} + +func (x *GetOrganIdBySdkKeyRsp_DATA) GetOrganId() string { + if x != nil { + return x.OrganId + } + return "" +} + +func (x *GetOrganIdBySdkKeyRsp_DATA) GetIsWhite() bool { + if x != nil { + return x.IsWhite + } + return false +} + +type BatchGetAppAndVerInfoReq_AppAndVer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` + Sequence int32 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence"` +} + +func (x *BatchGetAppAndVerInfoReq_AppAndVer) Reset() { + *x = BatchGetAppAndVerInfoReq_AppAndVer{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetAppAndVerInfoReq_AppAndVer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetAppAndVerInfoReq_AppAndVer) ProtoMessage() {} + +func (x *BatchGetAppAndVerInfoReq_AppAndVer) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetAppAndVerInfoReq_AppAndVer.ProtoReflect.Descriptor instead. +func (*BatchGetAppAndVerInfoReq_AppAndVer) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{20, 0} +} + +func (x *BatchGetAppAndVerInfoReq_AppAndVer) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *BatchGetAppAndVerInfoReq_AppAndVer) GetSequence() int32 { + if x != nil { + return x.Sequence + } + return 0 +} + +type BatchGetAppAndVerInfoRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppFailList []string `protobuf:"bytes,1,rep,name=appFailList,proto3" json:"appFailList"` + AppDataList []*AppInfoRspData `protobuf:"bytes,2,rep,name=appDataList,proto3" json:"appDataList"` + AppVerFailList []string `protobuf:"bytes,3,rep,name=appVerFailList,proto3" json:"appVerFailList"` + AppVerDataList []*AppInfoRspData `protobuf:"bytes,4,rep,name=appVerDataList,proto3" json:"appVerDataList"` +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) Reset() { + *x = BatchGetAppAndVerInfoRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetAppAndVerInfoRsp_DATA) ProtoMessage() {} + +func (x *BatchGetAppAndVerInfoRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetAppAndVerInfoRsp_DATA.ProtoReflect.Descriptor instead. +func (*BatchGetAppAndVerInfoRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{21, 0} +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) GetAppFailList() []string { + if x != nil { + return x.AppFailList + } + return nil +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) GetAppDataList() []*AppInfoRspData { + if x != nil { + return x.AppDataList + } + return nil +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) GetAppVerFailList() []string { + if x != nil { + return x.AppVerFailList + } + return nil +} + +func (x *BatchGetAppAndVerInfoRsp_DATA) GetAppVerDataList() []*AppInfoRspData { + if x != nil { + return x.AppVerDataList + } + return nil +} + +type BatchAppsByIdentityRsp_AppListItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Errcode string `protobuf:"bytes,1,opt,name=errcode,proto3" json:"errcode"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error"` + AppInfo *AppInfoRspData `protobuf:"bytes,3,opt,name=appInfo,proto3" json:"appInfo"` + ExternalAppStatus string `protobuf:"bytes,4,opt,name=externalAppStatus,proto3" json:"externalAppStatus"` + AppId string `protobuf:"bytes,5,opt,name=appId,proto3" json:"appId"` + Identity string `protobuf:"bytes,6,opt,name=identity,proto3" json:"identity"` +} + +func (x *BatchAppsByIdentityRsp_AppListItem) Reset() { + *x = BatchAppsByIdentityRsp_AppListItem{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchAppsByIdentityRsp_AppListItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchAppsByIdentityRsp_AppListItem) ProtoMessage() {} + +func (x *BatchAppsByIdentityRsp_AppListItem) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchAppsByIdentityRsp_AppListItem.ProtoReflect.Descriptor instead. +func (*BatchAppsByIdentityRsp_AppListItem) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{24, 0} +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetErrcode() string { + if x != nil { + return x.Errcode + } + return "" +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetAppInfo() *AppInfoRspData { + if x != nil { + return x.AppInfo + } + return nil +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetExternalAppStatus() string { + if x != nil { + return x.ExternalAppStatus + } + return "" +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *BatchAppsByIdentityRsp_AppListItem) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +type BatchAppsByIdentityRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppList []*BatchAppsByIdentityRsp_AppListItem `protobuf:"bytes,1,rep,name=appList,proto3" json:"appList"` +} + +func (x *BatchAppsByIdentityRsp_DATA) Reset() { + *x = BatchAppsByIdentityRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchAppsByIdentityRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchAppsByIdentityRsp_DATA) ProtoMessage() {} + +func (x *BatchAppsByIdentityRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchAppsByIdentityRsp_DATA.ProtoReflect.Descriptor instead. +func (*BatchAppsByIdentityRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{24, 1} +} + +func (x *BatchAppsByIdentityRsp_DATA) GetAppList() []*BatchAppsByIdentityRsp_AppListItem { + if x != nil { + return x.AppList + } + return nil +} + +type IdentityAppsCheckRsp_AppListItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Errcode string `protobuf:"bytes,1,opt,name=errcode,proto3" json:"errcode"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error"` + Data *IdentityAppsCheckRsp_AppListItem_AppListItemData `protobuf:"bytes,3,opt,name=data,proto3" json:"data"` +} + +func (x *IdentityAppsCheckRsp_AppListItem) Reset() { + *x = IdentityAppsCheckRsp_AppListItem{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckRsp_AppListItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckRsp_AppListItem) ProtoMessage() {} + +func (x *IdentityAppsCheckRsp_AppListItem) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckRsp_AppListItem.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckRsp_AppListItem) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{27, 0} +} + +func (x *IdentityAppsCheckRsp_AppListItem) GetErrcode() string { + if x != nil { + return x.Errcode + } + return "" +} + +func (x *IdentityAppsCheckRsp_AppListItem) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *IdentityAppsCheckRsp_AppListItem) GetData() *IdentityAppsCheckRsp_AppListItem_AppListItemData { + if x != nil { + return x.Data + } + return nil +} + +type IdentityAppsCheckRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppList []*IdentityAppsCheckRsp_AppListItem `protobuf:"bytes,1,rep,name=appList,proto3" json:"appList"` +} + +func (x *IdentityAppsCheckRsp_DATA) Reset() { + *x = IdentityAppsCheckRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckRsp_DATA) ProtoMessage() {} + +func (x *IdentityAppsCheckRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckRsp_DATA.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{27, 1} +} + +func (x *IdentityAppsCheckRsp_DATA) GetAppList() []*IdentityAppsCheckRsp_AppListItem { + if x != nil { + return x.AppList + } + return nil +} + +type IdentityAppsCheckRsp_AppListItem_AppListItemData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` + Identity string `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity"` + IdentityValid bool `protobuf:"varint,3,opt,name=identityValid,proto3" json:"identityValid"` +} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) Reset() { + *x = IdentityAppsCheckRsp_AppListItem_AppListItemData{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IdentityAppsCheckRsp_AppListItem_AppListItemData) ProtoMessage() {} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) ProtoReflect() protoreflect.Message { + mi := &file_mop_app_manage_svr_request_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IdentityAppsCheckRsp_AppListItem_AppListItemData.ProtoReflect.Descriptor instead. +func (*IdentityAppsCheckRsp_AppListItem_AppListItemData) Descriptor() ([]byte, []int) { + return file_mop_app_manage_svr_request_proto_rawDescGZIP(), []int{27, 0, 0} +} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +func (x *IdentityAppsCheckRsp_AppListItem_AppListItemData) GetIdentityValid() bool { + if x != nil { + return x.IdentityValid + } + return false +} + +var File_mop_app_manage_svr_request_proto protoreflect.FileDescriptor + +var file_mop_app_manage_svr_request_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x6d, 0x6f, 0x70, 0x5f, 0x61, 0x70, 0x70, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x76, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, 0x17, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x64, 0x6b, 0x56, 0x65, 0x72, 0x22, 0x78, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x20, 0x0a, + 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x79, 0x22, + 0x6a, 0x0a, 0x0e, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x61, 0x73, + 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, + 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, + 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x79, 0x22, 0x4f, 0x0a, 0x13, 0x4d, + 0x65, 0x6e, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x54, 0x0a, 0x0f, + 0x4d, 0x65, 0x6e, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6e, 0x75, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x6c, 0x69, + 0x73, 0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x41, 0x70, 0x69, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x69, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x69, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, + 0x22, 0xbf, 0x02, 0x0a, 0x0a, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x40, 0x0a, 0x10, 0x61, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x41, + 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, + 0x10, 0x61, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x12, 0x32, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x49, 0x6e, 0x66, 0x6f, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6e, 0x75, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x07, 0x61, 0x70, 0x69, 0x49, 0x6e, 0x66, 0x6f, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x69, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, 0x61, 0x70, 0x69, 0x49, 0x6e, + 0x66, 0x6f, 0x22, 0xbc, 0x01, 0x0a, 0x0f, 0x57, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0e, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1e, + 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x07, 0x65, 0x78, + 0x74, 0x55, 0x72, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, + 0x2e, 0x45, 0x78, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x52, 0x07, 0x65, 0x78, 0x74, 0x55, 0x72, 0x6c, + 0x73, 0x22, 0x41, 0x0a, 0x07, 0x45, 0x78, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x1c, 0x0a, 0x09, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, + 0x67, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x67, + 0x65, 0x55, 0x72, 0x6c, 0x22, 0xe6, 0x03, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x39, 0x0a, 0x08, 0x62, 0x75, 0x73, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x62, + 0x2e, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x12, 0x36, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x09, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, + 0x09, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x62, 0x6c, + 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x2e, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x09, 0x62, + 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x1a, 0x24, 0x0a, 0x08, 0x42, 0x75, 0x73, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x6f, + 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x1a, + 0x25, 0x0a, 0x09, 0x57, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x25, 0x0a, 0x09, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, + 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x22, 0xe3, 0x01, + 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, + 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 0x73, 0x69, 0x63, 0x50, + 0x61, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x50, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x08, 0x70, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, + 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, + 0x6f, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x67, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x67, 0x65, 0x73, 0x12, 0x20, 0x0a, + 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, + 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, + 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x22, + 0xbd, 0x06, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, + 0x70, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, + 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x72, 0x70, + 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x42, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x2e, 0x0a, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x44, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, + 0x70, 0x65, 0x72, 0x49, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x47, 0x72, 0x61, 0x79, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x47, 0x72, 0x61, 0x79, 0x52, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x6f, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x54, 0x65, + 0x6d, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x54, 0x65, 0x6d, 0x70, + 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x72, 0x74, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x0f, + 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x0a, 0x0f, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x69, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x54, 0x61, 0x67, 0x18, + 0x17, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x61, 0x70, 0x70, 0x54, 0x61, 0x67, 0x12, 0x2e, 0x0a, + 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x63, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x6b, 0x0a, 0x17, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, + 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7c, 0x0a, 0x1a, + 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, + 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, + 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x22, 0x6e, 0x0a, 0x1a, 0x52, 0x75, + 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, + 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x79, 0x0a, 0x17, 0x4f, 0x70, + 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x64, 0x6b, 0x56, 0x65, 0x72, 0x22, 0x6b, 0x0a, 0x17, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, + 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, + 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, + 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x64, + 0x42, 0x79, 0x53, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, + 0x4b, 0x65, 0x79, 0x22, 0xb1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x49, 0x64, 0x42, 0x79, 0x53, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x49, 0x64, 0x42, 0x79, 0x53, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x73, 0x70, + 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3a, 0x0a, 0x04, 0x44, + 0x41, 0x54, 0x41, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x69, 0x73, 0x57, 0x68, 0x69, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x69, 0x73, 0x57, 0x68, 0x69, 0x74, 0x65, 0x22, 0xeb, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, + 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x62, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x2e, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, + 0x65, 0x72, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x1a, 0x3d, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, + 0x56, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xc0, 0x02, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x35, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x62, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x1a, 0xc2, 0x01, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x20, 0x0a, 0x0b, + 0x61, 0x70, 0x70, 0x46, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x46, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, + 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x46, 0x61, + 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x70, + 0x70, 0x56, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0e, + 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, + 0x70, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x22, 0x4f, 0x0a, 0x1b, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x61, + 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x8f, 0x03, + 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, + 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, + 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xcb, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x4c, + 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x49, 0x6e, + 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, + 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x07, 0x61, 0x70, + 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x1a, 0x48, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x40, 0x0a, + 0x07, 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x73, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x4c, 0x69, + 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x22, + 0x9d, 0x01, 0x0a, 0x14, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x04, + 0x41, 0x70, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x62, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x41, 0x70, 0x70, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x41, 0x70, 0x70, 0x73, 0x22, + 0x4d, 0x0a, 0x19, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x41, 0x70, 0x70, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, + 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0xb0, + 0x03, 0x0a, 0x14, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x31, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, + 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0xf2, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, + 0x49, 0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x48, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x73, 0x70, 0x2e, 0x41, 0x70, 0x70, + 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, + 0x49, 0x74, 0x65, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x69, + 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x1a, 0x46, 0x0a, 0x04, 0x44, 0x41, 0x54, + 0x41, 0x12, 0x3e, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x73, 0x70, 0x2e, 0x41, 0x70, 0x70, + 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73, + 0x74, 0x22, 0x53, 0x0a, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, 0x51, + 0x52, 0x63, 0x6f, 0x64, 0x65, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x22, 0x58, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x22, 0x64, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x70, 0x70, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xcd, 0x04, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x64, 0x65, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, + 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x72, 0x65, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, + 0x79, 0x12, 0x2e, 0x0a, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x67, + 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x6f, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x69, + 0x73, 0x54, 0x65, 0x6d, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x54, + 0x65, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x65, + 0x64, 0x43, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, 0x65, 0x65, 0x64, + 0x43, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x64, 0x65, + 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3d, 0x0a, + 0x0f, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x62, 0x2e, 0x57, 0x65, 0x63, 0x68, + 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x77, 0x65, 0x63, + 0x68, 0x61, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, + 0x61, 0x70, 0x70, 0x54, 0x61, 0x67, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x61, 0x70, + 0x70, 0x54, 0x61, 0x67, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x12, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x32, 0xfc, 0x05, 0x0a, 0x0f, 0x4d, 0x6f, 0x70, 0x41, 0x70, + 0x70, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x53, 0x76, 0x72, 0x12, 0x52, 0x0a, 0x14, 0x52, 0x75, + 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, + 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x5b, + 0x0a, 0x17, 0x52, 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, + 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x52, + 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x52, + 0x75, 0x6c, 0x65, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x14, 0x4f, + 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, + 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, + 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x4c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x64, 0x42, 0x79, 0x53, + 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x49, 0x64, 0x42, 0x79, 0x53, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, + 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x49, 0x64, + 0x42, 0x79, 0x53, 0x64, 0x6b, 0x4b, 0x65, 0x79, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x55, 0x0a, + 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x70, 0x41, 0x6e, 0x64, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x73, 0x70, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, + 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x2e, 0x70, 0x62, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x41, 0x70, 0x70, 0x73, 0x42, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x41, 0x70, 0x70, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x5e, 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, 0x51, 0x52, + 0x63, 0x6f, 0x64, 0x65, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, + 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, 0x74, 0x51, 0x52, + 0x63, 0x6f, 0x64, 0x65, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x71, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x70, 0x69, 0x47, 0x65, + 0x74, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x43, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x70, 0x70, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x73, 0x70, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x3b, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_mop_app_manage_svr_request_proto_rawDescOnce sync.Once + file_mop_app_manage_svr_request_proto_rawDescData = file_mop_app_manage_svr_request_proto_rawDesc +) + +func file_mop_app_manage_svr_request_proto_rawDescGZIP() []byte { + file_mop_app_manage_svr_request_proto_rawDescOnce.Do(func() { + file_mop_app_manage_svr_request_proto_rawDescData = protoimpl.X.CompressGZIP(file_mop_app_manage_svr_request_proto_rawDescData) + }) + return file_mop_app_manage_svr_request_proto_rawDescData +} + +var file_mop_app_manage_svr_request_proto_msgTypes = make([]protoimpl.MessageInfo, 44) +var file_mop_app_manage_svr_request_proto_goTypes = []interface{}{ + (*RuleEngineGetAppInfoReq)(nil), // 0: pb.RuleEngineGetAppInfoReq + (*Status)(nil), // 1: pb.Status + (*SpecificStatus)(nil), // 2: pb.SpecificStatus + (*MenuInfoRspDataItem)(nil), // 3: pb.MenuInfoRspDataItem + (*MenuInfoRspData)(nil), // 4: pb.MenuInfoRspData + (*ApiInfoRspData)(nil), // 5: pb.ApiInfoRspData + (*CustomData)(nil), // 6: pb.CustomData + (*WechatLoginInfo)(nil), // 7: pb.WechatLoginInfo + (*ExtUrls)(nil), // 8: pb.ExtUrls + (*AppRuntimeDomain)(nil), // 9: pb.AppRuntimeDomain + (*SourceFileData)(nil), // 10: pb.SourceFileData + (*Package)(nil), // 11: pb.Package + (*AppInfoRspData)(nil), // 12: pb.AppInfoRspData + (*RuleEngineGetAppInfoRsp)(nil), // 13: pb.RuleEngineGetAppInfoRsp + (*RuleEngineGetAppVerInfoReq)(nil), // 14: pb.RuleEngineGetAppVerInfoReq + (*RuleEngineGetAppVerInfoRsp)(nil), // 15: pb.RuleEngineGetAppVerInfoRsp + (*OpenApiGetAppVerInfoReq)(nil), // 16: pb.OpenApiGetAppVerInfoReq + (*OpenApiGetAppVerInfoRsp)(nil), // 17: pb.OpenApiGetAppVerInfoRsp + (*GetOrganIdBySdkKeyReq)(nil), // 18: pb.GetOrganIdBySdkKeyReq + (*GetOrganIdBySdkKeyRsp)(nil), // 19: pb.GetOrganIdBySdkKeyRsp + (*BatchGetAppAndVerInfoReq)(nil), // 20: pb.BatchGetAppAndVerInfoReq + (*BatchGetAppAndVerInfoRsp)(nil), // 21: pb.BatchGetAppAndVerInfoRsp + (*BatchAppsByIdentityReq)(nil), // 22: pb.BatchAppsByIdentityReq + (*BatchAppsByIdentityAppsItem)(nil), // 23: pb.BatchAppsByIdentityAppsItem + (*BatchAppsByIdentityRsp)(nil), // 24: pb.BatchAppsByIdentityRsp + (*IdentityAppsCheckReq)(nil), // 25: pb.IdentityAppsCheckReq + (*IdentityAppsCheckAppsItem)(nil), // 26: pb.IdentityAppsCheckAppsItem + (*IdentityAppsCheckRsp)(nil), // 27: pb.IdentityAppsCheckRsp + (*OpenApiGetQRcodeAppVerInfoReq)(nil), // 28: pb.OpenApiGetQRcodeAppVerInfoReq + (*GetBuildAppInfoReq)(nil), // 29: pb.GetBuildAppInfoReq + (*GetBuildAppInfoRsp)(nil), // 30: pb.GetBuildAppInfoRsp + (*BuildAppInfo)(nil), // 31: pb.BuildAppInfo + (*AppRuntimeDomain_Business)(nil), // 32: pb.AppRuntimeDomain.Business + (*AppRuntimeDomain_Service)(nil), // 33: pb.AppRuntimeDomain.Service + (*AppRuntimeDomain_Whitelist)(nil), // 34: pb.AppRuntimeDomain.Whitelist + (*AppRuntimeDomain_Blacklist)(nil), // 35: pb.AppRuntimeDomain.Blacklist + (*GetOrganIdBySdkKeyRsp_DATA)(nil), // 36: pb.GetOrganIdBySdkKeyRsp.DATA + (*BatchGetAppAndVerInfoReq_AppAndVer)(nil), // 37: pb.BatchGetAppAndVerInfoReq.AppAndVer + (*BatchGetAppAndVerInfoRsp_DATA)(nil), // 38: pb.BatchGetAppAndVerInfoRsp.DATA + (*BatchAppsByIdentityRsp_AppListItem)(nil), // 39: pb.BatchAppsByIdentityRsp.AppListItem + (*BatchAppsByIdentityRsp_DATA)(nil), // 40: pb.BatchAppsByIdentityRsp.DATA + (*IdentityAppsCheckRsp_AppListItem)(nil), // 41: pb.IdentityAppsCheckRsp.AppListItem + (*IdentityAppsCheckRsp_DATA)(nil), // 42: pb.IdentityAppsCheckRsp.DATA + (*IdentityAppsCheckRsp_AppListItem_AppListItemData)(nil), // 43: pb.IdentityAppsCheckRsp.AppListItem.AppListItemData + (*CommonResult)(nil), // 44: pb.CommonResult +} +var file_mop_app_manage_svr_request_proto_depIdxs = []int32{ + 3, // 0: pb.MenuInfoRspData.list:type_name -> pb.MenuInfoRspDataItem + 9, // 1: pb.CustomData.appRuntimeDomain:type_name -> pb.AppRuntimeDomain + 10, // 2: pb.CustomData.sourceFile:type_name -> pb.SourceFileData + 4, // 3: pb.CustomData.menuInfo:type_name -> pb.MenuInfoRspData + 5, // 4: pb.CustomData.apiInfo:type_name -> pb.ApiInfoRspData + 8, // 5: pb.WechatLoginInfo.extUrls:type_name -> pb.ExtUrls + 32, // 6: pb.AppRuntimeDomain.business:type_name -> pb.AppRuntimeDomain.Business + 33, // 7: pb.AppRuntimeDomain.service:type_name -> pb.AppRuntimeDomain.Service + 34, // 8: pb.AppRuntimeDomain.whitelist:type_name -> pb.AppRuntimeDomain.Whitelist + 35, // 9: pb.AppRuntimeDomain.blacklist:type_name -> pb.AppRuntimeDomain.Blacklist + 11, // 10: pb.SourceFileData.packages:type_name -> pb.Package + 6, // 11: pb.AppInfoRspData.customData:type_name -> pb.CustomData + 1, // 12: pb.AppInfoRspData.status:type_name -> pb.Status + 7, // 13: pb.AppInfoRspData.wechatLoginInfo:type_name -> pb.WechatLoginInfo + 44, // 14: pb.RuleEngineGetAppInfoRsp.result:type_name -> pb.CommonResult + 12, // 15: pb.RuleEngineGetAppInfoRsp.data:type_name -> pb.AppInfoRspData + 44, // 16: pb.RuleEngineGetAppVerInfoRsp.result:type_name -> pb.CommonResult + 12, // 17: pb.RuleEngineGetAppVerInfoRsp.data:type_name -> pb.AppInfoRspData + 44, // 18: pb.OpenApiGetAppVerInfoRsp.result:type_name -> pb.CommonResult + 12, // 19: pb.OpenApiGetAppVerInfoRsp.data:type_name -> pb.AppInfoRspData + 44, // 20: pb.GetOrganIdBySdkKeyRsp.result:type_name -> pb.CommonResult + 36, // 21: pb.GetOrganIdBySdkKeyRsp.data:type_name -> pb.GetOrganIdBySdkKeyRsp.DATA + 37, // 22: pb.BatchGetAppAndVerInfoReq.appVerList:type_name -> pb.BatchGetAppAndVerInfoReq.AppAndVer + 44, // 23: pb.BatchGetAppAndVerInfoRsp.result:type_name -> pb.CommonResult + 38, // 24: pb.BatchGetAppAndVerInfoRsp.data:type_name -> pb.BatchGetAppAndVerInfoRsp.DATA + 23, // 25: pb.BatchAppsByIdentityReq.apps:type_name -> pb.BatchAppsByIdentityAppsItem + 44, // 26: pb.BatchAppsByIdentityRsp.result:type_name -> pb.CommonResult + 40, // 27: pb.BatchAppsByIdentityRsp.data:type_name -> pb.BatchAppsByIdentityRsp.DATA + 26, // 28: pb.IdentityAppsCheckReq.Apps:type_name -> pb.IdentityAppsCheckAppsItem + 44, // 29: pb.IdentityAppsCheckRsp.result:type_name -> pb.CommonResult + 42, // 30: pb.IdentityAppsCheckRsp.data:type_name -> pb.IdentityAppsCheckRsp.DATA + 44, // 31: pb.GetBuildAppInfoRsp.result:type_name -> pb.CommonResult + 31, // 32: pb.GetBuildAppInfoRsp.data:type_name -> pb.BuildAppInfo + 6, // 33: pb.BuildAppInfo.customData:type_name -> pb.CustomData + 7, // 34: pb.BuildAppInfo.wechatLoginInfo:type_name -> pb.WechatLoginInfo + 12, // 35: pb.BatchGetAppAndVerInfoRsp.DATA.appDataList:type_name -> pb.AppInfoRspData + 12, // 36: pb.BatchGetAppAndVerInfoRsp.DATA.appVerDataList:type_name -> pb.AppInfoRspData + 12, // 37: pb.BatchAppsByIdentityRsp.AppListItem.appInfo:type_name -> pb.AppInfoRspData + 39, // 38: pb.BatchAppsByIdentityRsp.DATA.appList:type_name -> pb.BatchAppsByIdentityRsp.AppListItem + 43, // 39: pb.IdentityAppsCheckRsp.AppListItem.data:type_name -> pb.IdentityAppsCheckRsp.AppListItem.AppListItemData + 41, // 40: pb.IdentityAppsCheckRsp.DATA.appList:type_name -> pb.IdentityAppsCheckRsp.AppListItem + 0, // 41: pb.MopAppManageSvr.RuleEngineGetAppInfo:input_type -> pb.RuleEngineGetAppInfoReq + 14, // 42: pb.MopAppManageSvr.RuleEngineGetAppVerInfo:input_type -> pb.RuleEngineGetAppVerInfoReq + 16, // 43: pb.MopAppManageSvr.OpenApiGetAppVerInfo:input_type -> pb.OpenApiGetAppVerInfoReq + 18, // 44: pb.MopAppManageSvr.GetOrganIdBySdkKey:input_type -> pb.GetOrganIdBySdkKeyReq + 20, // 45: pb.MopAppManageSvr.BatchGetAppAndVerInfo:input_type -> pb.BatchGetAppAndVerInfoReq + 22, // 46: pb.MopAppManageSvr.BatchAppsByIdentity:input_type -> pb.BatchAppsByIdentityReq + 25, // 47: pb.MopAppManageSvr.IdentityAppsCheck:input_type -> pb.IdentityAppsCheckReq + 28, // 48: pb.MopAppManageSvr.OpenApiGetQRcodeAppVerInfo:input_type -> pb.OpenApiGetQRcodeAppVerInfoReq + 29, // 49: pb.MopAppManageSvr.GetBuildAppInfo:input_type -> pb.GetBuildAppInfoReq + 13, // 50: pb.MopAppManageSvr.RuleEngineGetAppInfo:output_type -> pb.RuleEngineGetAppInfoRsp + 15, // 51: pb.MopAppManageSvr.RuleEngineGetAppVerInfo:output_type -> pb.RuleEngineGetAppVerInfoRsp + 17, // 52: pb.MopAppManageSvr.OpenApiGetAppVerInfo:output_type -> pb.OpenApiGetAppVerInfoRsp + 19, // 53: pb.MopAppManageSvr.GetOrganIdBySdkKey:output_type -> pb.GetOrganIdBySdkKeyRsp + 21, // 54: pb.MopAppManageSvr.BatchGetAppAndVerInfo:output_type -> pb.BatchGetAppAndVerInfoRsp + 24, // 55: pb.MopAppManageSvr.BatchAppsByIdentity:output_type -> pb.BatchAppsByIdentityRsp + 27, // 56: pb.MopAppManageSvr.IdentityAppsCheck:output_type -> pb.IdentityAppsCheckRsp + 17, // 57: pb.MopAppManageSvr.OpenApiGetQRcodeAppVerInfo:output_type -> pb.OpenApiGetAppVerInfoRsp + 30, // 58: pb.MopAppManageSvr.GetBuildAppInfo:output_type -> pb.GetBuildAppInfoRsp + 50, // [50:59] is the sub-list for method output_type + 41, // [41:50] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name +} + +func init() { file_mop_app_manage_svr_request_proto_init() } +func file_mop_app_manage_svr_request_proto_init() { + if File_mop_app_manage_svr_request_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_mop_app_manage_svr_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuleEngineGetAppInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Status); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SpecificStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MenuInfoRspDataItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MenuInfoRspData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApiInfoRspData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WechatLoginInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExtUrls); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRuntimeDomain); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SourceFileData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Package); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppInfoRspData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuleEngineGetAppInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuleEngineGetAppVerInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RuleEngineGetAppVerInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OpenApiGetAppVerInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OpenApiGetAppVerInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganIdBySdkKeyReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganIdBySdkKeyRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetAppAndVerInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetAppAndVerInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchAppsByIdentityReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchAppsByIdentityAppsItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchAppsByIdentityRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckAppsItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OpenApiGetQRcodeAppVerInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBuildAppInfoReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBuildAppInfoRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BuildAppInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRuntimeDomain_Business); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRuntimeDomain_Service); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRuntimeDomain_Whitelist); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRuntimeDomain_Blacklist); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganIdBySdkKeyRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetAppAndVerInfoReq_AppAndVer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetAppAndVerInfoRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchAppsByIdentityRsp_AppListItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchAppsByIdentityRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckRsp_AppListItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_app_manage_svr_request_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IdentityAppsCheckRsp_AppListItem_AppListItemData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_mop_app_manage_svr_request_proto_rawDesc, + NumEnums: 0, + NumMessages: 44, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mop_app_manage_svr_request_proto_goTypes, + DependencyIndexes: file_mop_app_manage_svr_request_proto_depIdxs, + MessageInfos: file_mop_app_manage_svr_request_proto_msgTypes, + }.Build() + File_mop_app_manage_svr_request_proto = out.File + file_mop_app_manage_svr_request_proto_rawDesc = nil + file_mop_app_manage_svr_request_proto_goTypes = nil + file_mop_app_manage_svr_request_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MopAppManageSvrClient is the client API for MopAppManageSvr service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MopAppManageSvrClient interface { + RuleEngineGetAppInfo(ctx context.Context, in *RuleEngineGetAppInfoReq, opts ...grpc.CallOption) (*RuleEngineGetAppInfoRsp, error) + RuleEngineGetAppVerInfo(ctx context.Context, in *RuleEngineGetAppVerInfoReq, opts ...grpc.CallOption) (*RuleEngineGetAppVerInfoRsp, error) + OpenApiGetAppVerInfo(ctx context.Context, in *OpenApiGetAppVerInfoReq, opts ...grpc.CallOption) (*OpenApiGetAppVerInfoRsp, error) + GetOrganIdBySdkKey(ctx context.Context, in *GetOrganIdBySdkKeyReq, opts ...grpc.CallOption) (*GetOrganIdBySdkKeyRsp, error) + BatchGetAppAndVerInfo(ctx context.Context, in *BatchGetAppAndVerInfoReq, opts ...grpc.CallOption) (*BatchGetAppAndVerInfoRsp, error) + BatchAppsByIdentity(ctx context.Context, in *BatchAppsByIdentityReq, opts ...grpc.CallOption) (*BatchAppsByIdentityRsp, error) + IdentityAppsCheck(ctx context.Context, in *IdentityAppsCheckReq, opts ...grpc.CallOption) (*IdentityAppsCheckRsp, error) + OpenApiGetQRcodeAppVerInfo(ctx context.Context, in *OpenApiGetQRcodeAppVerInfoReq, opts ...grpc.CallOption) (*OpenApiGetAppVerInfoRsp, error) + GetBuildAppInfo(ctx context.Context, in *GetBuildAppInfoReq, opts ...grpc.CallOption) (*GetBuildAppInfoRsp, error) +} + +type mopAppManageSvrClient struct { + cc grpc.ClientConnInterface +} + +func NewMopAppManageSvrClient(cc grpc.ClientConnInterface) MopAppManageSvrClient { + return &mopAppManageSvrClient{cc} +} + +func (c *mopAppManageSvrClient) RuleEngineGetAppInfo(ctx context.Context, in *RuleEngineGetAppInfoReq, opts ...grpc.CallOption) (*RuleEngineGetAppInfoRsp, error) { + out := new(RuleEngineGetAppInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/RuleEngineGetAppInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) RuleEngineGetAppVerInfo(ctx context.Context, in *RuleEngineGetAppVerInfoReq, opts ...grpc.CallOption) (*RuleEngineGetAppVerInfoRsp, error) { + out := new(RuleEngineGetAppVerInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/RuleEngineGetAppVerInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) OpenApiGetAppVerInfo(ctx context.Context, in *OpenApiGetAppVerInfoReq, opts ...grpc.CallOption) (*OpenApiGetAppVerInfoRsp, error) { + out := new(OpenApiGetAppVerInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/OpenApiGetAppVerInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) GetOrganIdBySdkKey(ctx context.Context, in *GetOrganIdBySdkKeyReq, opts ...grpc.CallOption) (*GetOrganIdBySdkKeyRsp, error) { + out := new(GetOrganIdBySdkKeyRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/GetOrganIdBySdkKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) BatchGetAppAndVerInfo(ctx context.Context, in *BatchGetAppAndVerInfoReq, opts ...grpc.CallOption) (*BatchGetAppAndVerInfoRsp, error) { + out := new(BatchGetAppAndVerInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/BatchGetAppAndVerInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) BatchAppsByIdentity(ctx context.Context, in *BatchAppsByIdentityReq, opts ...grpc.CallOption) (*BatchAppsByIdentityRsp, error) { + out := new(BatchAppsByIdentityRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/BatchAppsByIdentity", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) IdentityAppsCheck(ctx context.Context, in *IdentityAppsCheckReq, opts ...grpc.CallOption) (*IdentityAppsCheckRsp, error) { + out := new(IdentityAppsCheckRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/IdentityAppsCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) OpenApiGetQRcodeAppVerInfo(ctx context.Context, in *OpenApiGetQRcodeAppVerInfoReq, opts ...grpc.CallOption) (*OpenApiGetAppVerInfoRsp, error) { + out := new(OpenApiGetAppVerInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/OpenApiGetQRcodeAppVerInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopAppManageSvrClient) GetBuildAppInfo(ctx context.Context, in *GetBuildAppInfoReq, opts ...grpc.CallOption) (*GetBuildAppInfoRsp, error) { + out := new(GetBuildAppInfoRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppManageSvr/GetBuildAppInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MopAppManageSvrServer is the server API for MopAppManageSvr service. +type MopAppManageSvrServer interface { + RuleEngineGetAppInfo(context.Context, *RuleEngineGetAppInfoReq) (*RuleEngineGetAppInfoRsp, error) + RuleEngineGetAppVerInfo(context.Context, *RuleEngineGetAppVerInfoReq) (*RuleEngineGetAppVerInfoRsp, error) + OpenApiGetAppVerInfo(context.Context, *OpenApiGetAppVerInfoReq) (*OpenApiGetAppVerInfoRsp, error) + GetOrganIdBySdkKey(context.Context, *GetOrganIdBySdkKeyReq) (*GetOrganIdBySdkKeyRsp, error) + BatchGetAppAndVerInfo(context.Context, *BatchGetAppAndVerInfoReq) (*BatchGetAppAndVerInfoRsp, error) + BatchAppsByIdentity(context.Context, *BatchAppsByIdentityReq) (*BatchAppsByIdentityRsp, error) + IdentityAppsCheck(context.Context, *IdentityAppsCheckReq) (*IdentityAppsCheckRsp, error) + OpenApiGetQRcodeAppVerInfo(context.Context, *OpenApiGetQRcodeAppVerInfoReq) (*OpenApiGetAppVerInfoRsp, error) + GetBuildAppInfo(context.Context, *GetBuildAppInfoReq) (*GetBuildAppInfoRsp, error) +} + +// UnimplementedMopAppManageSvrServer can be embedded to have forward compatible implementations. +type UnimplementedMopAppManageSvrServer struct { +} + +func (*UnimplementedMopAppManageSvrServer) RuleEngineGetAppInfo(context.Context, *RuleEngineGetAppInfoReq) (*RuleEngineGetAppInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method RuleEngineGetAppInfo not implemented") +} +func (*UnimplementedMopAppManageSvrServer) RuleEngineGetAppVerInfo(context.Context, *RuleEngineGetAppVerInfoReq) (*RuleEngineGetAppVerInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method RuleEngineGetAppVerInfo not implemented") +} +func (*UnimplementedMopAppManageSvrServer) OpenApiGetAppVerInfo(context.Context, *OpenApiGetAppVerInfoReq) (*OpenApiGetAppVerInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method OpenApiGetAppVerInfo not implemented") +} +func (*UnimplementedMopAppManageSvrServer) GetOrganIdBySdkKey(context.Context, *GetOrganIdBySdkKeyReq) (*GetOrganIdBySdkKeyRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrganIdBySdkKey not implemented") +} +func (*UnimplementedMopAppManageSvrServer) BatchGetAppAndVerInfo(context.Context, *BatchGetAppAndVerInfoReq) (*BatchGetAppAndVerInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchGetAppAndVerInfo not implemented") +} +func (*UnimplementedMopAppManageSvrServer) BatchAppsByIdentity(context.Context, *BatchAppsByIdentityReq) (*BatchAppsByIdentityRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchAppsByIdentity not implemented") +} +func (*UnimplementedMopAppManageSvrServer) IdentityAppsCheck(context.Context, *IdentityAppsCheckReq) (*IdentityAppsCheckRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method IdentityAppsCheck not implemented") +} +func (*UnimplementedMopAppManageSvrServer) OpenApiGetQRcodeAppVerInfo(context.Context, *OpenApiGetQRcodeAppVerInfoReq) (*OpenApiGetAppVerInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method OpenApiGetQRcodeAppVerInfo not implemented") +} +func (*UnimplementedMopAppManageSvrServer) GetBuildAppInfo(context.Context, *GetBuildAppInfoReq) (*GetBuildAppInfoRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBuildAppInfo not implemented") +} + +func RegisterMopAppManageSvrServer(s *grpc.Server, srv MopAppManageSvrServer) { + s.RegisterService(&_MopAppManageSvr_serviceDesc, srv) +} + +func _MopAppManageSvr_RuleEngineGetAppInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RuleEngineGetAppInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).RuleEngineGetAppInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/RuleEngineGetAppInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).RuleEngineGetAppInfo(ctx, req.(*RuleEngineGetAppInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_RuleEngineGetAppVerInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RuleEngineGetAppVerInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).RuleEngineGetAppVerInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/RuleEngineGetAppVerInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).RuleEngineGetAppVerInfo(ctx, req.(*RuleEngineGetAppVerInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_OpenApiGetAppVerInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OpenApiGetAppVerInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).OpenApiGetAppVerInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/OpenApiGetAppVerInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).OpenApiGetAppVerInfo(ctx, req.(*OpenApiGetAppVerInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_GetOrganIdBySdkKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetOrganIdBySdkKeyReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).GetOrganIdBySdkKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/GetOrganIdBySdkKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).GetOrganIdBySdkKey(ctx, req.(*GetOrganIdBySdkKeyReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_BatchGetAppAndVerInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchGetAppAndVerInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).BatchGetAppAndVerInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/BatchGetAppAndVerInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).BatchGetAppAndVerInfo(ctx, req.(*BatchGetAppAndVerInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_BatchAppsByIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchAppsByIdentityReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).BatchAppsByIdentity(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/BatchAppsByIdentity", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).BatchAppsByIdentity(ctx, req.(*BatchAppsByIdentityReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_IdentityAppsCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IdentityAppsCheckReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).IdentityAppsCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/IdentityAppsCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).IdentityAppsCheck(ctx, req.(*IdentityAppsCheckReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_OpenApiGetQRcodeAppVerInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OpenApiGetQRcodeAppVerInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).OpenApiGetQRcodeAppVerInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/OpenApiGetQRcodeAppVerInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).OpenApiGetQRcodeAppVerInfo(ctx, req.(*OpenApiGetQRcodeAppVerInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopAppManageSvr_GetBuildAppInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBuildAppInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppManageSvrServer).GetBuildAppInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppManageSvr/GetBuildAppInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppManageSvrServer).GetBuildAppInfo(ctx, req.(*GetBuildAppInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _MopAppManageSvr_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.MopAppManageSvr", + HandlerType: (*MopAppManageSvrServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RuleEngineGetAppInfo", + Handler: _MopAppManageSvr_RuleEngineGetAppInfo_Handler, + }, + { + MethodName: "RuleEngineGetAppVerInfo", + Handler: _MopAppManageSvr_RuleEngineGetAppVerInfo_Handler, + }, + { + MethodName: "OpenApiGetAppVerInfo", + Handler: _MopAppManageSvr_OpenApiGetAppVerInfo_Handler, + }, + { + MethodName: "GetOrganIdBySdkKey", + Handler: _MopAppManageSvr_GetOrganIdBySdkKey_Handler, + }, + { + MethodName: "BatchGetAppAndVerInfo", + Handler: _MopAppManageSvr_BatchGetAppAndVerInfo_Handler, + }, + { + MethodName: "BatchAppsByIdentity", + Handler: _MopAppManageSvr_BatchAppsByIdentity_Handler, + }, + { + MethodName: "IdentityAppsCheck", + Handler: _MopAppManageSvr_IdentityAppsCheck_Handler, + }, + { + MethodName: "OpenApiGetQRcodeAppVerInfo", + Handler: _MopAppManageSvr_OpenApiGetQRcodeAppVerInfo_Handler, + }, + { + MethodName: "GetBuildAppInfo", + Handler: _MopAppManageSvr_GetBuildAppInfo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "mop_app_manage_svr_request.proto", +} diff --git a/infrastructure/protobuf/golang/mop_applet_build_manager.pb.go b/infrastructure/protobuf/golang/mop_applet_build_manager.pb.go new file mode 100644 index 0000000..dfa0740 --- /dev/null +++ b/infrastructure/protobuf/golang/mop_applet_build_manager.pb.go @@ -0,0 +1,383 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: mop_applet_build_manager.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +//接口一 +type QueryEncryptedReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SdkVersion string `protobuf:"bytes,1,opt,name=sdkVersion,proto3" json:"sdkVersion"` +} + +func (x *QueryEncryptedReq) Reset() { + *x = QueryEncryptedReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_applet_build_manager_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryEncryptedReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryEncryptedReq) ProtoMessage() {} + +func (x *QueryEncryptedReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_applet_build_manager_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryEncryptedReq.ProtoReflect.Descriptor instead. +func (*QueryEncryptedReq) Descriptor() ([]byte, []int) { + return file_mop_applet_build_manager_proto_rawDescGZIP(), []int{0} +} + +func (x *QueryEncryptedReq) GetSdkVersion() string { + if x != nil { + return x.SdkVersion + } + return "" +} + +type QueryEncryptedRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *QueryEncryptedRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *QueryEncryptedRsp) Reset() { + *x = QueryEncryptedRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_applet_build_manager_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryEncryptedRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryEncryptedRsp) ProtoMessage() {} + +func (x *QueryEncryptedRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_applet_build_manager_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryEncryptedRsp.ProtoReflect.Descriptor instead. +func (*QueryEncryptedRsp) Descriptor() ([]byte, []int) { + return file_mop_applet_build_manager_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryEncryptedRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *QueryEncryptedRsp) GetData() *QueryEncryptedRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type QueryEncryptedRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Encrypted bool `protobuf:"varint,1,opt,name=encrypted,proto3" json:"encrypted"` +} + +func (x *QueryEncryptedRsp_DATA) Reset() { + *x = QueryEncryptedRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_applet_build_manager_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryEncryptedRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryEncryptedRsp_DATA) ProtoMessage() {} + +func (x *QueryEncryptedRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_applet_build_manager_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryEncryptedRsp_DATA.ProtoReflect.Descriptor instead. +func (*QueryEncryptedRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_applet_build_manager_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *QueryEncryptedRsp_DATA) GetEncrypted() bool { + if x != nil { + return x.Encrypted + } + return false +} + +var File_mop_applet_build_manager_proto protoreflect.FileDescriptor + +var file_mop_applet_build_manager_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x6d, 0x6f, 0x70, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x74, 0x5f, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x64, 0x6b, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x64, 0x6b, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, + 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x24, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, + 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x32, 0x58, 0x0a, + 0x14, 0x4d, 0x6f, 0x70, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x74, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x15, + 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x52, 0x73, 0x70, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x3b, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_mop_applet_build_manager_proto_rawDescOnce sync.Once + file_mop_applet_build_manager_proto_rawDescData = file_mop_applet_build_manager_proto_rawDesc +) + +func file_mop_applet_build_manager_proto_rawDescGZIP() []byte { + file_mop_applet_build_manager_proto_rawDescOnce.Do(func() { + file_mop_applet_build_manager_proto_rawDescData = protoimpl.X.CompressGZIP(file_mop_applet_build_manager_proto_rawDescData) + }) + return file_mop_applet_build_manager_proto_rawDescData +} + +var file_mop_applet_build_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_mop_applet_build_manager_proto_goTypes = []interface{}{ + (*QueryEncryptedReq)(nil), // 0: pb.QueryEncryptedReq + (*QueryEncryptedRsp)(nil), // 1: pb.QueryEncryptedRsp + (*QueryEncryptedRsp_DATA)(nil), // 2: pb.QueryEncryptedRsp.DATA + (*CommonResult)(nil), // 3: pb.CommonResult +} +var file_mop_applet_build_manager_proto_depIdxs = []int32{ + 3, // 0: pb.QueryEncryptedRsp.result:type_name -> pb.CommonResult + 2, // 1: pb.QueryEncryptedRsp.data:type_name -> pb.QueryEncryptedRsp.DATA + 0, // 2: pb.MopAppletBuildManger.QueryEncrypted:input_type -> pb.QueryEncryptedReq + 1, // 3: pb.MopAppletBuildManger.QueryEncrypted:output_type -> pb.QueryEncryptedRsp + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_mop_applet_build_manager_proto_init() } +func file_mop_applet_build_manager_proto_init() { + if File_mop_applet_build_manager_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_mop_applet_build_manager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryEncryptedReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_applet_build_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryEncryptedRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_applet_build_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryEncryptedRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_mop_applet_build_manager_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mop_applet_build_manager_proto_goTypes, + DependencyIndexes: file_mop_applet_build_manager_proto_depIdxs, + MessageInfos: file_mop_applet_build_manager_proto_msgTypes, + }.Build() + File_mop_applet_build_manager_proto = out.File + file_mop_applet_build_manager_proto_rawDesc = nil + file_mop_applet_build_manager_proto_goTypes = nil + file_mop_applet_build_manager_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MopAppletBuildMangerClient is the client API for MopAppletBuildManger service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MopAppletBuildMangerClient interface { + QueryEncrypted(ctx context.Context, in *QueryEncryptedReq, opts ...grpc.CallOption) (*QueryEncryptedRsp, error) +} + +type mopAppletBuildMangerClient struct { + cc grpc.ClientConnInterface +} + +func NewMopAppletBuildMangerClient(cc grpc.ClientConnInterface) MopAppletBuildMangerClient { + return &mopAppletBuildMangerClient{cc} +} + +func (c *mopAppletBuildMangerClient) QueryEncrypted(ctx context.Context, in *QueryEncryptedReq, opts ...grpc.CallOption) (*QueryEncryptedRsp, error) { + out := new(QueryEncryptedRsp) + err := c.cc.Invoke(ctx, "/pb.MopAppletBuildManger/QueryEncrypted", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MopAppletBuildMangerServer is the server API for MopAppletBuildManger service. +type MopAppletBuildMangerServer interface { + QueryEncrypted(context.Context, *QueryEncryptedReq) (*QueryEncryptedRsp, error) +} + +// UnimplementedMopAppletBuildMangerServer can be embedded to have forward compatible implementations. +type UnimplementedMopAppletBuildMangerServer struct { +} + +func (*UnimplementedMopAppletBuildMangerServer) QueryEncrypted(context.Context, *QueryEncryptedReq) (*QueryEncryptedRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryEncrypted not implemented") +} + +func RegisterMopAppletBuildMangerServer(s *grpc.Server, srv MopAppletBuildMangerServer) { + s.RegisterService(&_MopAppletBuildManger_serviceDesc, srv) +} + +func _MopAppletBuildManger_QueryEncrypted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryEncryptedReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopAppletBuildMangerServer).QueryEncrypted(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopAppletBuildManger/QueryEncrypted", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopAppletBuildMangerServer).QueryEncrypted(ctx, req.(*QueryEncryptedReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _MopAppletBuildManger_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.MopAppletBuildManger", + HandlerType: (*MopAppletBuildMangerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "QueryEncrypted", + Handler: _MopAppletBuildManger_QueryEncrypted_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "mop_applet_build_manager.proto", +} diff --git a/infrastructure/protobuf/golang/mop_domain_manager_request.pb.go b/infrastructure/protobuf/golang/mop_domain_manager_request.pb.go new file mode 100644 index 0000000..1e0fe07 --- /dev/null +++ b/infrastructure/protobuf/golang/mop_domain_manager_request.pb.go @@ -0,0 +1,1565 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: mop_domain_manager_request.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +//接口一 +type GetAllDomainInternalReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppId string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId"` +} + +func (x *GetAllDomainInternalReq) Reset() { + *x = GetAllDomainInternalReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalReq) ProtoMessage() {} + +func (x *GetAllDomainInternalReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalReq.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalReq) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{0} +} + +func (x *GetAllDomainInternalReq) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +type GetAllDomainInternalRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *GetAllDomainInternalRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *GetAllDomainInternalRsp) Reset() { + *x = GetAllDomainInternalRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalRsp) ProtoMessage() {} + +func (x *GetAllDomainInternalRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalRsp.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalRsp) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{1} +} + +func (x *GetAllDomainInternalRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetAllDomainInternalRsp) GetData() *GetAllDomainInternalRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type GetAllDomainInternalV2Req struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrganId string `protobuf:"bytes,1,opt,name=organId,proto3" json:"organId"` +} + +func (x *GetAllDomainInternalV2Req) Reset() { + *x = GetAllDomainInternalV2Req{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Req) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Req) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Req) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Req.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Req) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{2} +} + +func (x *GetAllDomainInternalV2Req) GetOrganId() string { + if x != nil { + return x.OrganId + } + return "" +} + +type GetAllDomainInternalV2Rsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *GetAllDomainInternalV2Rsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *GetAllDomainInternalV2Rsp) Reset() { + *x = GetAllDomainInternalV2Rsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3} +} + +func (x *GetAllDomainInternalV2Rsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp) GetData() *GetAllDomainInternalV2Rsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type GetOrganDomainsWithCrtReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrganId string `protobuf:"bytes,1,opt,name=organId,proto3" json:"organId"` + ValidateDomainCrt map[string]*GetOrganDomainsWithCrtReq_DomainValidate `protobuf:"bytes,2,rep,name=validateDomainCrt,proto3" json:"validateDomainCrt" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetOrganDomainsWithCrtReq) Reset() { + *x = GetOrganDomainsWithCrtReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganDomainsWithCrtReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganDomainsWithCrtReq) ProtoMessage() {} + +func (x *GetOrganDomainsWithCrtReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganDomainsWithCrtReq.ProtoReflect.Descriptor instead. +func (*GetOrganDomainsWithCrtReq) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{4} +} + +func (x *GetOrganDomainsWithCrtReq) GetOrganId() string { + if x != nil { + return x.OrganId + } + return "" +} + +func (x *GetOrganDomainsWithCrtReq) GetValidateDomainCrt() map[string]*GetOrganDomainsWithCrtReq_DomainValidate { + if x != nil { + return x.ValidateDomainCrt + } + return nil +} + +type GetOrganDomainsWithCrtRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data []*GetOrganDomainsWithCrtRsp_DomainWithCrt `protobuf:"bytes,2,rep,name=data,proto3" json:"data"` +} + +func (x *GetOrganDomainsWithCrtRsp) Reset() { + *x = GetOrganDomainsWithCrtRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganDomainsWithCrtRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganDomainsWithCrtRsp) ProtoMessage() {} + +func (x *GetOrganDomainsWithCrtRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganDomainsWithCrtRsp.ProtoReflect.Descriptor instead. +func (*GetOrganDomainsWithCrtRsp) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{5} +} + +func (x *GetOrganDomainsWithCrtRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *GetOrganDomainsWithCrtRsp) GetData() []*GetOrganDomainsWithCrtRsp_DomainWithCrt { + if x != nil { + return x.Data + } + return nil +} + +type GetAllDomainInternalRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Service *GetAllDomainInternalRsp_DATA_SERVICE `protobuf:"bytes,2,opt,name=service,proto3" json:"service"` + Business *GetAllDomainInternalRsp_DATA_BUSINESS `protobuf:"bytes,3,opt,name=business,proto3" json:"business"` + Whitelist *GetAllDomainInternalRsp_DATA_WHITELIST `protobuf:"bytes,4,opt,name=whitelist,proto3" json:"whitelist"` +} + +func (x *GetAllDomainInternalRsp_DATA) Reset() { + *x = GetAllDomainInternalRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalRsp_DATA) ProtoMessage() {} + +func (x *GetAllDomainInternalRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalRsp_DATA.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *GetAllDomainInternalRsp_DATA) GetService() *GetAllDomainInternalRsp_DATA_SERVICE { + if x != nil { + return x.Service + } + return nil +} + +func (x *GetAllDomainInternalRsp_DATA) GetBusiness() *GetAllDomainInternalRsp_DATA_BUSINESS { + if x != nil { + return x.Business + } + return nil +} + +func (x *GetAllDomainInternalRsp_DATA) GetWhitelist() *GetAllDomainInternalRsp_DATA_WHITELIST { + if x != nil { + return x.Whitelist + } + return nil +} + +type GetAllDomainInternalRsp_DATA_SERVICE struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Request []string `protobuf:"bytes,1,rep,name=request,proto3" json:"request"` + Socket []string `protobuf:"bytes,2,rep,name=socket,proto3" json:"socket"` + Download []string `protobuf:"bytes,3,rep,name=download,proto3" json:"download"` + Upload []string `protobuf:"bytes,4,rep,name=upload,proto3" json:"upload"` +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) Reset() { + *x = GetAllDomainInternalRsp_DATA_SERVICE{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalRsp_DATA_SERVICE) ProtoMessage() {} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalRsp_DATA_SERVICE.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalRsp_DATA_SERVICE) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{1, 0, 0} +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) GetRequest() []string { + if x != nil { + return x.Request + } + return nil +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) GetSocket() []string { + if x != nil { + return x.Socket + } + return nil +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) GetDownload() []string { + if x != nil { + return x.Download + } + return nil +} + +func (x *GetAllDomainInternalRsp_DATA_SERVICE) GetUpload() []string { + if x != nil { + return x.Upload + } + return nil +} + +type GetAllDomainInternalRsp_DATA_BUSINESS struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *GetAllDomainInternalRsp_DATA_BUSINESS) Reset() { + *x = GetAllDomainInternalRsp_DATA_BUSINESS{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalRsp_DATA_BUSINESS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalRsp_DATA_BUSINESS) ProtoMessage() {} + +func (x *GetAllDomainInternalRsp_DATA_BUSINESS) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalRsp_DATA_BUSINESS.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalRsp_DATA_BUSINESS) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{1, 0, 1} +} + +func (x *GetAllDomainInternalRsp_DATA_BUSINESS) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetAllDomainInternalRsp_DATA_WHITELIST struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *GetAllDomainInternalRsp_DATA_WHITELIST) Reset() { + *x = GetAllDomainInternalRsp_DATA_WHITELIST{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalRsp_DATA_WHITELIST) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalRsp_DATA_WHITELIST) ProtoMessage() {} + +func (x *GetAllDomainInternalRsp_DATA_WHITELIST) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalRsp_DATA_WHITELIST.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalRsp_DATA_WHITELIST) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{1, 0, 2} +} + +func (x *GetAllDomainInternalRsp_DATA_WHITELIST) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetAllDomainInternalV2Rsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Service *GetAllDomainInternalV2Rsp_DATA_SERVICE `protobuf:"bytes,2,opt,name=service,proto3" json:"service"` + Business *GetAllDomainInternalV2Rsp_DATA_BUSINESS `protobuf:"bytes,3,opt,name=business,proto3" json:"business"` + Whitelist *GetAllDomainInternalV2Rsp_DATA_WHITELIST `protobuf:"bytes,4,opt,name=whitelist,proto3" json:"whitelist"` + Blacklist *GetAllDomainInternalV2Rsp_DATA_BLACKLIST `protobuf:"bytes,5,opt,name=blacklist,proto3" json:"blacklist"` +} + +func (x *GetAllDomainInternalV2Rsp_DATA) Reset() { + *x = GetAllDomainInternalV2Rsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp_DATA) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp_DATA.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *GetAllDomainInternalV2Rsp_DATA) GetService() *GetAllDomainInternalV2Rsp_DATA_SERVICE { + if x != nil { + return x.Service + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA) GetBusiness() *GetAllDomainInternalV2Rsp_DATA_BUSINESS { + if x != nil { + return x.Business + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA) GetWhitelist() *GetAllDomainInternalV2Rsp_DATA_WHITELIST { + if x != nil { + return x.Whitelist + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA) GetBlacklist() *GetAllDomainInternalV2Rsp_DATA_BLACKLIST { + if x != nil { + return x.Blacklist + } + return nil +} + +type GetAllDomainInternalV2Rsp_DATA_SERVICE struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Request []string `protobuf:"bytes,1,rep,name=request,proto3" json:"request"` + Socket []string `protobuf:"bytes,2,rep,name=socket,proto3" json:"socket"` + Download []string `protobuf:"bytes,3,rep,name=download,proto3" json:"download"` + Upload []string `protobuf:"bytes,4,rep,name=upload,proto3" json:"upload"` +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) Reset() { + *x = GetAllDomainInternalV2Rsp_DATA_SERVICE{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp_DATA_SERVICE) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp_DATA_SERVICE.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp_DATA_SERVICE) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3, 0, 0} +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) GetRequest() []string { + if x != nil { + return x.Request + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) GetSocket() []string { + if x != nil { + return x.Socket + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) GetDownload() []string { + if x != nil { + return x.Download + } + return nil +} + +func (x *GetAllDomainInternalV2Rsp_DATA_SERVICE) GetUpload() []string { + if x != nil { + return x.Upload + } + return nil +} + +type GetAllDomainInternalV2Rsp_DATA_BUSINESS struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BUSINESS) Reset() { + *x = GetAllDomainInternalV2Rsp_DATA_BUSINESS{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BUSINESS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp_DATA_BUSINESS) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp_DATA_BUSINESS) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp_DATA_BUSINESS.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp_DATA_BUSINESS) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3, 0, 1} +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BUSINESS) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetAllDomainInternalV2Rsp_DATA_WHITELIST struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *GetAllDomainInternalV2Rsp_DATA_WHITELIST) Reset() { + *x = GetAllDomainInternalV2Rsp_DATA_WHITELIST{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp_DATA_WHITELIST) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp_DATA_WHITELIST) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp_DATA_WHITELIST) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp_DATA_WHITELIST.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp_DATA_WHITELIST) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3, 0, 2} +} + +func (x *GetAllDomainInternalV2Rsp_DATA_WHITELIST) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetAllDomainInternalV2Rsp_DATA_BLACKLIST struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []string `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains"` +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BLACKLIST) Reset() { + *x = GetAllDomainInternalV2Rsp_DATA_BLACKLIST{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BLACKLIST) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAllDomainInternalV2Rsp_DATA_BLACKLIST) ProtoMessage() {} + +func (x *GetAllDomainInternalV2Rsp_DATA_BLACKLIST) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAllDomainInternalV2Rsp_DATA_BLACKLIST.ProtoReflect.Descriptor instead. +func (*GetAllDomainInternalV2Rsp_DATA_BLACKLIST) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{3, 0, 3} +} + +func (x *GetAllDomainInternalV2Rsp_DATA_BLACKLIST) GetDomains() []string { + if x != nil { + return x.Domains + } + return nil +} + +type GetOrganDomainsWithCrtReq_DomainValidate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Md5 string `protobuf:"bytes,1,opt,name=md5,proto3" json:"md5"` + Expired bool `protobuf:"varint,2,opt,name=expired,proto3" json:"expired"` +} + +func (x *GetOrganDomainsWithCrtReq_DomainValidate) Reset() { + *x = GetOrganDomainsWithCrtReq_DomainValidate{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganDomainsWithCrtReq_DomainValidate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganDomainsWithCrtReq_DomainValidate) ProtoMessage() {} + +func (x *GetOrganDomainsWithCrtReq_DomainValidate) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganDomainsWithCrtReq_DomainValidate.ProtoReflect.Descriptor instead. +func (*GetOrganDomainsWithCrtReq_DomainValidate) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *GetOrganDomainsWithCrtReq_DomainValidate) GetMd5() string { + if x != nil { + return x.Md5 + } + return "" +} + +func (x *GetOrganDomainsWithCrtReq_DomainValidate) GetExpired() bool { + if x != nil { + return x.Expired + } + return false +} + +type GetOrganDomainsWithCrtRsp_DomainWithCrt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain"` + Crt string `protobuf:"bytes,2,opt,name=crt,proto3" json:"crt"` + Expired bool `protobuf:"varint,3,opt,name=expired,proto3" json:"expired"` +} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) Reset() { + *x = GetOrganDomainsWithCrtRsp_DomainWithCrt{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_domain_manager_request_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetOrganDomainsWithCrtRsp_DomainWithCrt) ProtoMessage() {} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) ProtoReflect() protoreflect.Message { + mi := &file_mop_domain_manager_request_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetOrganDomainsWithCrtRsp_DomainWithCrt.ProtoReflect.Descriptor instead. +func (*GetOrganDomainsWithCrtRsp_DomainWithCrt) Descriptor() ([]byte, []int) { + return file_mop_domain_manager_request_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) GetCrt() string { + if x != nil { + return x.Crt + } + return "" +} + +func (x *GetOrganDomainsWithCrtRsp_DomainWithCrt) GetExpired() bool { + if x != nil { + return x.Expired + } + return false +} + +var File_mop_domain_manager_request_proto protoreflect.FileDescriptor + +var file_mop_domain_manager_request_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x6d, 0x6f, 0x70, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x12, + 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x61, 0x70, 0x70, 0x49, 0x64, 0x22, 0x95, 0x04, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x73, + 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x99, 0x03, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x42, 0x0a, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, 0x53, 0x45, + 0x52, 0x56, 0x49, 0x43, 0x45, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, + 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, + 0x54, 0x41, 0x2e, 0x42, 0x55, 0x53, 0x49, 0x4e, 0x45, 0x53, 0x53, 0x52, 0x08, 0x62, 0x75, 0x73, + 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x48, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, + 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, 0x57, 0x48, 0x49, 0x54, 0x45, + 0x4c, 0x49, 0x53, 0x54, 0x52, 0x09, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x1a, + 0x6f, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x1a, 0x24, 0x0a, 0x08, 0x42, 0x55, 0x53, 0x49, 0x4e, 0x45, 0x53, 0x53, 0x12, 0x18, 0x0a, 0x07, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x25, 0x0a, 0x09, 0x57, 0x48, 0x49, 0x54, 0x45, 0x4c, + 0x49, 0x53, 0x54, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x22, 0x35, 0x0a, + 0x19, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, + 0x67, 0x61, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x49, 0x64, 0x22, 0x92, 0x05, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, + 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x36, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x62, 0x2e, + 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x92, 0x04, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x12, 0x44, 0x0a, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, + 0x54, 0x41, 0x2e, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, + 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, + 0x32, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, 0x42, 0x55, 0x53, 0x49, 0x4e, 0x45, + 0x53, 0x53, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x09, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, 0x73, 0x70, 0x2e, 0x44, + 0x41, 0x54, 0x41, 0x2e, 0x57, 0x48, 0x49, 0x54, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x52, 0x09, 0x77, + 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x4a, 0x0a, 0x09, 0x62, 0x6c, 0x61, 0x63, + 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x2e, + 0x42, 0x4c, 0x41, 0x43, 0x4b, 0x4c, 0x49, 0x53, 0x54, 0x52, 0x09, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x6c, 0x69, 0x73, 0x74, 0x1a, 0x6f, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x24, 0x0a, 0x08, 0x42, 0x55, 0x53, 0x49, 0x4e, 0x45, 0x53, + 0x53, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x25, 0x0a, 0x09, 0x57, + 0x48, 0x49, 0x54, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x73, 0x1a, 0x25, 0x0a, 0x09, 0x42, 0x4c, 0x41, 0x43, 0x4b, 0x4c, 0x49, 0x53, 0x54, 0x12, + 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x22, 0xcb, 0x02, 0x0a, 0x19, 0x47, 0x65, + 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, + 0x68, 0x43, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x67, 0x61, 0x6e, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x49, + 0x64, 0x12, 0x62, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x43, 0x72, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x70, + 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x65, 0x71, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x43, 0x72, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x43, 0x72, 0x74, 0x1a, 0x3c, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x64, 0x35, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x64, 0x35, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x64, 0x1a, 0x72, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x43, 0x72, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x65, 0x71, 0x2e, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdb, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4f, + 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, + 0x72, 0x74, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x3f, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x73, 0x70, 0x2e, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x53, 0x0a, 0x0d, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x72, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x64, 0x32, 0x9a, 0x02, 0x0a, 0x10, 0x4d, 0x6f, 0x70, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x1a, + 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x58, + 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x32, 0x12, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x56, 0x32, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x6c, 0x6c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x56, 0x32, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4f, + 0x72, 0x67, 0x61, 0x6e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, + 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x72, 0x74, 0x52, 0x73, 0x70, + 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_mop_domain_manager_request_proto_rawDescOnce sync.Once + file_mop_domain_manager_request_proto_rawDescData = file_mop_domain_manager_request_proto_rawDesc +) + +func file_mop_domain_manager_request_proto_rawDescGZIP() []byte { + file_mop_domain_manager_request_proto_rawDescOnce.Do(func() { + file_mop_domain_manager_request_proto_rawDescData = protoimpl.X.CompressGZIP(file_mop_domain_manager_request_proto_rawDescData) + }) + return file_mop_domain_manager_request_proto_rawDescData +} + +var file_mop_domain_manager_request_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_mop_domain_manager_request_proto_goTypes = []interface{}{ + (*GetAllDomainInternalReq)(nil), // 0: pb.GetAllDomainInternalReq + (*GetAllDomainInternalRsp)(nil), // 1: pb.GetAllDomainInternalRsp + (*GetAllDomainInternalV2Req)(nil), // 2: pb.GetAllDomainInternalV2Req + (*GetAllDomainInternalV2Rsp)(nil), // 3: pb.GetAllDomainInternalV2Rsp + (*GetOrganDomainsWithCrtReq)(nil), // 4: pb.GetOrganDomainsWithCrtReq + (*GetOrganDomainsWithCrtRsp)(nil), // 5: pb.GetOrganDomainsWithCrtRsp + (*GetAllDomainInternalRsp_DATA)(nil), // 6: pb.GetAllDomainInternalRsp.DATA + (*GetAllDomainInternalRsp_DATA_SERVICE)(nil), // 7: pb.GetAllDomainInternalRsp.DATA.SERVICE + (*GetAllDomainInternalRsp_DATA_BUSINESS)(nil), // 8: pb.GetAllDomainInternalRsp.DATA.BUSINESS + (*GetAllDomainInternalRsp_DATA_WHITELIST)(nil), // 9: pb.GetAllDomainInternalRsp.DATA.WHITELIST + (*GetAllDomainInternalV2Rsp_DATA)(nil), // 10: pb.GetAllDomainInternalV2Rsp.DATA + (*GetAllDomainInternalV2Rsp_DATA_SERVICE)(nil), // 11: pb.GetAllDomainInternalV2Rsp.DATA.SERVICE + (*GetAllDomainInternalV2Rsp_DATA_BUSINESS)(nil), // 12: pb.GetAllDomainInternalV2Rsp.DATA.BUSINESS + (*GetAllDomainInternalV2Rsp_DATA_WHITELIST)(nil), // 13: pb.GetAllDomainInternalV2Rsp.DATA.WHITELIST + (*GetAllDomainInternalV2Rsp_DATA_BLACKLIST)(nil), // 14: pb.GetAllDomainInternalV2Rsp.DATA.BLACKLIST + (*GetOrganDomainsWithCrtReq_DomainValidate)(nil), // 15: pb.GetOrganDomainsWithCrtReq.DomainValidate + nil, // 16: pb.GetOrganDomainsWithCrtReq.ValidateDomainCrtEntry + (*GetOrganDomainsWithCrtRsp_DomainWithCrt)(nil), // 17: pb.GetOrganDomainsWithCrtRsp.DomainWithCrt + (*CommonResult)(nil), // 18: pb.CommonResult +} +var file_mop_domain_manager_request_proto_depIdxs = []int32{ + 18, // 0: pb.GetAllDomainInternalRsp.result:type_name -> pb.CommonResult + 6, // 1: pb.GetAllDomainInternalRsp.data:type_name -> pb.GetAllDomainInternalRsp.DATA + 18, // 2: pb.GetAllDomainInternalV2Rsp.result:type_name -> pb.CommonResult + 10, // 3: pb.GetAllDomainInternalV2Rsp.data:type_name -> pb.GetAllDomainInternalV2Rsp.DATA + 16, // 4: pb.GetOrganDomainsWithCrtReq.validateDomainCrt:type_name -> pb.GetOrganDomainsWithCrtReq.ValidateDomainCrtEntry + 18, // 5: pb.GetOrganDomainsWithCrtRsp.result:type_name -> pb.CommonResult + 17, // 6: pb.GetOrganDomainsWithCrtRsp.data:type_name -> pb.GetOrganDomainsWithCrtRsp.DomainWithCrt + 7, // 7: pb.GetAllDomainInternalRsp.DATA.service:type_name -> pb.GetAllDomainInternalRsp.DATA.SERVICE + 8, // 8: pb.GetAllDomainInternalRsp.DATA.business:type_name -> pb.GetAllDomainInternalRsp.DATA.BUSINESS + 9, // 9: pb.GetAllDomainInternalRsp.DATA.whitelist:type_name -> pb.GetAllDomainInternalRsp.DATA.WHITELIST + 11, // 10: pb.GetAllDomainInternalV2Rsp.DATA.service:type_name -> pb.GetAllDomainInternalV2Rsp.DATA.SERVICE + 12, // 11: pb.GetAllDomainInternalV2Rsp.DATA.business:type_name -> pb.GetAllDomainInternalV2Rsp.DATA.BUSINESS + 13, // 12: pb.GetAllDomainInternalV2Rsp.DATA.whitelist:type_name -> pb.GetAllDomainInternalV2Rsp.DATA.WHITELIST + 14, // 13: pb.GetAllDomainInternalV2Rsp.DATA.blacklist:type_name -> pb.GetAllDomainInternalV2Rsp.DATA.BLACKLIST + 15, // 14: pb.GetOrganDomainsWithCrtReq.ValidateDomainCrtEntry.value:type_name -> pb.GetOrganDomainsWithCrtReq.DomainValidate + 0, // 15: pb.MopDomainManager.GetAllDomainInternal:input_type -> pb.GetAllDomainInternalReq + 2, // 16: pb.MopDomainManager.GetAllDomainInternalV2:input_type -> pb.GetAllDomainInternalV2Req + 4, // 17: pb.MopDomainManager.GetOrganDomainsWithCrt:input_type -> pb.GetOrganDomainsWithCrtReq + 1, // 18: pb.MopDomainManager.GetAllDomainInternal:output_type -> pb.GetAllDomainInternalRsp + 3, // 19: pb.MopDomainManager.GetAllDomainInternalV2:output_type -> pb.GetAllDomainInternalV2Rsp + 5, // 20: pb.MopDomainManager.GetOrganDomainsWithCrt:output_type -> pb.GetOrganDomainsWithCrtRsp + 18, // [18:21] is the sub-list for method output_type + 15, // [15:18] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name +} + +func init() { file_mop_domain_manager_request_proto_init() } +func file_mop_domain_manager_request_proto_init() { + if File_mop_domain_manager_request_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_mop_domain_manager_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Req); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganDomainsWithCrtReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganDomainsWithCrtRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalRsp_DATA_SERVICE); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalRsp_DATA_BUSINESS); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalRsp_DATA_WHITELIST); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp_DATA_SERVICE); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp_DATA_BUSINESS); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp_DATA_WHITELIST); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAllDomainInternalV2Rsp_DATA_BLACKLIST); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganDomainsWithCrtReq_DomainValidate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_domain_manager_request_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetOrganDomainsWithCrtRsp_DomainWithCrt); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_mop_domain_manager_request_proto_rawDesc, + NumEnums: 0, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mop_domain_manager_request_proto_goTypes, + DependencyIndexes: file_mop_domain_manager_request_proto_depIdxs, + MessageInfos: file_mop_domain_manager_request_proto_msgTypes, + }.Build() + File_mop_domain_manager_request_proto = out.File + file_mop_domain_manager_request_proto_rawDesc = nil + file_mop_domain_manager_request_proto_goTypes = nil + file_mop_domain_manager_request_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MopDomainManagerClient is the client API for MopDomainManager service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MopDomainManagerClient interface { + GetAllDomainInternal(ctx context.Context, in *GetAllDomainInternalReq, opts ...grpc.CallOption) (*GetAllDomainInternalRsp, error) + GetAllDomainInternalV2(ctx context.Context, in *GetAllDomainInternalV2Req, opts ...grpc.CallOption) (*GetAllDomainInternalV2Rsp, error) + GetOrganDomainsWithCrt(ctx context.Context, in *GetOrganDomainsWithCrtReq, opts ...grpc.CallOption) (*GetOrganDomainsWithCrtRsp, error) +} + +type mopDomainManagerClient struct { + cc grpc.ClientConnInterface +} + +func NewMopDomainManagerClient(cc grpc.ClientConnInterface) MopDomainManagerClient { + return &mopDomainManagerClient{cc} +} + +func (c *mopDomainManagerClient) GetAllDomainInternal(ctx context.Context, in *GetAllDomainInternalReq, opts ...grpc.CallOption) (*GetAllDomainInternalRsp, error) { + out := new(GetAllDomainInternalRsp) + err := c.cc.Invoke(ctx, "/pb.MopDomainManager/GetAllDomainInternal", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopDomainManagerClient) GetAllDomainInternalV2(ctx context.Context, in *GetAllDomainInternalV2Req, opts ...grpc.CallOption) (*GetAllDomainInternalV2Rsp, error) { + out := new(GetAllDomainInternalV2Rsp) + err := c.cc.Invoke(ctx, "/pb.MopDomainManager/GetAllDomainInternalV2", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *mopDomainManagerClient) GetOrganDomainsWithCrt(ctx context.Context, in *GetOrganDomainsWithCrtReq, opts ...grpc.CallOption) (*GetOrganDomainsWithCrtRsp, error) { + out := new(GetOrganDomainsWithCrtRsp) + err := c.cc.Invoke(ctx, "/pb.MopDomainManager/GetOrganDomainsWithCrt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MopDomainManagerServer is the server API for MopDomainManager service. +type MopDomainManagerServer interface { + GetAllDomainInternal(context.Context, *GetAllDomainInternalReq) (*GetAllDomainInternalRsp, error) + GetAllDomainInternalV2(context.Context, *GetAllDomainInternalV2Req) (*GetAllDomainInternalV2Rsp, error) + GetOrganDomainsWithCrt(context.Context, *GetOrganDomainsWithCrtReq) (*GetOrganDomainsWithCrtRsp, error) +} + +// UnimplementedMopDomainManagerServer can be embedded to have forward compatible implementations. +type UnimplementedMopDomainManagerServer struct { +} + +func (*UnimplementedMopDomainManagerServer) GetAllDomainInternal(context.Context, *GetAllDomainInternalReq) (*GetAllDomainInternalRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllDomainInternal not implemented") +} +func (*UnimplementedMopDomainManagerServer) GetAllDomainInternalV2(context.Context, *GetAllDomainInternalV2Req) (*GetAllDomainInternalV2Rsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAllDomainInternalV2 not implemented") +} +func (*UnimplementedMopDomainManagerServer) GetOrganDomainsWithCrt(context.Context, *GetOrganDomainsWithCrtReq) (*GetOrganDomainsWithCrtRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrganDomainsWithCrt not implemented") +} + +func RegisterMopDomainManagerServer(s *grpc.Server, srv MopDomainManagerServer) { + s.RegisterService(&_MopDomainManager_serviceDesc, srv) +} + +func _MopDomainManager_GetAllDomainInternal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllDomainInternalReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopDomainManagerServer).GetAllDomainInternal(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopDomainManager/GetAllDomainInternal", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopDomainManagerServer).GetAllDomainInternal(ctx, req.(*GetAllDomainInternalReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopDomainManager_GetAllDomainInternalV2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAllDomainInternalV2Req) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopDomainManagerServer).GetAllDomainInternalV2(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopDomainManager/GetAllDomainInternalV2", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopDomainManagerServer).GetAllDomainInternalV2(ctx, req.(*GetAllDomainInternalV2Req)) + } + return interceptor(ctx, in, info, handler) +} + +func _MopDomainManager_GetOrganDomainsWithCrt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetOrganDomainsWithCrtReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopDomainManagerServer).GetOrganDomainsWithCrt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopDomainManager/GetOrganDomainsWithCrt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopDomainManagerServer).GetOrganDomainsWithCrt(ctx, req.(*GetOrganDomainsWithCrtReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _MopDomainManager_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.MopDomainManager", + HandlerType: (*MopDomainManagerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAllDomainInternal", + Handler: _MopDomainManager_GetAllDomainInternal_Handler, + }, + { + MethodName: "GetAllDomainInternalV2", + Handler: _MopDomainManager_GetAllDomainInternalV2_Handler, + }, + { + MethodName: "GetOrganDomainsWithCrt", + Handler: _MopDomainManager_GetOrganDomainsWithCrt_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "mop_domain_manager_request.proto", +} diff --git a/infrastructure/protobuf/golang/mop_purchasing_rights_manager.pb.go b/infrastructure/protobuf/golang/mop_purchasing_rights_manager.pb.go new file mode 100644 index 0000000..7cb8574 --- /dev/null +++ b/infrastructure/protobuf/golang/mop_purchasing_rights_manager.pb.go @@ -0,0 +1,385 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.11.4 +// source: mop_purchasing_rights_manager.proto + +package pb + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +//接口一 +type QueryBusinessStatusReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BusinessId string `protobuf:"bytes,1,opt,name=businessId,proto3" json:"businessId"` +} + +func (x *QueryBusinessStatusReq) Reset() { + *x = QueryBusinessStatusReq{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryBusinessStatusReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryBusinessStatusReq) ProtoMessage() {} + +func (x *QueryBusinessStatusReq) ProtoReflect() protoreflect.Message { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryBusinessStatusReq.ProtoReflect.Descriptor instead. +func (*QueryBusinessStatusReq) Descriptor() ([]byte, []int) { + return file_mop_purchasing_rights_manager_proto_rawDescGZIP(), []int{0} +} + +func (x *QueryBusinessStatusReq) GetBusinessId() string { + if x != nil { + return x.BusinessId + } + return "" +} + +type QueryBusinessStatusRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *CommonResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` + Data *QueryBusinessStatusRsp_DATA `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +} + +func (x *QueryBusinessStatusRsp) Reset() { + *x = QueryBusinessStatusRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryBusinessStatusRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryBusinessStatusRsp) ProtoMessage() {} + +func (x *QueryBusinessStatusRsp) ProtoReflect() protoreflect.Message { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryBusinessStatusRsp.ProtoReflect.Descriptor instead. +func (*QueryBusinessStatusRsp) Descriptor() ([]byte, []int) { + return file_mop_purchasing_rights_manager_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryBusinessStatusRsp) GetResult() *CommonResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *QueryBusinessStatusRsp) GetData() *QueryBusinessStatusRsp_DATA { + if x != nil { + return x.Data + } + return nil +} + +type QueryBusinessStatusRsp_DATA struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status"` +} + +func (x *QueryBusinessStatusRsp_DATA) Reset() { + *x = QueryBusinessStatusRsp_DATA{} + if protoimpl.UnsafeEnabled { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryBusinessStatusRsp_DATA) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryBusinessStatusRsp_DATA) ProtoMessage() {} + +func (x *QueryBusinessStatusRsp_DATA) ProtoReflect() protoreflect.Message { + mi := &file_mop_purchasing_rights_manager_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QueryBusinessStatusRsp_DATA.ProtoReflect.Descriptor instead. +func (*QueryBusinessStatusRsp_DATA) Descriptor() ([]byte, []int) { + return file_mop_purchasing_rights_manager_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *QueryBusinessStatusRsp_DATA) GetStatus() int32 { + if x != nil { + return x.Status + } + return 0 +} + +var File_mop_purchasing_rights_manager_proto protoreflect.FileDescriptor + +var file_mop_purchasing_rights_manager_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x6d, 0x6f, 0x70, 0x5f, 0x70, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, + 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x38, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x49, + 0x64, 0x22, 0x97, 0x01, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x73, 0x70, 0x12, 0x28, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, + 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, + 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x73, 0x70, + 0x2e, 0x44, 0x41, 0x54, 0x41, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x1e, 0x0a, 0x04, 0x44, + 0x41, 0x54, 0x41, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0x6d, 0x0a, 0x1a, 0x4d, + 0x6f, 0x70, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x13, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x70, + 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x73, 0x70, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2f, + 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_mop_purchasing_rights_manager_proto_rawDescOnce sync.Once + file_mop_purchasing_rights_manager_proto_rawDescData = file_mop_purchasing_rights_manager_proto_rawDesc +) + +func file_mop_purchasing_rights_manager_proto_rawDescGZIP() []byte { + file_mop_purchasing_rights_manager_proto_rawDescOnce.Do(func() { + file_mop_purchasing_rights_manager_proto_rawDescData = protoimpl.X.CompressGZIP(file_mop_purchasing_rights_manager_proto_rawDescData) + }) + return file_mop_purchasing_rights_manager_proto_rawDescData +} + +var file_mop_purchasing_rights_manager_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_mop_purchasing_rights_manager_proto_goTypes = []interface{}{ + (*QueryBusinessStatusReq)(nil), // 0: pb.QueryBusinessStatusReq + (*QueryBusinessStatusRsp)(nil), // 1: pb.QueryBusinessStatusRsp + (*QueryBusinessStatusRsp_DATA)(nil), // 2: pb.QueryBusinessStatusRsp.DATA + (*CommonResult)(nil), // 3: pb.CommonResult +} +var file_mop_purchasing_rights_manager_proto_depIdxs = []int32{ + 3, // 0: pb.QueryBusinessStatusRsp.result:type_name -> pb.CommonResult + 2, // 1: pb.QueryBusinessStatusRsp.data:type_name -> pb.QueryBusinessStatusRsp.DATA + 0, // 2: pb.MopPurchasingRightsManager.QueryBusinessStatus:input_type -> pb.QueryBusinessStatusReq + 1, // 3: pb.MopPurchasingRightsManager.QueryBusinessStatus:output_type -> pb.QueryBusinessStatusRsp + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_mop_purchasing_rights_manager_proto_init() } +func file_mop_purchasing_rights_manager_proto_init() { + if File_mop_purchasing_rights_manager_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_mop_purchasing_rights_manager_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryBusinessStatusReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_purchasing_rights_manager_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryBusinessStatusRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mop_purchasing_rights_manager_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryBusinessStatusRsp_DATA); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_mop_purchasing_rights_manager_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mop_purchasing_rights_manager_proto_goTypes, + DependencyIndexes: file_mop_purchasing_rights_manager_proto_depIdxs, + MessageInfos: file_mop_purchasing_rights_manager_proto_msgTypes, + }.Build() + File_mop_purchasing_rights_manager_proto = out.File + file_mop_purchasing_rights_manager_proto_rawDesc = nil + file_mop_purchasing_rights_manager_proto_goTypes = nil + file_mop_purchasing_rights_manager_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// MopPurchasingRightsManagerClient is the client API for MopPurchasingRightsManager service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MopPurchasingRightsManagerClient interface { + QueryBusinessStatus(ctx context.Context, in *QueryBusinessStatusReq, opts ...grpc.CallOption) (*QueryBusinessStatusRsp, error) +} + +type mopPurchasingRightsManagerClient struct { + cc grpc.ClientConnInterface +} + +func NewMopPurchasingRightsManagerClient(cc grpc.ClientConnInterface) MopPurchasingRightsManagerClient { + return &mopPurchasingRightsManagerClient{cc} +} + +func (c *mopPurchasingRightsManagerClient) QueryBusinessStatus(ctx context.Context, in *QueryBusinessStatusReq, opts ...grpc.CallOption) (*QueryBusinessStatusRsp, error) { + out := new(QueryBusinessStatusRsp) + err := c.cc.Invoke(ctx, "/pb.MopPurchasingRightsManager/QueryBusinessStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MopPurchasingRightsManagerServer is the server API for MopPurchasingRightsManager service. +type MopPurchasingRightsManagerServer interface { + QueryBusinessStatus(context.Context, *QueryBusinessStatusReq) (*QueryBusinessStatusRsp, error) +} + +// UnimplementedMopPurchasingRightsManagerServer can be embedded to have forward compatible implementations. +type UnimplementedMopPurchasingRightsManagerServer struct { +} + +func (*UnimplementedMopPurchasingRightsManagerServer) QueryBusinessStatus(context.Context, *QueryBusinessStatusReq) (*QueryBusinessStatusRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryBusinessStatus not implemented") +} + +func RegisterMopPurchasingRightsManagerServer(s *grpc.Server, srv MopPurchasingRightsManagerServer) { + s.RegisterService(&_MopPurchasingRightsManager_serviceDesc, srv) +} + +func _MopPurchasingRightsManager_QueryBusinessStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBusinessStatusReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MopPurchasingRightsManagerServer).QueryBusinessStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.MopPurchasingRightsManager/QueryBusinessStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MopPurchasingRightsManagerServer).QueryBusinessStatus(ctx, req.(*QueryBusinessStatusReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _MopPurchasingRightsManager_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.MopPurchasingRightsManager", + HandlerType: (*MopPurchasingRightsManagerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "QueryBusinessStatus", + Handler: _MopPurchasingRightsManager_QueryBusinessStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "mop_purchasing_rights_manager.proto", +} diff --git a/infrastructure/protobuf/make.sh b/infrastructure/protobuf/make.sh new file mode 100755 index 0000000..602f69f --- /dev/null +++ b/infrastructure/protobuf/make.sh @@ -0,0 +1,13 @@ +cd proto + +protoc -I ./ *.proto --go_out=plugins=grpc:. + +if [ $? -ne 0 ];then + echo "生成go代码失败!" +else + cd ../golang + rm -rf *.go + mv ../proto/*.go . + sed -i '' 's/,omitempty//g' *.go + echo "生成go代码成功!" +fi \ No newline at end of file diff --git a/infrastructure/protobuf/proto/common.proto b/infrastructure/protobuf/proto/common.proto new file mode 100644 index 0000000..d590b43 --- /dev/null +++ b/infrastructure/protobuf/proto/common.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +message CommonResult { + string error = 1; + string errcode = 2; + int32 httpcode = 3; +} \ No newline at end of file diff --git a/infrastructure/protobuf/proto/mop_account_system_organ_request.proto b/infrastructure/protobuf/proto/mop_account_system_organ_request.proto new file mode 100644 index 0000000..587d18e --- /dev/null +++ b/infrastructure/protobuf/proto/mop_account_system_organ_request.proto @@ -0,0 +1,69 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +import "common.proto"; + +service MopAccountSystem { + rpc QueryOrganInfo (QueryOrganInfoReq) returns (QueryOrganInfoRsp) {} + rpc GetBusinessInfoById (GetBusinessInfoByIdReq) returns (GetBusinessInfoByIdRsp) {} +} + +//接口一 +message QueryOrganInfoReq { + string accountId = 1; +} + + +message QueryOrganInfoRsp { + CommonResult result = 1; + + message DATA { + string accountTraceId = 1; + string organTraceId = 2; + + message ACCOUNT_INFO { + string account = 1; + string phone = 2; + int64 createTime = 3; + } + ACCOUNT_INFO accountInfo = 3; + + message ORGSN_INFO_WITH_STATUS { + string name = 1; + string socialCreditCode = 2; + string licenseNetdiskId = 3; + string authorizationNetdiskId = 4; + int32 reviewStatus = 5; + } + ORGSN_INFO_WITH_STATUS organInfo = 4; + + message ADMIN_INFO { + string name = 1; + string identity = 2; + string phone = 3; + } + ADMIN_INFO adminInfo = 5; + } + + DATA data = 2; +} + +//接口二 +message GetBusinessInfoByIdReq { + string organTraceId = 1; +} + +message GetBusinessInfoByIdRsp { + CommonResult result = 1; + + message DATA { + string groupId = 1; + string groupName = 2; + int32 reviewStatus = 3; + string socialCreditCode = 4; + } + DATA data = 2; +} \ No newline at end of file diff --git a/infrastructure/protobuf/proto/mop_app_manage_svr_request.proto b/infrastructure/protobuf/proto/mop_app_manage_svr_request.proto new file mode 100644 index 0000000..d1dafdb --- /dev/null +++ b/infrastructure/protobuf/proto/mop_app_manage_svr_request.proto @@ -0,0 +1,316 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +import "common.proto"; +//import "google/protobuf/any.proto"; + +service MopAppManageSvr { + rpc RuleEngineGetAppInfo (RuleEngineGetAppInfoReq) returns (RuleEngineGetAppInfoRsp) {} + rpc RuleEngineGetAppVerInfo (RuleEngineGetAppVerInfoReq) returns (RuleEngineGetAppVerInfoRsp) {} + rpc OpenApiGetAppVerInfo (OpenApiGetAppVerInfoReq) returns (OpenApiGetAppVerInfoRsp) {} + rpc GetOrganIdBySdkKey (GetOrganIdBySdkKeyReq) returns (GetOrganIdBySdkKeyRsp) {} + rpc BatchGetAppAndVerInfo (BatchGetAppAndVerInfoReq) returns (BatchGetAppAndVerInfoRsp) {} + rpc BatchAppsByIdentity (BatchAppsByIdentityReq) returns (BatchAppsByIdentityRsp) {}//根据标识获取小程序信息 + rpc IdentityAppsCheck (IdentityAppsCheckReq) returns (IdentityAppsCheckRsp) {} + rpc OpenApiGetQRcodeAppVerInfo (OpenApiGetQRcodeAppVerInfoReq) returns (OpenApiGetAppVerInfoRsp) {} + rpc GetBuildAppInfo (GetBuildAppInfoReq) returns (GetBuildAppInfoRsp) {} +} + +//接口一 +message RuleEngineGetAppInfoReq { + string sdkKey = 1; + string appId = 2; + string sdkVer = 3; +} + +message Status { + string value = 1 ; + string reason = 2 ; + int64 lastUpdated = 3 ; + string modifiedBy = 4 ; +} + +message SpecificStatus { + string reason = 1; + int64 lastUpdated = 2; + string modifiedBy = 3; +} + +message MenuInfoRspDataItem { + string name = 1; + string id = 2; + string image = 3; +} + +message MenuInfoRspData { + int32 total = 1; + repeated MenuInfoRspDataItem list = 2; +} + +message ApiInfoRspData { + string apiName = 1; + string url = 2; +} + +message CustomData { + AppRuntimeDomain appRuntimeDomain = 1; + repeated SourceFileData sourceFile = 2; + string versionDescription = 3; + string detailDescription = 4; + MenuInfoRspData menuInfo = 5; + repeated ApiInfoRspData apiInfo = 6; +} + +message WechatLoginInfo { + string wechatOriginId = 1; + string profileUrl = 2; + string phoneUrl = 3; + string paymentUrl = 4; + repeated ExtUrls extUrls = 5; +} + +message ExtUrls { + string fieldName = 1; + string pageUrl = 2; +} + +message AppRuntimeDomain { + message Business{ + repeated string domains= 1; + } + message Service{ + repeated string download= 1; + repeated string request= 2; + repeated string socket= 3; + repeated string upload= 4; + } + message Whitelist { + repeated string domains= 1; + } + message Blacklist { + repeated string domains= 1; + } + Business business = 1; + Service service = 2; + Whitelist whitelist = 3; + Blacklist blacklist = 4; +} + +message SourceFileData { + string fileMd5 = 1; + string name = 2; + int64 uploadDate = 3; + string url = 4; + string sourceFileUrl = 5; + string basicPackVer = 6; + repeated Package packages = 7; +} + +message Package{ + string root =1; + string name=2; + repeated string pages=3; + bool independent = 4; + string filename = 5; + string fileUrl = 6; + string fileMd5 = 7; +} + +message AppInfoRspData { + string appClass = 1; + string appId = 2; + string appType = 3; + string coreDescription = 4; + string corporationId = 5; + int64 created = 6; + string createdBy = 7; + CustomData customData = 8; + string developerId = 9; + string groupId = 10; + string groupName = 11; + bool inGrayRelease = 12; + string logo = 13; + string name = 14; + int32 sequence = 15; + string version = 16; + Status status = 17; + bool isTemp = 18; + bool isUserLimit = 19; + bool needCrt = 20; + int32 developerStatus = 21; + WechatLoginInfo wechatLoginInfo = 22; + repeated string appTag = 23; + int32 privacySettingType = 24; + int32 projectType = 25; +} + +message RuleEngineGetAppInfoRsp { + CommonResult result = 1; + AppInfoRspData data = 2; + //google.protobuf.Any data = 2; +} + +//接口二 +message RuleEngineGetAppVerInfoReq { + string sdkKey = 1; + string appId = 2; + int32 version = 3; + string sdkVer = 4; +} + +message RuleEngineGetAppVerInfoRsp { + CommonResult result = 1; + AppInfoRspData data = 2; + //google.protobuf.Any data = 2; +} + +//接口三 +message OpenApiGetAppVerInfoReq { + string appId = 1; + int32 version = 2; + string sdkKey = 3; + string sdkVer = 4; +} + +message OpenApiGetAppVerInfoRsp { + CommonResult result = 1; + AppInfoRspData data = 2; + //google.protobuf.Any data = 2; +} + +//接口四 +message GetOrganIdBySdkKeyReq { + string sdkKey = 1; +} + +message GetOrganIdBySdkKeyRsp { + CommonResult result = 1; + message DATA { + string organId = 1; + bool isWhite = 2; + } + DATA data = 2; +} + +//接口五,批量获取小程序详情和小程序版本详情 +message BatchGetAppAndVerInfoReq { + string sdkKey = 1; + repeated string appList = 2; + message AppAndVer{ + string appId = 1; + int32 sequence = 2; + } + repeated AppAndVer appVerList = 3; + string sdkVer = 4; +} + +message BatchGetAppAndVerInfoRsp { + CommonResult result = 1; + message DATA { + repeated string appFailList = 1; + repeated AppInfoRspData appDataList = 2; + repeated string appVerFailList = 3; + repeated AppInfoRspData appVerDataList = 4; + } + DATA data = 2; +} + +message BatchAppsByIdentityReq { + string sdkKey = 1; + string source = 2; + string identityType = 3; + repeated BatchAppsByIdentityAppsItem apps = 4; +} + +message BatchAppsByIdentityAppsItem { + string appId = 1; + string identity = 2; +} + +message BatchAppsByIdentityRsp { + CommonResult result = 1; + message AppListItem { + string errcode = 1; + string error = 2; + AppInfoRspData appInfo = 3; + string externalAppStatus = 4; + string appId = 5; + string identity = 6; + } + message DATA { + repeated AppListItem appList = 1; + } + DATA data = 2; +} + +message IdentityAppsCheckReq { + string sdkKey = 1; + string source = 2; + string identityType = 3; + repeated IdentityAppsCheckAppsItem Apps = 4; +} + +message IdentityAppsCheckAppsItem { + string appId = 1; + string identity = 2; +} + +message IdentityAppsCheckRsp { + CommonResult result = 1; + message AppListItem { + string errcode = 1; + string error = 2; + message AppListItemData { + string appId = 1; + string identity = 2; + bool identityValid = 3; + } + AppListItemData data = 3; + } + message DATA { + repeated AppListItem appList = 1; + } + DATA data = 2; +} + +//接口六 +message OpenApiGetQRcodeAppVerInfoReq { + string redisKey = 1; + string sdkKey = 2; +} + +//接口七 +message GetBuildAppInfoReq { + string type = 1; + string sdkKey = 2; + string codeId = 3; +} + +message GetBuildAppInfoRsp { + CommonResult result = 1; + BuildAppInfo data = 2; +} + +message BuildAppInfo { + string codeId = 1; + string coreDescription = 2; + int64 created = 3; + string createdBy = 4; + CustomData customData = 5; + string groupId = 6; + string groupName = 7; + string logo = 8; + string name = 9; + string version = 10; + bool isTemp = 11; + string appId = 12; + bool needCrt = 13; + int32 developerStatus = 14; + WechatLoginInfo wechatLoginInfo = 15; + repeated string appTag = 16; + int32 privacySettingType = 17; + int32 projectType = 18; +} diff --git a/infrastructure/protobuf/proto/mop_applet_build_manager.proto b/infrastructure/protobuf/proto/mop_applet_build_manager.proto new file mode 100644 index 0000000..12afc95 --- /dev/null +++ b/infrastructure/protobuf/proto/mop_applet_build_manager.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +import "common.proto"; + +service MopAppletBuildManger { + rpc QueryEncrypted (QueryEncryptedReq) returns (QueryEncryptedRsp) {} +} + +//接口一 +message QueryEncryptedReq { + string sdkVersion = 1; +} + + +message QueryEncryptedRsp { + CommonResult result = 1; + + message DATA { + bool encrypted = 1; + } + + DATA data = 2; +} \ No newline at end of file diff --git a/infrastructure/protobuf/proto/mop_domain_manager_request.proto b/infrastructure/protobuf/proto/mop_domain_manager_request.proto new file mode 100644 index 0000000..7bc257c --- /dev/null +++ b/infrastructure/protobuf/proto/mop_domain_manager_request.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +import "common.proto"; + +service MopDomainManager { + rpc GetAllDomainInternal (GetAllDomainInternalReq) returns (GetAllDomainInternalRsp) {} + rpc GetAllDomainInternalV2 (GetAllDomainInternalV2Req) returns (GetAllDomainInternalV2Rsp) {} + rpc GetOrganDomainsWithCrt (GetOrganDomainsWithCrtReq) returns (GetOrganDomainsWithCrtRsp) {} +} + +//接口一 +message GetAllDomainInternalReq { + string appId = 1; +} + +message GetAllDomainInternalRsp { + CommonResult result = 1; + + message DATA { + message SERVICE { + repeated string request = 1; + repeated string socket = 2; + repeated string download = 3; + repeated string upload = 4; + } + + SERVICE service = 2; + + message BUSINESS { + repeated string domains = 1; + } + + BUSINESS business = 3; + + message WHITELIST { + repeated string domains = 1; + } + + WHITELIST whitelist = 4; + } + + DATA data = 2; +} + +message GetAllDomainInternalV2Req { + string organId = 1; +} + +message GetAllDomainInternalV2Rsp { + CommonResult result = 1; + + message DATA { + message SERVICE { + repeated string request = 1; + repeated string socket = 2; + repeated string download = 3; + repeated string upload = 4; + } + + SERVICE service = 2; + + message BUSINESS { + repeated string domains = 1; + } + + BUSINESS business = 3; + + message WHITELIST { + repeated string domains = 1; + } + + WHITELIST whitelist = 4; + + message BLACKLIST { + repeated string domains = 1; + } + + BLACKLIST blacklist = 5; + } + + DATA data = 2; +} + +message GetOrganDomainsWithCrtReq { + string organId = 1; + + message DomainValidate { + string md5 = 1; + bool expired = 2; + } + map validateDomainCrt = 2; +} + +message GetOrganDomainsWithCrtRsp { + CommonResult result = 1; + + message DomainWithCrt { + string domain = 1; + string crt = 2; + bool expired = 3; + } + + repeated DomainWithCrt data = 2; +} diff --git a/infrastructure/protobuf/proto/mop_purchasing_rights_manager.proto b/infrastructure/protobuf/proto/mop_purchasing_rights_manager.proto new file mode 100644 index 0000000..76bcbc8 --- /dev/null +++ b/infrastructure/protobuf/proto/mop_purchasing_rights_manager.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; + +package pb; + +option go_package = "./;pb"; + +import "common.proto"; + +service MopPurchasingRightsManager { + rpc QueryBusinessStatus (QueryBusinessStatusReq) returns (QueryBusinessStatusRsp) {} +} + +//接口一 +message QueryBusinessStatusReq { + string businessId = 1; +} + + +message QueryBusinessStatusRsp { + CommonResult result = 1; + + message DATA { + int32 status = 1; + } + + DATA data = 2; +} + diff --git a/infrastructure/utility/err_msg.go b/infrastructure/utility/err_msg.go new file mode 100644 index 0000000..2092065 --- /dev/null +++ b/infrastructure/utility/err_msg.go @@ -0,0 +1,270 @@ +package utility + +import ( + pb "finclip-app-manager/infrastructure/protobuf/golang" + "net/http" + + "github.com/gin-gonic/gin" +) + +const ( + OK = "OK" + FS_NOT_FOUND = "FS_NOT_FOUND" + FS_BAD_JSON = "FS_BAD_JSON" + FS_DB_ERR = "FS_DB_ERR" + FS_SYSTEM_CALL = "FS_SYSTEM_CALL" + FS_LACK_OF_APPID = "FS_LACK_OF_APPID" + FS_LACK_OF_SDKKEY = "FS_LACK_OF_SDKKEY" + FS_APP_ID_NOT_FOUND = "FS_APP_ID_NOT_FOUND" + FS_APP_SEQUENCE_NOT_FOUND = "FS_APP_SEQUENCE_NOT_FOUND" + FS_GET_GROUP_FAILED = "FS_GET_GROUP_FAILED" + FS_GET_DOMAIN_INFO_ERROR = "FS_GET_DOMAIN_INFO_ERROR" + FS_GET_ACCOUNTINFO_ERROR = "FS_GET_ACCOUNTINFO_ERROR" + FS_GET_MENUINFO_ERROR = "FS_GET_MENUINFO_ERROR" + FS_FORBIDDEN = "FS_FORBIDDEN" + FS_PUBLISHING_OR_UNPUBLISHING = "FS_PUBLISHING_OR_UNPUBLISHING" + FS_ACCESS_RULE_NOT_SET = "FS_ACCESS_RULE_NOT_SET" + FS_INVALID_STATE = "FS_INVALID_STATE" + FS_LACK_OF_ORGANIZAITON_ID = "FS_LACK_OF_ORGANIZATION_ID" + FS_LACK_OF_USER_ID = "FS_LACK_OF_USER_ID" + FS_SEQUENCE_LESS_THAN_CURRENT = "FS_SEQUENCE_LESS_THAN_CURRENT" + FS_SPECIFIED_APP_ID_NOT_DELETEABLE = "FS_SPECIFIED_APP_ID_NOT_DELETEABLE" + FS_APP_OWNED_BY_USER = "FS_APP_OWNED_BY_USER" + FS_INVALID_APPROVAL_STATE = "FS_INVALID_APPROVAL_STATE" + FS_INVALID_BINDING_OPERATION = "FS_INVALID_BINDING_OPERATION" + FS_LACK_OF_BINDING_ID = "FS_LACK_OF_BINDING_ID" + FS_APP_ASSOCIATED = "FS_APP_ASSOCIATED" + FS_APP_NOT_ASSOCIATED = "FS_APP_NOT_ASSOCIATED" + FS_INVALID_COOPERATE_STATUS = "FS_INVALID_COOPERATE_STATUS" + FS_APP_NOT_PUBLISHED = "FS_APP_NOT_PUBLISHED" + FS_APP_BUNDLEID_REPEAT = "FS_APP_BUNDLEID_REPEAT" + FS_COOPERATION_TERMINATED = "FS_COOPERATION_TERMINATED" + FS_ORGAN_STATUS_INVALID = "FS_ORGAN_STATUS_INVALID" + FS_APP_NOT_ASS_BIND = "FS_APP_NOT_ASS_BIND" + FS_BIND_NOT_FOUND = "FS_BIND_NOT_FOUND" + FS_SERVICE_UNAVAILABLE = "FS_SERVICE_UNAVAILABLE" + FS_APP_PAY_EXPIRE = "FS_APP_PAY_EXPIRE" + FS_BIND_PAY_EXPIRE = "FS_BIND_PAY_EXPIRE" + FS_BINDING_NAME_REPEAT = "FS_BINDING_NAME_REPEAT" + FS_TIMESTAMP_TIMEOUT = "FS_TIMESTAMP_TIMEOUT" + FS_UUID_INVAILD = "FS_UUID_INVAILD" + FS_SIGNATURE_INVAILD = "FS_SIGNATURE_INVAILD" + FS_SIGNATURE_SDKKEY_INVAILD = "FS_SIGNATURE_SDKKEY_INVAILD" + FS_LICENSE_SERVER_ERROR = "FS_LICENSE_SERVER_ERROR" + FC_OPERA_LIMIT_BIND_OVER_ERROR = "FC_OPERA_LIMIT_BIND_OVER_ERROR" + FC_PRI_OPERA_LIMIT_BIND_OVER_ERROR = "FC_PRI_OPERA_LIMIT_BIND_OVER_ERROR" + FS_BUNDLE_ID_COUNT_OVER = "FS_BUNDLE_ID_COUNT_OVER" + FS_BUNDLE_ID_NOT_FOUND = "FS_BUNDLE_ID_NOT_FOUND" + FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR = "FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR" + FC_OPERA_LIMIT_APPID_OVER_ERROR = "FC_OPERA_LIMIT_APPID_OVER_ERROR" + FC_PRI_LIMIT_APPID_OVER_ERROR = "FC_PRI_LIMIT_APPID_OVER_ERROR" + FS_BINDINGID_NOT = "FS_BINDINGID_NOT" + FS_SDKKEY_NOT = "FS_SDKKEY_NOT" + FS_LICENSE_INVALID_ERR = "FS_LICENSE_INVALID_ERR" + FS_BIND_BUNDLE_LIMIT = "FS_BIND_BUNDLE_LIMIT" + FS_LINK_AUDIT_APPLY_EXIST = "FS_LINK_AUDIT_EXIST" + FS_EXPORT_APP_CLASS_ERR = "FS_EXPORT_APP_CLASS_ERR" + FS_ALIYUN_ADD_ERR = "FS_ALIYUN_ADD_ERR" + FS_DATA_HAS_DEL_ERR = "FS_DATA_HAS_DEL_ERR" + FS_MENU_ID_EXITS_ERR = "FS_MENU_ID_EXITS_ERR" + FS_SERVER_ERR = "FS_SERVER_ERR" + FS_IDENTITY_NOT_FOUND_ERR = "FS_IDENTITY_NOT_FOUND_ERR" + FS_QRCODE_HAS_EXPIRE = "FS_QRCODE_HAS_EXPIRE" + FS_ROLLBACK_FORBID = "FS_ROLLBACK_FORBID" + FS_PUBLISH_FORBID = "FS_PUBLISH_FORBID" + FS_MULTI_ROLLBACK_FORBID = "FS_MULTI_ROLLBACK_FORBID" + FS_NOT_TRIAL_INFO = "FS_NOT_TRIAL_INFO" + FS_REDIS_ERR = "FS_REDIS_ERR" + FS_MANAGE_APP_NO_AUTH = "FS_MANAGE_APP_NO_AUTH" + FS_APPID_ORGANID_ERR = "FS_APPID_ORGANID_ERR" + FS_APP_MARKET_LIMIT_ERROR = "FS_APP_MARKET_LIMIT_ERROR" + FS_APPLET_ID_IN_USE = "FS_APPLET_ID_IN_USE" + FS_APP_IS_FORBIDDEN = "FS_APP_IS_FORBIDDEN" + FS_BIND_IS_FORBIDDEN = "FS_BIND_IS_FORBIDDEN" + FS_PARAM_ERR = "FS_PARAM_ERR" + FS_BUNDLE_AVAILABLE_NUM_LIMIT = "FS_BUNDLE_AVAILABLE_NUM_LIMIT" + FS_BUNDLE_ALL_NUM_LIMIT = "FS_BUNDLE_ALL_NUM_LIMIT" + FS_OPER_BUNDLE_NUM_LIMIT = "FS_OPER_BUNDLE_NUM_LIMIT" + FS_OPER_CREATE_BUNDLE_ERR = "FS_OPER_CREATE_BUNDLE_ERR" + FS_OPER_HANDLE_ERR = "FS_OPER_HANDLE_ERR" + FS_QR_CODE_EXPIRED = "FS_QR_CODE_EXPIRED" + FS_OPER_REPEAT_BUNDLE_ERR = "FS_OPER_REPEAT_BUNDLE_ERR" + FS_OPER_AUTO_BIND_DOING_ERR = "FS_OPER_AUTO_BIND_DOING_ERR" + FS_NOT_REVIEW_BINDING_ERR = "FS_NOT_REVIEW_BINDING_ERR" + FC_LACK_OF_TO_BINDING_ID = "FC_LACK_OF_TO_BINDING_ID" + FC_BINDING_ID_EQUAL_TO_INDING_ID = "FC_BINDING_ID_EQUAL_TO_INDING_ID" + FC_MOVE_BINDING_NO_AUTH = "FC_MOVE_BINDING_NO_AUTH" + FC_LACK_OF_BUNDLE_ERR = "FC_LACK_OF_BUNDLE_ERR" + FC_APP_EXT_WX_ACCESS_TOKEN_ERR = "FC_APP_EXT_WX_ACCESS_TOKEN_ERR" +) + +var ErrorMap = map[string]string{ + OK: "", + FS_NOT_FOUND: "资源不存在", + FS_BAD_JSON: "参数格式错误,解析失败", + FS_DB_ERR: "数据库内部错误", + FS_SYSTEM_CALL: "系统内部错误", + FS_LACK_OF_APPID: "缺少appId", + FS_LACK_OF_SDKKEY: "缺少sdkKey", + FS_APP_ID_NOT_FOUND: "小程序不存在,请检查 AppID", + FS_GET_GROUP_FAILED: "企业状态校验异常", + FS_GET_DOMAIN_INFO_ERROR: "获取域名失败,相关服务不可用", + FS_GET_ACCOUNTINFO_ERROR: "获取账号信息失败", + FS_FORBIDDEN: "账号没有权限", + FS_PUBLISHING_OR_UNPUBLISHING: "正在申请上架或者申请下架", + FS_ACCESS_RULE_NOT_SET: "可见性范围未设置", + FS_INVALID_STATE: "应用当前状态不允许执行此操作", + FS_LACK_OF_ORGANIZAITON_ID: "缺少机构id", + FS_LACK_OF_USER_ID: "缺少用户id", + FS_SEQUENCE_LESS_THAN_CURRENT: "序列号不得低于当前已上架序列号", + FS_SPECIFIED_APP_ID_NOT_DELETEABLE: "指定appId的应用不可删除", + FS_APP_OWNED_BY_USER: "应用正在使用,不可删除", + FS_INVALID_APPROVAL_STATE: "审核后的状态值不合法", + FS_INVALID_BINDING_OPERATION: "应用操作不合法", + FS_LACK_OF_BINDING_ID: "缺少应用id", + FS_APP_ASSOCIATED: "小程序已关联", + FS_APP_NOT_ASSOCIATED: "小程序未关联", + FS_INVALID_COOPERATE_STATUS: "当前合作状态不允许执行此操作", + FS_APP_NOT_PUBLISHED: "小程序审核未通过或已下架", + FS_APP_BUNDLEID_REPEAT: "Bundle Id已存在", + FS_ORGAN_STATUS_INVALID: "小程序所属企业账号状态异常,请登录平台处理", + FS_COOPERATION_TERMINATED: "当前应用已经停止合作", + FS_APP_NOT_ASS_BIND: "小程序与本应用的关联关系没有生效,请检查关联关系", + FS_BIND_NOT_FOUND: "当前应用未在平台备案,请检查 SDK 初始化配置信息", + FS_SERVICE_UNAVAILABLE: "小程序已下架,相关服务暂不可用", + FS_APP_PAY_EXPIRE: "小程序已过有效期,相关服务暂不可用", + FS_BIND_PAY_EXPIRE: "当前应用已过期", + FS_BINDING_NAME_REPEAT: "应用名称已存在", + FS_APP_SEQUENCE_NOT_FOUND: "小程序版本错误", + FS_TIMESTAMP_TIMEOUT: "时间戳失效", + FS_UUID_INVAILD: "无效的uuid", + FS_SIGNATURE_INVAILD: "无效的signature", + FS_SIGNATURE_SDKKEY_INVAILD: "SDK Key 出错,请联系管理员处理", + FS_LICENSE_SERVER_ERROR: "license错误", + FC_OPERA_LIMIT_BIND_OVER_ERROR: "应用数量已达上限,如需新增应用,请联系平台运营方", + FC_PRI_OPERA_LIMIT_BIND_OVER_ERROR: "操作失败,当前环境应用个数已达license上限", + FC_OPERA_LIMIT_APPID_OVER_ERROR: "小程序数量已达上限,如需新增小程序,请联系平台运营方", + FC_PRI_LIMIT_APPID_OVER_ERROR: "操作失败,当前环境小程序个数已达license上限", + FS_BINDINGID_NOT: "应用id缺失", + FS_SDKKEY_NOT: "sdk key缺失", + FS_BUNDLE_ID_COUNT_OVER: "license权限不足", //bundle id达到上限 + FS_BUNDLE_ID_NOT_FOUND: "无法绑定非运营端添加的bundleId", //bundle id达到上限 + FS_BUNDLE_ID_COUNT_OVER_TO_WEB_ERR: "操作失败,当前环境Bundle ID已达到licesne上限", + FS_LICENSE_INVALID_ERR: "您当前的 license 异常,请联系管理员处理", + FS_BIND_BUNDLE_LIMIT: "bundle绑定达到限制", + FS_LINK_AUDIT_APPLY_EXIST: "小程序关联应用审核中", + FS_EXPORT_APP_CLASS_ERR: "导出小程序类型错误", + FS_ALIYUN_ADD_ERR: "阿里云添加失败", + FS_DATA_HAS_DEL_ERR: "数据已被删除,请刷新重试", + FS_MENU_ID_EXITS_ERR: "按钮ID或名称已存在", + FS_SERVER_ERR: "服务错误,请刷新重试", + FS_GET_MENUINFO_ERROR: "获取菜单列表失败", + FS_IDENTITY_NOT_FOUND_ERR: "该文件签名不存在", + FS_QRCODE_HAS_EXPIRE: "二维码过期,请刷新", + FS_ROLLBACK_FORBID: "该版本不可回退", + FS_PUBLISH_FORBID: "该版本不可发布", + FS_MULTI_ROLLBACK_FORBID: "不可连续回退", + FS_NOT_TRIAL_INFO: "该版本非体验版", + FS_REDIS_ERR: "redis异常", + FS_MANAGE_APP_NO_AUTH: "该用户无权限", + FS_APPID_ORGANID_ERR: "机构和小程序对不上", + FS_APP_IS_FORBIDDEN: "小程序被禁用,相关服务暂不可用", + FS_BIND_IS_FORBIDDEN: "BundleID 被禁用,相关服务暂不可用", + FS_PARAM_ERR: "参数错误", + FS_BUNDLE_AVAILABLE_NUM_LIMIT: "应用绑定正常状态的Bundle ID数量超过限制", + FS_BUNDLE_ALL_NUM_LIMIT: "应用绑定Bundle ID数量超过限制", + FS_OPER_BUNDLE_NUM_LIMIT: "正常状态的Bundle ID数量已达上限", + FS_OPER_CREATE_BUNDLE_ERR: "运营端创建合作应用必须含有非禁用的Bundle ID", + FS_OPER_HANDLE_ERR: "操作类型不支持", + FS_QR_CODE_EXPIRED: "二维码已失效", + FS_OPER_REPEAT_BUNDLE_ERR: "存在重复的bundleID", + FS_OPER_AUTO_BIND_DOING_ERR: "请等待上次自动关联小程序完成", + FS_NOT_REVIEW_BINDING_ERR: "不是审核应用", + FC_LACK_OF_TO_BINDING_ID: "缺少目标应用id", + FC_BINDING_ID_EQUAL_TO_INDING_ID: "源应用和目标应用id相同", + FC_MOVE_BINDING_NO_AUTH: "没有权限移动此Bundle ID", + FC_LACK_OF_BUNDLE_ERR: "缺少bundle信息", + FC_APP_EXT_WX_ACCESS_TOKEN_ERR: "获取ACCESS_TOKEN失败, 请检查appID和secret", +} + +func GetErrMsg(errcode string) string { + errmsg, ok := ErrorMap[errcode] + if !ok { + return "" + } + return errmsg +} + +type SvrRsp struct { + HttpStatus int + ErrCode string + ErrMsg string +} + +func DefaultSvrRsp() *SvrRsp { + return &SvrRsp{ + HttpStatus: http.StatusOK, + ErrCode: OK, + ErrMsg: GetErrMsg(OK), + } +} + +func NewSvrRsp() *SvrRsp { + return &SvrRsp{ + HttpStatus: http.StatusOK, + ErrCode: OK, + ErrMsg: "", + } +} + +func (s *SvrRsp) Set(status int, errCode, errMsg string) *SvrRsp { + s.HttpStatus = status + s.ErrCode = errCode + s.ErrMsg = errMsg + return s +} + +func (s *SvrRsp) SetLoc(status int, errCode string) *SvrRsp { + s.HttpStatus = status + s.ErrCode = errCode + s.ErrMsg = GetErrMsg(errCode) + return s +} + +func MakeLocRsp(c *gin.Context, status int, errcode string, data interface{}) { + c.JSON(status, gin.H{ + "errcode": errcode, + "error": GetErrMsg(errcode), + "data": data, + }) +} + +func MakeErrRsp(c *gin.Context, httpStatus int, errCode string, err string, data interface{}) { + c.JSON(httpStatus, gin.H{ + "error": err, + "errcode": errCode, + "data": data, + }) +} + +func (s *SvrRsp) MakeRsp(c *gin.Context, data interface{}) { + c.JSON(s.HttpStatus, gin.H{ + "errcode": s.ErrCode, + "error": s.ErrMsg, + "data": data, + }) +} + +func MakeGrpcCommonResult(httpStatus int, errCode string, result **pb.CommonResult) { + *result = &pb.CommonResult{} + (*result).Error = ErrorMap[errCode] + (*result).Errcode = errCode + (*result).Httpcode = int32(httpStatus) +} + +func MakeGrpcCommonResultNoLoc(httpStatus int, errCode, errmsg string, result **pb.CommonResult) { + *result = &pb.CommonResult{} + (*result).Error = errmsg + (*result).Errcode = errCode + (*result).Httpcode = int32(httpStatus) +} diff --git a/infrastructure/utility/tool.go b/infrastructure/utility/tool.go new file mode 100644 index 0000000..7143868 --- /dev/null +++ b/infrastructure/utility/tool.go @@ -0,0 +1,41 @@ +package utility + +import "github.com/gin-gonic/gin" + +const ( + ACCOUNT_ID_KEY = "X-Consumer-Custom-ID" + SDK_KEY_SIGNAL = "mop-sdk-key" + SDKKEY_VER_HEADER_KEY = "mop-sdk-version" +) + +const ( + MenuCreatedKey = "mop_app_manage_menu_has_created_key" + MenuCreatedValue = "ok" +) + +//工具函数 + +func GetUserId(c *gin.Context) string { + userId := c.GetHeader("x-mop-fcid") + if userId == "" { + userId = c.GetHeader("X-Consumer-Custom-ID") + } + return userId +} + +func GetSdkKey(c *gin.Context) string { + return c.GetHeader(SDK_KEY_SIGNAL) +} + +func GetSdkKeyVer(c *gin.Context) string { + return c.GetHeader(SDKKEY_VER_HEADER_KEY) +} + +func InArry(s string, arry []string) bool { + for _, v := range arry { + if v == s { + return true + } + } + return false +} diff --git a/infrastructure/utility/transfer.go b/infrastructure/utility/transfer.go new file mode 100644 index 0000000..26ee1e0 --- /dev/null +++ b/infrastructure/utility/transfer.go @@ -0,0 +1,43 @@ +package utility + +import ( + "encoding/json" + "regexp" + "strings" + "unicode" +) + +func InterfaceToJsonString(obj interface{}) string { + jsonBytes, err := json.Marshal(obj) + if err == nil { + return string(jsonBytes) + } + + return "" +} + +func IsMobile(mobile string) bool { + mobile = strings.Replace(mobile, " ", "", -1) + if ok := CheckPhoneIsOK(mobile); !ok { + return false + } + + result, _ := regexp.MatchString(`^(1[3|4|5|6|7|8|9][0-9]\d{4,8})$`, mobile) + return result +} + +func CheckPhoneIsOK(phone string) bool { + if len(phone) != 11 { + return false + } + + isOK := true + for _, r := range phone { + if !unicode.IsDigit(r) { + isOK = false + break + } + } + + return isOK +} diff --git a/infrastructure/utils/appSecret.go b/infrastructure/utils/appSecret.go new file mode 100644 index 0000000..0055924 --- /dev/null +++ b/infrastructure/utils/appSecret.go @@ -0,0 +1,19 @@ +package utils + +import ( + "crypto/sha1" + "finclip-app-manager/infrastructure/config" + "fmt" + "math/rand" + "time" +) + +//运行sha1加密生成appSecret +func GenAppSecret(sdk_key string) string { + rand.Seed(time.Now().Unix()) + s := sdk_key + time.Now().String() + fmt.Sprintf("%s", rand.Intn(100000)) + config.Cfg.AppSecretSalt + h := sha1.New() + h.Write([]byte(s)) + bs := h.Sum(nil) + return fmt.Sprintf("%x", bs)[16:32] +} diff --git a/infrastructure/utils/des.go b/infrastructure/utils/des.go new file mode 100644 index 0000000..a4e042c --- /dev/null +++ b/infrastructure/utils/des.go @@ -0,0 +1,71 @@ +package utils + +import ( + "bytes" + "crypto/des" + "encoding/hex" + "errors" + "fmt" +) + +const ( + DES_CRYPT_KEY = "w$D5%8x@" +) + +func DesEcbDecrypt(src string, key ...string) (result string, err error) { + if len(key) == 0 { + return DES_ECB{}.DecryptDES_ECB(src, DES_CRYPT_KEY) + } else { + return DES_ECB{}.DecryptDES_ECB(src, key[0]) + } +} + +type DES_ECB struct { +} + +//DecryptDES_ECB ECB解密 +func (d DES_ECB) DecryptDES_ECB(src, key string) (result string, err error) { + defer func() { + if defErr := recover(); defErr != nil { + fmt.Printf("DecryptDES_ECB_V2 panic info:%v\n", defErr) + result = "" + err = errors.New("DecryptDES_ECB_V2 err") + } + }() + data, err := hex.DecodeString(src) + if err != nil { + return "", err + } + keyByte := []byte(key) + block, err := des.NewCipher(keyByte) + if err != nil { + return "", err + } + bs := block.BlockSize() + if len(data)%bs != 0 { + return "", errors.New("crypto/cipher: input not full blocks") + } + out := make([]byte, len(data)) + dst := out + for len(data) > 0 { + block.Decrypt(dst, data[:bs]) + data = data[bs:] + dst = dst[bs:] + } + out = d.PKCS5UnPadding(out) + return string(out), nil +} + +//明文补码算法 +func (d DES_ECB) PKCS5Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +//明文减码算法 +func (d DES_ECB) PKCS5UnPadding(origData []byte) []byte { + length := len(origData) + unpadding := int(origData[length-1]) + return origData[:(length - unpadding)] +} diff --git a/infrastructure/utils/encrypt.go b/infrastructure/utils/encrypt.go new file mode 100644 index 0000000..393dec8 --- /dev/null +++ b/infrastructure/utils/encrypt.go @@ -0,0 +1,118 @@ +// +build linux + +package utils + +/* +#cgo CFLAGS: -I. + +#cgo LDFLAGS: -L./lib/linux -lsdkcore + +#include "sdkcore.h" +#include +*/ +import "C" + +import ( + "fmt" + "unsafe" + + "finclip-app-manager/infrastructure/config" +) + +const ( + BundleIDFinChatIOS = "com.finogeeks.finchat.oa" + BundleIDFinChatAndroid = "com.finogeeks.finochatapp" + BundleFTHelp = "com.finogeeks.mop.finosprite" + BundleIDFinElves = "com.finogeeks.finosprite" + BundleIDDemo = "com.finogeeks.finchat.finappletdemo" + BundleIDSample = "com.finogeeks.lib.applet.sample" + BundleIdVerifyAssistant = "com.finogeeks.mop.finoverify" + + SecretFinChatIOS = "919248e19a6c7fd3" + SecretFinChatAndroid = "154a4a31a57e75cb" + SecretFinElves = "703b9026be3d6bc5" + SecretDemo = "705b46f78820c7a8" + SecretSample = "42ac8b95d32b95e7" + SecretVerifyAssistant = "b2f3d5bd38b0bfa5" +) + +const ( + BUFF_LEN = 1024 * 4 +) + +var SDKKeyFinChatIOS string +var SDKKeyFinChatAndroid string +var SDKKeyFTHelp string +var SDKKeyFinElves string +var SDKKeyDemo string +var SDKKeySample string +var SDKKeyVerifyAssistant string +var SDKArry []string + +func init() { + ver := config.Cfg.SDKVersion + SDKKeyFinChatIOS = Encrypt(ver + "&" + BundleIDFinChatIOS) + SDKKeyFinChatAndroid = Encrypt(ver + "&" + BundleIDFinChatAndroid) + SDKKeyFTHelp = Encrypt(ver + "&" + BundleFTHelp) + SDKKeyFinElves = Encrypt(ver + "&" + BundleIDFinElves) + SDKKeyDemo = Encrypt(ver + "&" + BundleIDDemo) + SDKKeySample = Encrypt(ver + "&" + BundleIDSample) + SDKKeyVerifyAssistant = Encrypt(ver + "&" + BundleIdVerifyAssistant) + SDKArry = []string{SDKKeyFinChatIOS, SDKKeyFinChatAndroid, SDKKeyFTHelp, SDKKeyFinElves, SDKKeyDemo, SDKKeySample, SDKKeyVerifyAssistant} + fmt.Println("SDK Keys:", SDKKeyFinChatIOS, SDKKeyFTHelp, SDKKeyFinChatAndroid, SDKKeyFinElves, SDKKeyDemo, SDKKeySample, SDKKeyVerifyAssistant) + //fmt.Println("test secret:", GenAppSecret(SDKKeyFTHelp)) + fmt.Println("SDK Arry", SDKArry) +} + +// 国密算法加密 +func EncryptSM4(str string) string { + //cmd := C.CBytes([]byte(str)) + cmd := C.CString(str) + rlen := C.uint(BUFF_LEN) + s := make([]byte, BUFF_LEN) + C.encodeBySM4((*C.uchar)((unsafe.Pointer)(cmd)), C.uint(len(str)), (*C.uchar)(unsafe.Pointer(&s[0])), &rlen) + for i := 0; i < len(s); i++ { + if s[i] == 0 { + s = s[:i] + break + } + } + str2 := string(s[:]) + C.free((unsafe.Pointer)(cmd)) + return str2 +} + +// Encrypt 对称加密:调用cgo静态库 +func Encrypt(str string) string { + //cmd := C.CBytes([]byte(str)) + cmd := C.CString(str) + rlen := C.uint(BUFF_LEN) + s := make([]byte, BUFF_LEN) + C.encode((*C.uchar)((unsafe.Pointer)(cmd)), C.uint(len(str)), (*C.uchar)(unsafe.Pointer(&s[0])), &rlen) + for i := 0; i < len(s); i++ { + if s[i] == 0 { + s = s[:i] + break + } + } + str2 := string(s[:]) + C.free((unsafe.Pointer)(cmd)) + return str2 +} + +// Encrypt 对称加密:调用cgo静态库 +func EncodeAESContent(str string) string { + cmd := C.CString(str) + rlen := C.uint(BUFF_LEN) + s := make([]byte, BUFF_LEN) + C.encodeAESContent((*C.uchar)((unsafe.Pointer)(cmd)), C.uint(len(str)), (*C.uchar)(unsafe.Pointer(&s[0])), &rlen) + for i := 0; i < len(s); i++ { + if s[i] == 0 { + s = s[:i] + break + } + } + str2 := string(s[:]) + C.free((unsafe.Pointer)(cmd)) + return str2 +} diff --git a/infrastructure/utils/encrypt_drawin.go b/infrastructure/utils/encrypt_drawin.go new file mode 100644 index 0000000..7256fd2 --- /dev/null +++ b/infrastructure/utils/encrypt_drawin.go @@ -0,0 +1,53 @@ +// +build darwin + +package utils + +import "C" + +const ( + BundleIDFinChatIOS = "com.finogeeks.finchat.oa" + BundleIDFinChatAndroid = "com.finogeeks.finochatapp" + BundleFTHelp = "com.finogeeks.mop.finosprite" + BundleIDFinElves = "com.finogeeks.finosprite" + BundleIDDemo = "com.finogeeks.finchat.finappletdemo" + BundleIDSample = "com.finogeeks.lib.applet.sample" + BundleIdVerifyAssistant = "com.finogeeks.mop.finoverify" + + SecretFinChatIOS = "919248e19a6c7fd3" + SecretFinChatAndroid = "154a4a31a57e75cb" + SecretFinElves = "703b9026be3d6bc5" + SecretDemo = "705b46f78820c7a8" + SecretSample = "42ac8b95d32b95e7" + SecretVerifyAssistant = "b2f3d5bd38b0bfa5" +) + +const ( + BUFF_LEN = 1024 * 4 +) + +var SDKKeyFinChatIOS string +var SDKKeyFinChatAndroid string +var SDKKeyFTHelp string +var SDKKeyFinElves string +var SDKKeyDemo string +var SDKKeySample string +var SDKKeyVerifyAssistant string +var SDKArry []string + +func init() { +} + +// EncryptSM4 国密算法加密 +func EncryptSM4(str string) string { + return str +} + +// Encrypt 对称加密:调用cgo静态库 +func Encrypt(str string) string { + return str +} + +// EncodeAESContent 对称加密:调用cgo静态库 +func EncodeAESContent(str string) string { + return str +} diff --git a/infrastructure/utils/lib/drawwin/x64/libsdkcore.a b/infrastructure/utils/lib/drawwin/x64/libsdkcore.a new file mode 100644 index 0000000..365c0a9 Binary files /dev/null and b/infrastructure/utils/lib/drawwin/x64/libsdkcore.a differ diff --git a/infrastructure/utils/lib/linux/.gitkeep b/infrastructure/utils/lib/linux/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/infrastructure/utils/lib/linux/libsdkcore.a b/infrastructure/utils/lib/linux/libsdkcore.a new file mode 100644 index 0000000..f33e142 Binary files /dev/null and b/infrastructure/utils/lib/linux/libsdkcore.a differ diff --git a/infrastructure/utils/md5.go b/infrastructure/utils/md5.go new file mode 100644 index 0000000..9bb2ada --- /dev/null +++ b/infrastructure/utils/md5.go @@ -0,0 +1,15 @@ +package utils + +import ( + "crypto/md5" + "fmt" +) + +//生成md5串 + +func Md5Pro(str string) string { + data := []byte(str) + has := md5.Sum(data) + md5str := fmt.Sprintf("%x", has) + return md5str[0:24] +} diff --git a/infrastructure/utils/sdkcore.h b/infrastructure/utils/sdkcore.h new file mode 100644 index 0000000..c782419 --- /dev/null +++ b/infrastructure/utils/sdkcore.h @@ -0,0 +1,144 @@ +#if defined(_MSC_VER) && (_MSC_VER >= 1000) +#pragma once +#endif +#ifndef _INC_FINCHAT_SDKCORE_INCLUDED +#define _INC_FINCHAT_SDKCORE_INCLUDED +#define _ENCODE_ +#define _DECODE_ +// #define _ENCODE_LICENSE_ +#ifdef __cplusplus +extern "C" +{ +#endif +#ifdef _ENCODE_ + /** + * @brief 加密license + * + * @param plainText license缓冲区 + * @param textLen license长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void encode(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); + /** + * @brief 加密license + * + * @param plainText license缓冲区 + * @param textLen license长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void encodeBySM4(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); +#endif +#ifdef _DECODE_ + /** + * @brief 解密license + * + * @param base64Text license缓冲区 + * @param base64TextLen license长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void decode(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); + /** + * @brief 解密license + * + * @param base64Text license缓冲区 + * @param base64TextLen license长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void decodeBySM4(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); +#endif + + /** + * @brief 指定key解密 + * + * @param base64Text 加密串 + * @param base64TextLen 加密串长度 + * @param key 加密key(长度需为16) + * @param keyLen key长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void decodeByKey(const unsigned char *base64Text, unsigned int base64TextLen, const unsigned char *key, unsigned int keyLen, unsigned char *lpBuffer, unsigned int *lpSize); + /** + * @brief 指定key加密 + * + * @param plainText 待加密内容 + * @param plainTextLen 待加密长度 + * @param key 加密key(长度需为16) + * @param keyLen key长度 + * @param lpBuffer 加缓冲区(需先分配长度) + * @param lpSize 加密长度 + */ + void encodeByKey(const unsigned char *plainText, unsigned int plainTextLen, const unsigned char *key, unsigned int keyLen, unsigned char *lpBuffer, unsigned int *lpSize); + + + /** + * @brief 指定key解密 + * + * @param base64Text 加密串 + * @param base64TextLen 加密串长度 + * @param key 加密key(长度需为16) + * @param keyLen key长度 + * @param lpBuffer 解密缓冲区(需先分配长度) + * @param lpSize 解密长度 + */ + void decodeBySM4Key(const unsigned char *base64Text, unsigned int base64TextLen, const unsigned char *key, unsigned int keyLen, unsigned char *lpBuffer, unsigned int *lpSize); + /** + * @brief 指定key加密 + * + * @param plainText 待加密内容 + * @param plainTextLen 待加密长度 + * @param key 加密key(长度需为16) + * @param keyLen key长度 + * @param lpBuffer 加缓冲区(需先分配长度) + * @param lpSize 加密长度 + */ + void encodeBySM4Key(const unsigned char *plainText, unsigned int textLen, const unsigned char *key, unsigned int keyLen, unsigned char *lpBuffer, unsigned int *lpSize); + +#ifdef _ENCODE_LICENSE_ + void encodeLicense(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); + void encodeLicenseBySM4(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); +#endif + void decodeLicense(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); + void decodeLicenseBySM4(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); + + /** + * @brief 取私有sdkkey + * + * @param sdkkey sdkkey + * @param secret secret缓冲区(需先分配长度) + * @param secretLen 长度 + */ + void getSecretBySDKKey(const unsigned char *sdkkey,unsigned char *secret, unsigned int *secretLen); + + /** + * @brief 取私有sdkkey + * + * @param sdkkey sdkkey + * @param secret secret缓冲区(需先分配长度) + * @param secretLen 长度 + */ + void getSecretBySM3SDKKey(const unsigned char *sdkkey,unsigned char *secret, unsigned int *secretLen); + + /** + * @brief 消息摘要 + * + * @param sdkkey sdkkey + * @param secret secret缓冲区(需先分配长度) + * @param secretLen 长度 + */ + void messageDigest(const unsigned char *message,unsigned int iLen, unsigned char *lpBuffer,unsigned int *lpSize); + + + void encodeAESContent(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); + void encodeSMContent(const unsigned char *plainText, unsigned int textLen, unsigned char *lpBuffer, unsigned int *lpSize); + void decodeAESContent(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); + void decodeSMContent(const unsigned char *base64Text, unsigned int base64TextLen, unsigned char *lpBuffer, unsigned int *lpSize); + +#ifdef __cplusplus +} +#endif +#endif /* _INC_FINCHAT_SDKCORE_INCLUDED */ diff --git a/infrastructure/utils/util.go b/infrastructure/utils/util.go new file mode 100644 index 0000000..103379a --- /dev/null +++ b/infrastructure/utils/util.go @@ -0,0 +1,334 @@ +package utils + +import ( + "context" + "crypto/md5" + "encoding/json" + "errors" + "finclip-app-manager/domain/entity" + "finclip-app-manager/domain/entity/proto" + "fmt" + "github.com/gin-gonic/gin" + "gitlab.finogeeks.club/finclip-backend-v2/finclip-mgo/bson" + "strconv" + "strings" + "time" +) + +func GetNowMs() int64 { + return time.Now().UnixNano() / 1e6 +} + +func GetUserId(c *gin.Context) string { + return c.GetHeader(entity.ACCOUNT_ID_HEADER_KEY) +} + +func GenMd5(s string) string { + return fmt.Sprintf("%x", md5.Sum([]byte(s))) +} + +func Gen16Md5(s string) string { + return fmt.Sprintf("%x", md5.Sum([]byte(s)))[8:24] +} + +func GetCommonParam(c *gin.Context) (bson.M, []string, bson.M, int, int, error) { + query := c.DefaultQuery("query", "{}") + sort := c.Query("sort") + searchFields := c.Query("searchFields") + searchText := c.Query("searchText") + pageSize := c.DefaultQuery("pageSize", "10") + pageNo := c.DefaultQuery("pageNo", "0") + pageSizeInt, err := strconv.Atoi(pageSize) + if err != nil { + return nil, nil, nil, 0, 0, err + } + pageNoInt, err := strconv.Atoi(pageNo) + if err != nil { + return nil, nil, nil, 0, 0, err + } + sortFilter, err := ParseSortString(sort) + if err != nil { + return nil, nil, nil, 0, 0, err + } + queryFilter, err := ParseQueryString(query) + if err != nil { + return nil, nil, nil, 0, 0, err + } + if searchFields != "" && searchText != "" { + searchFilter, err := ParseSearchString(searchText, searchFields) + if err != nil { + return nil, nil, nil, 0, 0, err + } + return queryFilter, sortFilter, searchFilter, pageSizeInt, pageNoInt, nil + } + + return queryFilter, sortFilter, bson.M{}, pageSizeInt, pageNoInt, nil +} + +func ParseSearchString(searchText string, searchFields string) (bson.M, error) { + fieldsArray := strings.Split(searchFields, ",") + result := []bson.M{} + for _, v := range fieldsArray { + regex := bson.RegEx{ + Pattern: searchText, + Options: "i", + } + filter := bson.M{v: regex} + result = append(result, filter) + } + return bson.M{"$or": result}, nil +} + +func ParseSortString(sortStr string) ([]string, error) { + if sortStr == "" { + return []string{}, nil + } + sortMap := bson.M{} + err := json.Unmarshal([]byte(sortStr), &sortMap) + if err != nil { + return nil, err + } + result := []string{} + for k, v := range sortMap { + value, ok := v.(float64) + if !ok { + return nil, errors.New(fmt.Sprint("Invalid sort value type: ", v)) + } + if value == 1 { + result = append(result, k) + } else if value == -1 { + result = append(result, "-"+k) + } else { + return nil, errors.New(fmt.Sprint("Invalid sort value: ", v)) + } + } + return result, nil +} + +func ParseQueryString(queryStr string) (bson.M, error) { + result := bson.M{} + err := json.Unmarshal([]byte(queryStr), &result) + if err != nil { + return nil, err + } + return result, nil +} + +func InArry(s string, arry []string) bool { + for _, v := range arry { + if v == s { + return true + } + } + return false +} + +type MenuInfoFetcher interface { + GetMenuRspInfo(ctx context.Context) (*proto.MenuInfoRspData, error) +} + +//func ConvertModelCustomDataToPb( +// ctx context.Context, +// rs MenuInfoFetcher, +// groupId string, +// data entity.CustomDataInfo, +// domainInfo *httpcall.DomainResponseData, +// sdkVer string, +//) (error, string, *pb.CustomData) { +// var err error +// hCaller := httpcall.NewClient() +// if domainInfo == nil { +// domainInfo, err = hCaller.GetDomainInfoByOrganId(ctx, groupId) +// if err != nil { +// logger.GetLogger().Errorf("InternalGetAppVerInfo ger domain info err:%s", err.Error()) +// return err, utility.FS_GET_DOMAIN_INFO_ERROR, nil +// } +// } +// +// //menuRsp, err := GetMenuRspInfo(ctx) +// //if err != nil { +// // log.Errorf("GetDevInfo GetMenuRspInfo err:%+v", err) +// // return err, utility.FS_SERVER_ERR, nil +// //} +// +// apiData, err := hCaller.GetApiList(ctx, groupId) +// if err != nil { +// logger.GetLogger().Errorf("get api list err:%s", err.Error()) +// return err, utility.FS_SERVER_ERR, nil +// } +// res := new(pb.CustomData) +// res.ApiInfo = nil +// if apiData != nil { +// res.ApiInfo = make([]*pb.ApiInfoRspData, 0) +// for _, v := range apiData { +// res.ApiInfo = append(res.ApiInfo, &pb.ApiInfoRspData{Url: v.Url, ApiName: v.ApiName}) +// } +// } +// //if menuRsp != nil { +// // res.MenuInfo = new(pb.MenuInfoRspData) +// // res.MenuInfo.Total = int32(menuRsp.Total) +// // res.MenuInfo.List = make([]*pb.MenuInfoRspDataItem, 0) +// // for _, v := range menuRsp.List { +// // res.MenuInfo.List = append(res.MenuInfo.List, &pb.MenuInfoRspDataItem{Name: v.Name, Id: v.ID, Image: v.Image}) +// // } +// //} +// +// res.DetailDescription = data.DetailDescription +// res.VersionDescription = data.VersionDescription +// res.SourceFile = make([]*pb.SourceFileData, 0) +// for _, v := range data.SourceFile { +// item := &pb.SourceFileData{ +// FileMd5: v.FileMd5, +// Name: v.Name, +// UploadDate: v.UploadDate, +// Url: v.Url, +// SourceFileUrl: "", +// BasicPackVer: v.BasicPackVer, +// } +// if sdkVer != "" { +// isEncry := false +// if sdkVer == "cache" { +// isEncry = true +// } else { +// isEncry, err = GetSdkVerEncryResult(ctx, sdkVer) +// if err != nil { +// return err, utility.FS_SERVER_ERR, nil +// } +// } +// if isEncry && v.EncryptedUrl != "" && v.EncryptedFileMd5 != "" { +// item.Url = v.EncryptedUrl +// item.FileMd5 = v.EncryptedFileMd5 +// } +// } +// for _, val := range v.EncryptPackages { +// item.Packages = append(item.Packages, &pb.Package{ +// Root: val.Root, +// Name: val.Name, +// Pages: val.Pages, +// Independent: val.Independent, +// Filename: val.Filename, +// FileUrl: val.FileUrl, +// FileMd5: val.FileMd5, +// }) +// } +// res.SourceFile = append(res.SourceFile, item) +// } +// res.AppRuntimeDomain = GetPbRuntimeDomains(domainInfo) +// return nil, "", res +//} + +//func GetSdkVerEncryResult(ctx context.Context, sdkVer string) (bool, error) { +// var isEncry bool +// var err error +// /*isEncry, ok := cache.GetSdkVerResult(ctx, sdkVer) +// if ok { +// return isEncry, nil +// }*/ +// switch config.Cfg.ReqType { +// case "grpc": +// isEncry, err = grpc.GetSdkVerEncrypted(ctx, sdkVer) +// default: +// isEncry, err = httpcall.NewClient().GetSdkVerIsEncrypted(ctx, sdkVer) +// } +// if err != nil { +// return false, err +// } +// //cache.SetSdkVerResult(ctx, sdkVer, isEncry) +// return isEncry, nil +//} + +//func GetPbRuntimeDomains(domainInfo *httpcall.DomainResponseData) *pb.AppRuntimeDomain { +// result := &pb.AppRuntimeDomain{} +// result.Business = &pb.AppRuntimeDomain_Business{Domains: make([]string, 0)} +// if domainInfo.Business.Domains != nil { +// result.Business.Domains = domainInfo.Business.Domains +// } +// result.Service = &pb.AppRuntimeDomain_Service{ +// Download: make([]string, 0), +// Request: make([]string, 0), +// Socket: make([]string, 0), +// Upload: make([]string, 0), +// } +// if domainInfo.Service.Download != nil { +// result.Service.Download = domainInfo.Service.Download +// } +// if domainInfo.Service.Request != nil { +// result.Service.Request = domainInfo.Service.Request +// } +// if domainInfo.Service.Socket != nil { +// result.Service.Socket = domainInfo.Service.Socket +// } +// if domainInfo.Service.Download != nil { +// result.Service.Upload = domainInfo.Service.Upload +// } +// +// result.Whitelist = &pb.AppRuntimeDomain_Whitelist{Domains: make([]string, 0)} +// if domainInfo.Whitelist.Domains != nil { +// result.Whitelist.Domains = domainInfo.Whitelist.Domains +// } +// result.Blacklist = &pb.AppRuntimeDomain_Blacklist{Domains: make([]string, 0)} +// if domainInfo.Blacklist.Domains != nil { +// result.Blacklist.Domains = domainInfo.Blacklist.Domains +// } +// return result +//} + +//func GetMenuRspInfo(ctx context.Context) (*proto.MenuInfoRspData, error) { +// //非私有化环境置为nil +// if !config.Cfg.IsPrivateEnv() { +// return nil, nil +// } +// /*menuCreated, err := rs.menuCache.MenuHasCreated(ctx) +// if err != nil { +// return nil, err +// } +// if !menuCreated { +// return nil, nil +// }*/ +// result := new(proto.MenuInfoRspData) +// result.List = make([]proto.MenuInfoRspDataItem, 0) +// /*cacheRsp, err := rs.menuCache.Get(ctx) +// if err == nil { +// result.Total = cacheRsp.Total +// for _, m := range cacheRsp.List { +// item := proto.MenuInfoRspDataItem{} +// item.ID = m.ID +// item.Name = m.Name +// item.Image = m.Image +// result.List = append(result.List, item) +// } +// return result, nil +// }*/ +// +// menuCacheInfo := apiproto.GetAllMenuRsp{} +// +// repoRspList, total, err := impl.InitMenuInfoRepo().GetAllMenuList(ctx, []string{"sortNum"}) +// if err != nil { +// return nil, err +// } +// result.Total = total +// menuCacheInfo.Total = total +// for _, m := range repoRspList { +// item := proto.MenuInfoRspDataItem{} +// item.ID = m.InfoId +// item.Name = m.Name +// item.Image = m.ImageUrl +// result.List = append(result.List, item) +// +// cacheItem := apiproto.GetAllMenuRspItem{ +// TraceId: m.TraceId, +// Name: m.Name, +// ID: m.InfoId, +// Image: m.ImageUrl, +// SortNum: m.SortNum, +// CreateTime: m.CreateTime, +// UpdateTime: m.UpdateTime, +// UpdateOperator: m.UpdateOperator, +// } +// menuCacheInfo.List = append(menuCacheInfo.List, cacheItem) +// } +// +// //rs.menuCache.Set(ctx, menuCacheInfo) +// +// return result, nil +//} diff --git a/infrastructure/utils/uuid.go b/infrastructure/utils/uuid.go new file mode 100644 index 0000000..da3ef34 --- /dev/null +++ b/infrastructure/utils/uuid.go @@ -0,0 +1,142 @@ +package utils + +import ( + "crypto/rand" + "encoding/base64" + "errors" + "fmt" + "sync" + "time" +) + +const ( + objectIDLen int = 24 +) + +var Idg, _ = NewDefaultIdGenerator(0) + +func GetShortObjectID(objectID string) (string, error) { + length := len(objectID) + if len(objectID) != objectIDLen { + err := errors.New(fmt.Sprintf("Invalid ObjectId: length=%d", length)) + return "", err + } + shortID := objectID[0:8] + objectID[18:] + return shortID, nil +} + +func AppIDAndSequence(appID string, sequence int) string { + return fmt.Sprintf("%s_%d", appID, sequence) +} + +func BuildRandomURLEncString(length int) (string, error) { + b := make([]byte, length) + if _, err := rand.Read(b); err != nil { + return "", err + } + // url-safe no padding + return base64.RawURLEncoding.EncodeToString(b), nil +} + +const ( + BaseTs = 1530687318000 //2018/7/4 14:55:18 + SeqLen = 12 + WorkerLen = 10 + + WorkerMask = 1< MaxWorkId || start < 0 || end > MaxWorkId || end < 0 || start > end { + panic(errors.New("wrong para")) + } + + idg.idStart = int64(start) + idg.idEnd = int64(end) + idg.idCur = int64(start) + + idg.lastTs = -1 + idg.seq = 0 + return idg, nil +} + +func NewIdGenerator(start, end int64) (*UidGenerator, error) { + idg := new(UidGenerator) + if start > MaxWorkId || start < 0 || end > MaxWorkId || end < 0 || start > end { + panic(errors.New("wrong para")) + } + + idg.idStart = start + idg.idEnd = end + idg.idCur = start + + idg.lastTs = -1 + idg.seq = 0 + return idg, nil +} + +func (idg *UidGenerator) getMs() int64 { + return time.Now().UnixNano() / 1000000 +} + +func (idg *UidGenerator) Next() (id int64, err error) { + idg.lock.Lock() + defer idg.lock.Unlock() + + now := idg.getMs() + if now < idg.lastTs { //incase time schew + time.Sleep(time.Duration(idg.lastTs-now) * time.Millisecond) + now = idg.getMs() + } + + if now == idg.lastTs { + idg.seq = (idg.seq + 1) % SeqMask + if idg.seq == 0 { + if idg.idCur < idg.idEnd { + idg.idCur = idg.idCur + 1 + } else { + cur := idg.lastTs * 1000000 + for { + now = time.Now().UnixNano() //wait next slot + if now > cur { + now = now / 1000000 + break + } + } + idg.seq = 0 + idg.idCur = idg.idStart + } + } + } else { + idg.seq = 0 + idg.idCur = idg.idStart + } + + idg.lastTs = now + id = (now-BaseTs)<