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) } }