kobe6258 3 days ago
parent
commit
bdad3e3d03

+ 4 - 0
common/exception/exc_enums.go

@@ -21,6 +21,7 @@ const (
 	QueryRiskMappingError
 	IllegalConfigType
 	GetConfigValueFailed
+	TooManyRequest
 )
 
 // BIZErrCode  业务错误
@@ -146,6 +147,7 @@ const (
 	GetCapTokenFailed
 	GetCustomerRiskInfoFailed
 	GenerateRiskTestTokenFailed
+	SyncAccountStatusError
 )
 const (
 	OrderErrorCode int = iota + 90000
@@ -199,6 +201,7 @@ var ErrorMap = map[int]string{
 	GetAnalystListFailed:  "获取研究员列表失败",
 	IllegalConfigType:     "不合法的配置项值类型",
 	GetConfigValueFailed:  "配置获取失败",
+	TooManyRequest:        "请求太频繁了,请稍后重试",
 	//用户
 	TemplateUserNotFound:               "临时用户记录不存在",
 	LogoutFailed:                       "退出登录失败",
@@ -279,6 +282,7 @@ var ErrorMap = map[int]string{
 	IllegalProductType:    "非法的产品类型",
 	//webhook
 	SyncRiskError:               "同步风险等级失败",
+	SyncAccountStatusError:      "同步用户开户状态失败",
 	GetCapTokenFailed:           "获取cap token失败",
 	GenerateRiskTestTokenFailed: "生成风险测评token失败",
 	GetCustomerRiskInfoFailed:   "查询客户风险信息失败",

+ 1 - 1
common/utils/auth/rsa_utils.go

@@ -88,7 +88,7 @@ func ParsePublicKey(configPath string) (publicKey *rsa.PublicKey, err error) {
 
 // ParsePublicKeyFromPEM 解析RSA公钥
 func ParsePublicKeyFromPEM() (publicKey *rsa.PublicKey, err error) {
-	pemBlock, err := os.ReadFile("./conf/rsa_public_key.pem")
+	pemBlock, err := os.ReadFile("./conf/rsa_public_key_ht.pem")
 	block, _ := pem.Decode(pemBlock)
 	if block == nil {
 		logger.Error("公钥解析失败")

+ 3 - 1
common/utils/redis/key_generator.go

@@ -28,7 +28,9 @@ func GenerateCAPAccessTokenKey() string {
 func GenerateReportRefreshKey(source string, id int, modifyTime int64) string {
 	return fmt.Sprintf("%s:%d:%d", source, id, modifyTime)
 }
-
+func GenerateAccountStatusKey(idNo string) string {
+	return fmt.Sprintf("third:account:sync:%s", idNo)
+}
 func GeneratePaymentKey(orderNo string) string {
 	return fmt.Sprint(PaymentKeyPrefix, orderNo)
 }

+ 2 - 2
controllers/order/subscribe_controller.go

@@ -148,7 +148,7 @@ func (sc *SubscribeController) SubscribeProduct() {
 			return
 		}
 		switch officialUser.AccountStatus {
-		case "unopen":
+		case "unOpen":
 			result.Ret = AccountNotOpen
 			err = exception.New(exception.AccountNotOpen)
 			sc.FailedResult("用户未开通账户", result)
@@ -158,7 +158,7 @@ func (sc *SubscribeController) SubscribeProduct() {
 			err = exception.New(exception.AccountNotOpen)
 			sc.FailedResult("用户开户中", result)
 			return
-		case "opened":
+		case "open":
 		default:
 			err = exception.New(exception.IllegalAccountStatus)
 			sc.FailedResult(result.Msg, result)

+ 2 - 2
controllers/user/account_controller.go

@@ -105,7 +105,7 @@ func (a *AccountController) CheckUserStatus() {
 			return
 		}
 		switch officialUser.AccountStatus {
-		case "unopen":
+		case "unOpen":
 			result.Ret = AccountNotOpen
 			err = exception.New(exception.AccountNotOpen)
 			a.FailedResult("用户未开通账户", result)
@@ -115,7 +115,7 @@ func (a *AccountController) CheckUserStatus() {
 			err = exception.New(exception.AccountNotOpen)
 			a.FailedResult("用户开户中", result)
 			return
-		case "opened":
+		case "open":
 		default:
 			err = exception.New(exception.IllegalAccountStatus)
 			a.FailedResult(result.Msg, result)

+ 129 - 37
controllers/web_hook/htfutures_account_controller.go

@@ -1,14 +1,61 @@
 package web_hook
 
 import (
+	"eta/eta_mini_ht_api/common/component/cache"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	"eta/eta_mini_ht_api/common/exception"
 	"eta/eta_mini_ht_api/controllers"
 	userService "eta/eta_mini_ht_api/domian/user"
+	accountService "eta/eta_mini_ht_api/service/user"
 	"fmt"
+	"golang.org/x/time/rate"
+	"net/http"
+	"strings"
+	"sync"
 	"time"
 )
 
+var (
+	// 初始化限流器
+	accountRateLimiter = NewThirdRateLimiter(rate.Every(1*time.Second), 1)
+	rdServer           = cache.GetInstance()
+)
+
+type ThirdRateLimiter struct {
+	limiters       sync.Map      // 存储每个用户的限流器
+	defaultLimiter *rate.Limiter // 默认限流器
+}
+
+func NewThirdRateLimiter(limit rate.Limit, burst int) *ThirdRateLimiter {
+	return &ThirdRateLimiter{
+		defaultLimiter: rate.NewLimiter(limit, burst),
+	}
+}
+
+func (url *ThirdRateLimiter) Allow(idNo string) bool {
+	if limiter, ok := url.limiters.Load(idNo); ok {
+		return limiter.(*rate.Limiter).Allow()
+	}
+	// 创建新的限流器并存储
+	newLimiter := rate.NewLimiter(url.defaultLimiter.Limit(), url.defaultLimiter.Burst())
+	url.limiters.Store(idNo, newLimiter)
+	return newLimiter.Allow()
+}
+
+// ThirdRateLimitFilter 回调接口限流
+func ThirdRateLimitFilter(idNo string) (code int) {
+	if idNo == "" {
+		code = http.StatusBadRequest
+		return
+	}
+	if !accountRateLimiter.Allow(idNo) {
+		code = http.StatusTooManyRequests
+		return
+	}
+	code = http.StatusOK
+	return
+}
+
 type HTFuturesAccountController struct {
 	controllers.WebHookController
 }
@@ -188,65 +235,78 @@ func (h *HTFuturesAccountController) SyncCustomerRiskLevel() {
 // @router /v1/syncAccountInfo/ [post]
 func (h *HTFuturesAccountController) SyncCustomerAccountInfo() {
 	controllers.WrapWebhook(&h.WebHookController, func() (result *controllers.WrapData, err error) {
-		result = h.InitWrapData("同步风险等级")
-		syncCustomerRiskLevelReq := new(SyncCustomerRiskLevelReq)
+		result = h.InitWrapData("同步开户信息")
+		syncCustomerRiskLevelReq := new(AccountOpenInfoReq)
 		h.GetPostParams(syncCustomerRiskLevelReq)
-		custInfo := syncCustomerRiskLevelReq.CustInfo
-		riskInfo := syncCustomerRiskLevelReq.RiskInfo
+		if ThirdRateLimitFilter(syncCustomerRiskLevelReq.IdNo) != 200 {
+			err = exception.New(exception.TooManyRequest)
+			h.FailedResult("接口请求太频繁,请稍后重试", result)
+			return
+		}
 
-		if custInfo.ClientName == "" {
-			err = exception.New(exception.SyncRiskError)
+		//if syncCustomerRiskLevelReq.MobileTel != "" && syncCustomerRiskLevelReq.DealMobileTel != syncCustomerRiskLevelReq.MobileTel {
+		//	err = exception.New(exception.SyncRiskError)
+		//	h.FailedResult(fmt.Sprintf("柜台预留手机号码不一致,测评手机:%s,柜台预留手机:%s", syncCustomerRiskLevelReq.DealMobileTel, syncCustomerRiskLevelReq.MobileTel), result)
+		//	return
+		//}
+		if syncCustomerRiskLevelReq.ClientName == "" {
+			err = exception.New(exception.SyncAccountStatusError)
 			h.FailedResult("用户名字不能为空", result)
 			return
 		}
-		if custInfo.MobileTel == "" {
-			err = exception.New(exception.SyncRiskError)
+		if syncCustomerRiskLevelReq.MobileTel == "" {
+			err = exception.New(exception.SyncAccountStatusError)
 			h.FailedResult("手机号码不能为空", result)
 			return
 		}
-		if custInfo.IdNo == "" {
-			err = exception.New(exception.SyncRiskError)
-			h.FailedResult("身份证号不能为空", result)
+		if _, ok := idKindMap[syncCustomerRiskLevelReq.IdKind]; !ok {
+			err = exception.New(exception.SyncAccountStatusError)
+			validIdKind := make([]string, 0)
+			for _, v := range idKindMap {
+				validIdKind = append(validIdKind, string(v))
+			}
+			h.FailedResult(fmt.Sprintf("证件类型不合法,当前只支持[%s]", strings.Join(validIdKind, ",")), result)
 			return
 		}
-
-		//if !utils.IsValidIDCard(custInfo.IdNo) && !utils.IsValidOldIDCard(custInfo.IdNo) {
-		//	err = exception.New(exception.SyncRiskError)
-		//	h.FailedResult("身份证号不合法", result)
-		//	return
-		//}
-		if riskInfo.CorpRiskLevel == "" {
-			err = exception.New(exception.SyncRiskError)
-			h.FailedResult("风险等级不能为空", result)
+		if syncCustomerRiskLevelReq.IdNo == "" {
+			err = exception.New(exception.SyncAccountStatusError)
+			h.FailedResult("证号号码不能为空", result)
 			return
 		}
-		if riskInfo.CorpEndDate == "" {
-			err = exception.New(exception.SyncRiskError)
-			h.FailedResult("风险测评有效结束日期不能为空", result)
+		idBeginDate, parseErr := time.Parse(time.DateOnly, syncCustomerRiskLevelReq.IdBeginDate)
+		if parseErr != nil {
+			err = exception.New(exception.SyncAccountStatusError)
+			h.FailedResult("身份证有效开始时间不合法["+syncCustomerRiskLevelReq.IdBeginDate+"]", result)
 			return
 		}
-		if risk, ok := riskMappingMap[riskInfo.CorpRiskLevel]; ok {
-			riskInfo.CorpRiskLevel = risk
-		} else {
-			err = exception.New(exception.SyncRiskError)
-			h.FailedResult(fmt.Sprintf("风险等级不合法,应答结果:%s", riskInfo.CorpRiskLevel), result)
+		idEndDate, parseErr := time.Parse(time.DateOnly, syncCustomerRiskLevelReq.IdEndDate)
+		if parseErr != nil {
+			err = exception.New(exception.SyncAccountStatusError)
+			h.FailedResult("身份证有效结束时间不合法["+syncCustomerRiskLevelReq.IdEndDate+"]", result)
 			return
 		}
-		fmt.Println(riskInfo.CorpRiskLevel)
-		err = userService.UpdateRiskLevelInfo(userService.RiskLevelInfoDTO{
-			Name:             custInfo.ClientName,
-			PhoneNumber:      custInfo.MobileTel,
-			RiskLevel:        riskInfo.CorpRiskLevel,
-			RiskValidEndDate: riskInfo.CorpEndDate,
+		if idEndDate.Before(idBeginDate) {
+			err = exception.New(exception.SyncAccountStatusError)
+			h.FailedResult("身份证有效结束时间不合法,开始日期不能大于结束日期", result)
+			return
+		}
+		err = accountService.UpdateUserAccountOpenStatus(accountService.AccountStatusDTO{
+			MobileTel:     syncCustomerRiskLevelReq.MobileTel,
+			ClientName:    syncCustomerRiskLevelReq.ClientName,
+			IdKind:        syncCustomerRiskLevelReq.IdKind,
+			IdNo:          syncCustomerRiskLevelReq.IdNo,
+			IdBeginDate:   idBeginDate,
+			IdEndDate:     idEndDate,
+			AccountStatus: string(syncCustomerRiskLevelReq.AccountStatus),
+			ErrorMessage:  syncCustomerRiskLevelReq.ErrorMessage,
 		})
 		if err != nil {
 			logger.ErrorWithTraceId(h.Ctx, err.Error())
 			h.FailedResult(err.Error(), result)
-			err = exception.New(exception.SyncRiskError)
+			err = exception.New(exception.SyncAccountStatusError)
 			return
 		}
-		logger.InfoWithTraceId(h.Ctx, err.Error())
-		result = h.InitWrapData("同步风险等级成功")
+		result = h.InitWrapData("同步开户信息成功")
 		h.SuccessResult("success", syncCustomerRiskLevelReq, result)
 		return
 	})
@@ -276,3 +336,35 @@ type SyncCustomerAccountInfoReq struct {
 	CustInfo CustInfo `json:"custInfo"`
 	RiskInfo RiskInfo `json:"riskInfo"`
 }
+type AccountStatus string
+type IdKind string
+
+var (
+	accountStatusMap = map[string]AccountStatus{
+		"success": AccountStatusOpenSuccess,
+		"failed":  AccountStatusOpenFailed,
+	}
+	idKindMap = map[int]IdKind{
+		1: Id,
+	}
+)
+
+const (
+	AccountStatusOpenSuccess AccountStatus = "success"
+	AccountStatusOpenFailed  AccountStatus = "failed"
+	Id                       IdKind        = "身份证"
+)
+
+type AccountOpenInfoReq struct {
+	MobileTel string `json:"mobile_tel"`
+	//DealMobileTel string        `json:"deal_mobile_tel"`
+	ClientName    string        `json:"client_name"`
+	IdKind        int           `json:"id_kind"`
+	IdNo          string        `json:"id_no"`
+	AccountStatus AccountStatus `json:"account_status"`
+	//ErrorCode     int           `json:"error_code"`
+	IdBeginDate  string `json:"id_begin_date"`
+	IdEndDate    string `json:"id_end_date"`
+	ErrorMessage string `json:"error_message"`
+	Timestamp    int64  `json:"timestamp"`
+}

+ 1 - 1
domian/user/user_serivce.go

@@ -70,7 +70,7 @@ func convertOfficialUserDTO(user userDao.User) OfficialUserDTO {
 		TemplateUserID: user.TemplateUserID,
 		IDValid:        !user.IDEndDate.Before(today),
 		IdKind:         user.IDKind,
-		AccountStatus:  user.AccountStatus,
+		AccountStatus:  string(user.AccountStatus),
 	}
 }
 func GetUserByMobile(mobile string) (dto UserDTO, err error) {

BIN
eta_mini_ht_api


+ 27 - 0
main.go

@@ -1,6 +1,8 @@
 package main
 
 import (
+	"encoding/base64"
+	"encoding/json"
 	"eta/eta_mini_ht_api/api"
 	_ "eta/eta_mini_ht_api/common/component"
 	"eta/eta_mini_ht_api/common/component/cache"
@@ -8,13 +10,16 @@ import (
 	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/redis"
+	"eta/eta_mini_ht_api/controllers/web_hook"
 	"eta/eta_mini_ht_api/domian/report"
 	"eta/eta_mini_ht_api/models/eta"
 	"eta/eta_mini_ht_api/models/ht"
 	merchantDao "eta/eta_mini_ht_api/models/merchant"
 	_ "eta/eta_mini_ht_api/routers"
 	_ "eta/eta_mini_ht_api/task"
+	"fmt"
 	"github.com/beego/beego/v2/server/web"
 	"sync"
 	"time"
@@ -25,7 +30,28 @@ var (
 	htApi      = api.GetInstance()
 )
 
+func test() {
+	pk, _ := auth.ParsePublicKeyFromPEM()
+	data := web_hook.AccountOpenInfoReq{
+		MobileTel: "18267183251",
+		//DealMobileTel string        `json:"deal_mobile_tel"`
+		ClientName:    "陈晗",
+		IdKind:        1,
+		IdNo:          "330501199101080013",
+		AccountStatus: "success",
+		//ErrorCode     int           `json:"error_code"`
+		IdBeginDate:  "2021-03-10",
+		IdEndDate:    "2029-03-10",
+		ErrorMessage: "",
+		Timestamp:    time.Now().Unix(),
+	}
+	bytes, _ := json.Marshal(data)
+	entry, _ := auth.EncryptWithRSA(pk, bytes)
+	fmt.Println(base64.StdEncoding.EncodeToString(entry))
+}
+
 func main() {
+
 	htConfig := config.GetConfig(contants.HT).(*config.HTBizConfig)
 	if web.BConfig.RunMode == "dev" {
 		web.BConfig.WebConfig.DirectoryIndex = true
@@ -48,6 +74,7 @@ func main() {
 
 	}()
 	logger.Info("初始化成功")
+	test()
 	web.Run()
 }
 func initThirdPartyAccessToken() {

+ 0 - 1
middleware/webhook_middleware.go

@@ -44,7 +44,6 @@ func WebHookAuthMiddleware() web.FilterFunc {
 			_ = ctx.JSONResp(rep)
 			return
 		}
-		//fmt.Printf("解密后的请求: %v", string(decodeData))
 		ctx.Input.RequestBody = decodeData
 		return
 	}

+ 31 - 0
models/user/third_user_biz_flow.go

@@ -0,0 +1,31 @@
+package user
+
+import (
+	"eta/eta_mini_ht_api/models"
+	"time"
+)
+
+const (
+	BizTypeAccountOpen = "account_open"
+	BizTypeRiskSync    = "risk_sync"
+	BizTypeSuccess     = "success"
+	BizTypeFailed      = "failed"
+)
+
+type ThirdUserBizFlow struct {
+	ID             int       `gorm:"column:id;primary_key" json:"id"`
+	TemplateUserId int       `gorm:"column:template_user_id" json:"template_user_id,omitempty"`
+	UserId         int       `gorm:"column:user_id" json:"user_id,omitempty"`
+	BizType        string    `gorm:"column:biz_type" json:"biz_type"`         // enum('account_open','risk_sync')
+	BizStatus      string    `gorm:"column:biz_status" json:"biz_status"`     // enum('success','failed')
+	BizMessage     string    `gorm:"column:biz_message" json:"biz_message"`   // 业务消息
+	CreatedTime    time.Time `gorm:"column:created_time" json:"created_time"` // 创建时间
+}
+
+func (ThirdUserBizFlow) TableName() string {
+	return "third_user_biz_flows"
+}
+func InsertThirdBizFlow(flow *ThirdUserBizFlow) error {
+	db := models.Main()
+	return db.Model(&ThirdUserBizFlow{}).Create(&flow).Error
+}

+ 36 - 10
models/user/user.go

@@ -7,19 +7,20 @@ import (
 
 const (
 	defaultColumn = "id,real_name,id_no,id_end_date,account_status"
+	updateColumn  = "real_name,id_no,id_begin_date,id_end_date,id_kind,id_no,account_status,update_time"
 )
 
 type User struct {
-	ID             int       `gorm:"column:id;primaryKey"`
-	TemplateUserID int       `gorm:"column:template_user_id"`
-	RealName       string    `gorm:"column:real_name;size:255"`
-	IDNo           string    `gorm:"column:id_no;size:15"`
-	IDKind         int       `gorm:"column:id_kind"`
-	IDBeginDate    time.Time `gorm:"column:id_begin_date"`
-	IDEndDate      time.Time `gorm:"column:id_end_date"`
-	AccountStatus  string    `gorm:"column:account_status;type:enum('unopen','opening','opened')"`
-	CreatedTime    time.Time `gorm:"column:created_time"`
-	UpdatedTime    time.Time `gorm:"column:updated_time"`
+	ID             int           `gorm:"column:id;primaryKey"`
+	TemplateUserID int           `gorm:"column:template_user_id"`
+	RealName       string        `gorm:"column:real_name;size:255"`
+	IDNo           string        `gorm:"column:id_no;size:15"`
+	IDKind         int           `gorm:"column:id_kind"`
+	IDBeginDate    time.Time     `gorm:"column:id_begin_date"`
+	IDEndDate      time.Time     `gorm:"column:id_end_date"`
+	AccountStatus  AccountStatus `gorm:"column:account_status;type:enum('unOpen','opening','open')"`
+	CreatedTime    time.Time     `gorm:"column:created_time"`
+	UpdatedTime    time.Time     `gorm:"column:updated_time"`
 }
 
 func GetUserByTemplateUserId(templateUserId int) (user User, err error) {
@@ -27,3 +28,28 @@ func GetUserByTemplateUserId(templateUserId int) (user User, err error) {
 	err = db.Select(defaultColumn).Where("template_user_id=?", templateUserId).First(&user).Error
 	return
 }
+func GetThirdUserInfoByTemplateUserId(templateUserId int) (user User, err error) {
+	db := models.Main()
+	err = db.Select("*").Where("template_user_id=?", templateUserId).First(&user).Error
+	return
+}
+func OpenAccountSuccess(info User) (err error) {
+	db := models.Main()
+	tx := db.Begin()
+	if tx.Error != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+			return
+		}
+		tx.Commit()
+	}()
+	err = tx.Save(&info).Error
+	if err != nil {
+		return
+	}
+	err = tx.Exec("update template_users set account_status='open' where id=?", info.TemplateUserID).Error
+	return
+}

+ 86 - 1
service/user/user_service.go

@@ -13,6 +13,7 @@ import (
 	merchantDao "eta/eta_mini_ht_api/models/merchant"
 	userDao "eta/eta_mini_ht_api/models/user"
 	"eta/eta_mini_ht_api/service/config"
+	"fmt"
 	"gorm.io/gorm"
 	"sort"
 	"sync"
@@ -235,7 +236,7 @@ func GetUserProfile(userId int) (userProfile UserProfile, err error) {
 	}
 	userProfile = convertUserDTOToProfile(userDTO)
 	if errors.Is(err, gorm.ErrRecordNotFound) {
-		userProfile.AccountStatus = "unopen"
+		userProfile.AccountStatus = "unOpen"
 		err = nil
 		return
 	} else {
@@ -608,6 +609,16 @@ type BookMarkReport struct {
 	Score           float64         `json:"score"`
 	Show            bool            `json:"-"`
 }
+type AccountStatusDTO struct {
+	MobileTel     string
+	ClientName    string
+	IdKind        int
+	IdNo          string
+	IdBeginDate   time.Time
+	IdEndDate     time.Time
+	AccountStatus string
+	ErrorMessage  string
+}
 
 func (bk BookMarkReport) GetID() int {
 	return bk.ReportID
@@ -625,3 +636,77 @@ func (bk BookMarkChart) GetSourceType() string {
 // func SearchBookMark(key string, sourceType string, ids []int, pageInfo page.PageInfo, userId int) (list []BookMarkInterface, err error) {
 //
 // }
+
+func UpdateUserAccountOpenStatus(dto AccountStatusDTO) (err error) {
+	//通过手机号获取临时用户
+	templateUser, err := userDao.GetUserByMobile(dto.MobileTel)
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			logger.Error("获取用户信息失败,手机号码不存在:" + dto.MobileTel)
+			err = fmt.Errorf("获取用户信息失败,手机号码不存在:%s", dto.MobileTel)
+		} else {
+			logger.Error("获取用户信息失败:" + err.Error())
+			err = fmt.Errorf("获取用户信息失败,手机号码:%s", dto.MobileTel)
+		}
+		return
+	}
+	//根据临时用户id获取正式用户信息
+	userInfo, err := userDao.GetThirdUserInfoByTemplateUserId(templateUser.Id)
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			logger.Error("开户记录不存在,手机号码:" + dto.MobileTel)
+			err = fmt.Errorf("开户记录不存在,手机号码:%s", dto.MobileTel)
+		} else {
+			logger.Error("获取开户记录失败:" + err.Error())
+			err = fmt.Errorf("获取开户记录失败,手机号码:%s", dto.MobileTel)
+		}
+		return
+	}
+	if userInfo.AccountStatus == userDao.Open {
+		logger.Error("用户已开户,手机号码:" + dto.MobileTel)
+		err = fmt.Errorf("用户已开户,手机号码:%s", dto.MobileTel)
+		return
+	}
+	if userInfo.AccountStatus == userDao.UnOpen {
+		logger.Error("用户开户状态异常:[未发起开户流程],手机号码:" + dto.MobileTel)
+		err = fmt.Errorf("用户开户状态异常:[未发起开户流程],手机号码:%s", dto.MobileTel)
+		return
+	}
+	var thirdBizFlow *userDao.ThirdUserBizFlow
+	if dto.AccountStatus == "success" {
+		userInfo.AccountStatus = userDao.Open
+		userInfo.RealName = dto.ClientName
+		userInfo.IDKind = dto.IdKind
+		userInfo.IDNo = dto.IdNo
+		userInfo.IDBeginDate = dto.IdBeginDate
+		userInfo.IDEndDate = dto.IdEndDate
+		err = userDao.OpenAccountSuccess(userInfo)
+		if err != nil {
+			logger.Error(fmt.Sprintf("更新用户信息失败:%v", userInfo) + err.Error())
+			err = fmt.Errorf("更新用户信息失败,手机号码:%v", dto.MobileTel)
+			return
+		}
+		thirdBizFlow = &userDao.ThirdUserBizFlow{
+			TemplateUserId: templateUser.Id,
+			UserId:         userInfo.ID,
+			BizType:        userDao.BizTypeAccountOpen,
+			BizStatus:      userDao.BizTypeSuccess,
+			BizMessage:     dto.ErrorMessage,
+			CreatedTime:    time.Now(),
+		}
+	} else {
+		thirdBizFlow = &userDao.ThirdUserBizFlow{
+			TemplateUserId: templateUser.Id,
+			UserId:         userInfo.ID,
+			BizType:        userDao.BizTypeAccountOpen,
+			BizStatus:      userDao.BizTypeFailed,
+			BizMessage:     dto.ErrorMessage,
+			CreatedTime:    time.Now(),
+		}
+	}
+	flowErr := userDao.InsertThirdBizFlow(thirdBizFlow)
+	if flowErr != nil {
+		logger.Error(fmt.Sprintf("插入第三方回调信息记录失败:%v", thirdBizFlow) + flowErr.Error())
+	}
+	return
+}

+ 56 - 0
test/rsa_utils_test.go

@@ -0,0 +1,56 @@
+package test
+
+import (
+	"encoding/json"
+	"eta/eta_mini_ht_api/common/utils/auth"
+	"eta/eta_mini_ht_api/controllers/web_hook"
+	"testing"
+	"time"
+)
+
+func TestEncryptWithRSA(t *testing.T) {
+	type args struct {
+		data interface{}
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "test",
+			args: args{
+				data: web_hook.AccountOpenInfoReq{
+					MobileTel: "18267183251",
+					//DealMobileTel string        `json:"deal_mobile_tel"`
+					ClientName:    "陈晗",
+					IdKind:        1,
+					IdNo:          "330501199101080013",
+					AccountStatus: "failed",
+					//ErrorCode     int           `json:"error_code"`
+					IdBeginDate:  "2021-03-10",
+					IdEndDate:    "2029-03-10",
+					ErrorMessage: "不合法的开户请求",
+					Timestamp:    time.Now().Unix(),
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pk, _ := auth.ParsePublicKeyFromPEM()
+			bytes, _ := json.Marshal(tt.args.data)
+			entry, _ := auth.EncryptWithRSA(pk, bytes)
+			//fmt.Println(string(entry))
+			got, _ := auth.EncryptWithRSA(pk, entry)
+			t.Errorf("EncryptWithRSA() got = %v, ", got)
+			//if (err != nil) != tt.wantErr {
+			//	t.Errorf("EncryptWithRSA() error = %v, wantErr %v", err, tt.wantErr)
+			//	return
+			//}
+			//if !reflect.DeepEqual(got, tt.want) {
+			//	t.Errorf("EncryptWithRSA() got = %v, want %v", got, tt.want)
+			//}
+			//fmt.Println(got)
+		})
+	}
+}