|
@@ -0,0 +1,185 @@
|
|
|
+package api
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "eta/eta_mini_ht_api/common/component/config"
|
|
|
+ logger "eta/eta_mini_ht_api/common/component/log"
|
|
|
+ "eta/eta_mini_ht_api/common/contants"
|
|
|
+ "eta/eta_mini_ht_api/common/exception"
|
|
|
+ "eta/eta_mini_ht_api/common/utils/auth"
|
|
|
+ "eta/eta_mini_ht_api/common/utils/client"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "sync"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ clientSuitInfoUrl = "/open/api/getClientSuitInfo"
|
|
|
+ accessTokenUrl = "/api/openapi/authless/token"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ htFacadeOnce sync.Once
|
|
|
+
|
|
|
+ htFacade *HTAccountApi
|
|
|
+)
|
|
|
+
|
|
|
+type HTAccountApi struct {
|
|
|
+ htConfig *config.HTBizConfig
|
|
|
+ // HTTP请求客户端
|
|
|
+ client *client.HttpClient
|
|
|
+}
|
|
|
+
|
|
|
+func GetInstance() *HTAccountApi {
|
|
|
+ htFacadeOnce.Do(func() {
|
|
|
+ htFacade = &HTAccountApi{
|
|
|
+ htConfig: config.GetConfig(contants.HT).(*config.HTBizConfig),
|
|
|
+ client: client.DefaultClient()}
|
|
|
+ })
|
|
|
+ return htFacade
|
|
|
+}
|
|
|
+
|
|
|
+type ClientSuitInfoReq struct {
|
|
|
+ ClientName string `json:"client_name"`
|
|
|
+ IdKind int `json:"id_kind"`
|
|
|
+ IdNo string `json:"id_no"`
|
|
|
+}
|
|
|
+
|
|
|
+func (f *HTAccountApi) GetCustomerRiskLevelInfo(req ClientSuitInfoReq) (info CustomerAccountInfo, err error) {
|
|
|
+ url := f.htConfig.GetAccountApiUrl() + clientSuitInfoUrl
|
|
|
+ resp, err := f.client.Post(url, nil)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("调用CAP customerRiskInfo接口失败:[%v]", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer func(Body io.ReadCloser) {
|
|
|
+ closeErr := Body.Close()
|
|
|
+ if closeErr != nil {
|
|
|
+ logger.Error("关闭Response失败:%v", closeErr)
|
|
|
+ }
|
|
|
+ }(resp.Body)
|
|
|
+ body, _ := io.ReadAll(resp.Body)
|
|
|
+ return decodeResponse(body)
|
|
|
+}
|
|
|
+
|
|
|
+type AccessTokenReq struct {
|
|
|
+ AppId string `json:"app_id"`
|
|
|
+ SecretKey string `json:"secret_key"`
|
|
|
+}
|
|
|
+
|
|
|
+func (f *HTAccountApi) GetAccessToken() (token TokenInfo, err error) {
|
|
|
+ url := f.htConfig.GetAccountApiUrl() + accessTokenUrl
|
|
|
+ req := AccessTokenReq{
|
|
|
+ AppId: f.htConfig.GetAppId(),
|
|
|
+ SecretKey: f.htConfig.GetSecretKey(),
|
|
|
+ }
|
|
|
+ resp, err := f.client.Post(url, req)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("调用CAP accessToken接口失败:[%v]", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer func(Body io.ReadCloser) {
|
|
|
+ closeErr := Body.Close()
|
|
|
+ if closeErr != nil {
|
|
|
+ logger.Error("关闭Response失败:%v", closeErr)
|
|
|
+ }
|
|
|
+ }(resp.Body)
|
|
|
+ body, _ := io.ReadAll(resp.Body)
|
|
|
+
|
|
|
+ var tokenResp AccessTokenResp
|
|
|
+ err = json.Unmarshal(body, &tokenResp)
|
|
|
+ if err != nil {
|
|
|
+ logger.Warn("[cap 接口调用]解析cap token接口应答失败:%v", err)
|
|
|
+ err = exception.New(exception.GetCapTokenFailed)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if tokenResp.Error.ErrorNo != "0" {
|
|
|
+ logger.Warn("[cap 接口调用] 获取token失败:[code:%v, msg:%v, path:%v]", tokenResp.Error.ErrorNo, tokenResp.Error.ErrorInfo, tokenResp.Error.ErrorPathInfo)
|
|
|
+ err = exception.NewWithException(exception.GetCapTokenFailed, tokenResp.Error.ErrorInfo)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ token = TokenInfo{
|
|
|
+ AccessToken: tokenResp.Data.AccessToken,
|
|
|
+ ExpiresAt: tokenResp.Data.ExpiresAt,
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+type AccessTokenResp struct {
|
|
|
+ Error Error `json:"error"`
|
|
|
+ Data AccessTokenData `json:"data"`
|
|
|
+}
|
|
|
+
|
|
|
+type Error struct {
|
|
|
+ ErrorNo string `json:"error_no"`
|
|
|
+ ErrorInfo string `json:"error_info"`
|
|
|
+ ErrorPathInfo string `json:"error_path_info"`
|
|
|
+}
|
|
|
+
|
|
|
+type AccessTokenData struct {
|
|
|
+ AccessToken string `json:"accessToken"`
|
|
|
+ ExpiresAt string `json:"expiresAt"`
|
|
|
+}
|
|
|
+
|
|
|
+type TokenInfo struct {
|
|
|
+ AccessToken string
|
|
|
+ ExpiresAt string
|
|
|
+}
|
|
|
+
|
|
|
+type WebhookRequest struct {
|
|
|
+ Data string `json:"data"`
|
|
|
+}
|
|
|
+
|
|
|
+type SyncCustomerRiskLevelReq struct {
|
|
|
+ CustInfo CustInfo `json:"custInfo"`
|
|
|
+ RiskInfo RiskInfo `json:"riskInfo"`
|
|
|
+}
|
|
|
+
|
|
|
+type CustInfo struct {
|
|
|
+ MobileTel string `json:"mobile_tel"`
|
|
|
+ ClientName string `json:"client_name"`
|
|
|
+ IdKind string `json:"id_kind"`
|
|
|
+ IdNo string `json:"id_no"`
|
|
|
+ IdBeginDate string `json:"id_begindate"`
|
|
|
+ IdEndDate string `json:"id_enddate"`
|
|
|
+}
|
|
|
+
|
|
|
+type RiskInfo struct {
|
|
|
+ CorpBeginDate string `json:"corp_begin_date"`
|
|
|
+ CorpEndDate string `json:"corp_end_date"`
|
|
|
+ UserInvestTerm string `json:"user_invest_term"`
|
|
|
+ UserInvestKind string `json:"user_invest_kind"`
|
|
|
+ CorpRiskLevel string `json:"corp_risk_level"`
|
|
|
+}
|
|
|
+type CustomerAccountInfo struct {
|
|
|
+ CustInfo CustInfo `json:"custInfo"`
|
|
|
+ RiskInfo RiskInfo `json:"riskInfo"`
|
|
|
+}
|
|
|
+
|
|
|
+func decodeResponse(resp []byte) (info CustomerAccountInfo, err error) {
|
|
|
+ webhookRequest := new(WebhookRequest)
|
|
|
+ err = json.Unmarshal(resp, &webhookRequest)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("WebhookRequest解析失败: %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ privateKey, err := auth.ParsePrivateKey(htFacade.htConfig.GetWebhookPrivateKey())
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("解析私钥失败: %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ logger.Info("解码请求: %v", webhookRequest.Data)
|
|
|
+ decodeData, err := auth.DecryptWithRSA(privateKey, webhookRequest.Data)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("解密请求体失败: %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ fmt.Printf("解密后的请求: %v", string(decodeData))
|
|
|
+ err = json.Unmarshal(decodeData, &info)
|
|
|
+ if err != nil {
|
|
|
+ logger.Error("customerInfo解析失败: %v", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|