123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- package api
- import (
- "encoding/base64"
- "encoding/json"
- "eta/eta_mini_ht_api/common/component/cache"
- "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"
- "eta/eta_mini_ht_api/common/utils/redis"
- "fmt"
- "io"
- "sync"
- "time"
- )
- const (
- clientSuitInfoUrl = "/wt/front/api/open/api/getClientSuitInfo"
- accessTokenUrl = "/api/openapi/authless/token"
- )
- var (
- htFacadeOnce sync.Once
- htFacade *HTApi
- )
- type HTApi struct {
- htConfig *config.HTBizConfig
- // HTTP请求客户端
- client *client.HttpClient
- redisUtils *cache.RedisCache
- }
- func GetInstance() *HTApi {
- htFacadeOnce.Do(func() {
- htFacade = &HTApi{
- htConfig: config.GetConfig(contants.HT).(*config.HTBizConfig),
- client: client.DefaultClient(),
- redisUtils: cache.GetInstance()}
- })
- return htFacade
- }
- type ClientSuitInfoReq struct {
- ClientName string `json:"client_name"`
- IdKind int `json:"id_kind"`
- IdNo string `json:"id_no"`
- }
- type CustomerRiskReq struct {
- MobileTel string `json:"mobile_tel"`
- ClientName string `json:"client_name"`
- IdKind int `json:"id_kind"`
- IdNo string `json:"id_no"`
- CreateTime string `json:"create_time"`
- LoginType string `json:"login_type"`
- }
- func (f *HTApi) EnCodeData(req CustomerRiskReq) (token string, err error) {
- publicKey, err := auth.ParsePublicKey(f.htConfig.GetWebhookPublicKey())
- if err != nil {
- logger.Error("解析公钥失败:%v", err)
- err = exception.New(exception.SysError)
- return
- }
- str, err := json.Marshal(req)
- if err != nil {
- logger.Error("json序列化失败:%v", err)
- err = exception.New(exception.SysError)
- return
- }
- rsa, err := auth.EncryptWithRSA(publicKey, str)
- if err != nil {
- logger.Error("公钥加密失败:%v", err)
- err = exception.New(exception.SysError)
- return
- }
- token = base64.StdEncoding.EncodeToString(rsa)
- return
- }
- type EncodeReq struct {
- Param string `json:"param"`
- }
- func (f *HTApi) getToken() (token string, err error) {
- accessToken := redis.GenerateCAPAccessTokenKey()
- token = f.redisUtils.GetString(accessToken)
- var tokenInfo TokenInfo
- if token == "" {
- tokenInfo, err = f.GetAccessToken()
- if err != nil {
- logger.Error("获取token失败%v", err)
- return
- }
- var parseErr error
- expireTime, parseErr := time.Parse(time.DateTime, tokenInfo.ExpiresAt)
- if parseErr != nil {
- logger.Error("解析过期时间失败:%v", parseErr)
- err = parseErr
- return
- }
- duration := expireTime.Sub(time.Now()).Seconds()
- token = tokenInfo.AccessToken
- _ = f.redisUtils.SetString(accessToken, tokenInfo.AccessToken, int(duration)-5)
- }
- return
- }
- func (f *HTApi) GetCustomerRiskLevelInfo(req ClientSuitInfoReq) (info CustomerAccountInfo, err error) {
- url := f.htConfig.GetAccountApiUrl() + clientSuitInfoUrl
- token, err := f.getToken()
- if err != nil {
- return
- }
- publicKey, err := auth.ParsePublicKey(f.htConfig.GetWebhookPublicKey())
- if err != nil {
- logger.Error("解析公钥失败:%v", err)
- }
- reqStr, err := json.Marshal(req)
- encodeData, _ := auth.EncryptWithRSA(publicKey, reqStr)
- resp, err := f.client.PostWithAuth(url, EncodeReq{
- Param: base64.StdEncoding.EncodeToString(encodeData),
- }, token)
- 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 *HTApi) 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 CustomerRiskInfoResp struct {
- Error Error `json:"error"`
- 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) {
- customerRiskInfoResp := new(CustomerRiskInfoResp)
- err = json.Unmarshal(resp, &customerRiskInfoResp)
- if err != nil {
- logger.Error("customerRiskInfoResp解析失败: %v", err)
- return
- }
- if err != nil {
- logger.Warn("[cap 接口调用]解析客户风险信息接口应答失败:%v", err)
- err = exception.New(exception.GetCapTokenFailed)
- return
- }
- if customerRiskInfoResp.Error.ErrorNo != "0" {
- logger.Warn("[cap 接口调用] 获取客户风险信息失败:[code:%v, msg:%v, path:%v]", customerRiskInfoResp.Error.ErrorNo, customerRiskInfoResp.Error.ErrorInfo, customerRiskInfoResp.Error.ErrorPathInfo)
- err = exception.NewWithException(exception.GetCustomerRiskInfoFailed, customerRiskInfoResp.Error.ErrorInfo)
- return
- }
- privateKey, err := auth.ParsePrivateKey(htFacade.htConfig.GetWebhookPrivateKey())
- if err != nil {
- logger.Error("解析私钥失败: %v", err)
- return
- }
- decodeData, err := auth.DecryptWithRSA(privateKey, customerRiskInfoResp.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
- }
|