123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- 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
- }
- // // SyncCustomerRiskLevel 风险测评同步接口
- // // @Summary 风险测评同步接口
- // // @Description 风险测评同步接口
- // // @Success 200 {object} controllers.BaseResponse
- // // @router /riskLevel [post]
- //
- // func (h *UserController) SyncCustomerRiskLevel() {
- // controllers.Wrap(&h.BaseController, func() (result *controllers.WrapData, err error) {
- // result = h.InitWrapData("同步风险等级")
- // htConfig := config.GetConfig(contants.HT).(*config.HTBizConfig)
- // webhookRequest := new(WebhookRequest)
- // h.GetPostParams(webhookRequest)
- // privateKey, err := authUtils.ParsePrivateKey(htConfig.GetWebhookPrivateKey())
- // if err != nil {
- // err = exception.NewWithException(exception.SysError, err.Error())
- // logger.Error("解析私钥失败: %v", err)
- // h.FailedResult("解析私钥失败", result)
- // return
- // }
- // decodeData, err := authUtils.DecryptWithRSA(privateKey, webhookRequest.Data)
- // if err != nil {
- // err = exception.NewWithException(exception.SysError, err.Error())
- // logger.Error("解密请求体失败: %v", err)
- // h.FailedResult("解密请求体失败", result)
- // return
- // }
- // syncCustomerRiskLevelReq := new(SyncCustomerRiskLevelReq)
- // err = json.Unmarshal(decodeData, syncCustomerRiskLevelReq)
- // if err != nil {
- // err = exception.NewWithException(exception.SyncRiskError, err.Error())
- // logger.Error("解析请求体失败: %v", err)
- // h.FailedResult("解析请求体失败", result)
- // return
- // }
- // custInfo := syncCustomerRiskLevelReq.CustInfo
- // riskInfo := syncCustomerRiskLevelReq.RiskInfo
- // if custInfo.ClientName == "" {
- // err = exception.New(exception.SyncRiskError)
- // h.FailedResult("用户名字不能为空", result)
- // return
- // }
- // if custInfo.MobileTel == "" {
- // err = exception.New(exception.SyncRiskError)
- // h.FailedResult("手机号码不能为空", result)
- // return
- // }
- // if custInfo.IdNo == "" {
- // err = exception.New(exception.SyncRiskError)
- // h.FailedResult("身份证号不能为空", 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)
- // return
- // }
- // if riskInfo.CorpEndDate == "" {
- // err = exception.New(exception.SyncRiskError)
- // h.FailedResult("风险测评有效结束日期不能为空", result)
- // return
- // }
- // err = userService.UpdateRiskLevelInfo(userService.RiskLevelInfoDTO{
- // Name: custInfo.ClientName,
- // PhoneNumber: custInfo.MobileTel,
- // RiskLevel: riskInfo.CorpRiskLevel,
- // RiskValidEndDate: riskInfo.CorpEndDate,
- // })
- // if err != nil {
- // logger.ErrorWithTraceId(h.Ctx, err.Error())
- // h.FailedResult(err.Error(), result)
- // err = exception.New(exception.SyncRiskError)
- // return
- // }
- // logger.InfoWithTraceId(h.Ctx, err.Error())
- // result = h.InitWrapData("同步风险等级成功")
- // h.SuccessResult("success", syncCustomerRiskLevelReq, result)
- // return
- // })
- // }
- var (
- riskMappingMap = map[string]string{
- "0": "C1",
- "1": "C1",
- "2": "C2",
- "3": "C3",
- "4": "C4",
- "5": "C5",
- }
- )
- // SyncCustomerRiskLevel 风险测评同步接口
- // @Summary 风险测评同步接口
- // @Description 风险测评同步接口
- // @Success 200 {object} controllers.BaseResponse
- // @router /v1/syncRiskLevel/ [post]
- func (h *HTFuturesAccountController) SyncCustomerRiskLevel() {
- controllers.WrapWebhook(&h.WebHookController, func() (result *controllers.WrapData, err error) {
- result = h.InitWrapData("同步风险等级")
- syncCustomerRiskLevelReq := new(SyncCustomerRiskLevelReq)
- h.GetPostParams(syncCustomerRiskLevelReq)
- custInfo := syncCustomerRiskLevelReq.CustInfo
- riskInfo := syncCustomerRiskLevelReq.RiskInfo
- if custInfo.ClientName == "" {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("用户名字不能为空", result)
- return
- }
- if custInfo.DealMobileTel == "" {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("手机号码不能为空", result)
- return
- }
- if custInfo.IdNo == "" {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("身份证号不能为空", result)
- return
- }
- if custInfo.MobileTel != "" && custInfo.DealMobileTel != custInfo.MobileTel {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult(fmt.Sprintf("柜台预留手机号码不一致,测评手机:%s,柜台预留手机:%s", custInfo.DealMobileTel, custInfo.MobileTel), result)
- return
- }
- if riskInfo.CorpRiskLevel == "" {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("风险等级不能为空", result)
- return
- }
- if riskInfo.CorpEndDate == "" {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("风险测评有效结束日期不能为空", result)
- return
- }
- riskEndDate, parseErr := time.Parse("20060102", riskInfo.CorpEndDate)
- if parseErr != nil {
- err = exception.New(exception.SyncRiskError)
- h.FailedResult("风险测评有效结束日期不合法["+riskInfo.CorpEndDate+"]", 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)
- return
- }
- err = userService.UpdateRiskLevelInfo(userService.RiskLevelInfoDTO{
- Name: custInfo.ClientName,
- PhoneNumber: custInfo.DealMobileTel,
- RiskLevel: riskInfo.CorpRiskLevel,
- RiskValidEndDate: riskEndDate.Format(time.DateOnly),
- })
- if err != nil {
- logger.ErrorWithTraceId(h.Ctx, err.Error())
- h.FailedResult(err.Error(), result)
- err = exception.New(exception.SyncRiskError)
- return
- }
- result = h.InitWrapData("同步风险等级成功")
- h.SuccessResult("success", syncCustomerRiskLevelReq, result)
- return
- })
- }
- // SyncCustomerAccountInfo 开户信息同步接口
- // @Summary 开户信息同步接口
- // @Description 开户信息同步接口
- // @Success 200 {object} controllers.BaseResponse
- // @router /v1/syncAccountInfo/ [post]
- func (h *HTFuturesAccountController) SyncCustomerAccountInfo() {
- controllers.WrapWebhook(&h.WebHookController, func() (result *controllers.WrapData, err error) {
- result = h.InitWrapData("同步开户信息")
- syncCustomerRiskLevelReq := new(AccountOpenInfoReq)
- h.GetPostParams(syncCustomerRiskLevelReq)
- if ThirdRateLimitFilter(syncCustomerRiskLevelReq.IdNo) != 200 {
- err = exception.New(exception.TooManyRequest)
- h.FailedResult("接口请求太频繁,请稍后重试", result)
- return
- }
- //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 syncCustomerRiskLevelReq.MobileTel == "" {
- err = exception.New(exception.SyncAccountStatusError)
- h.FailedResult("手机号码不能为空", result)
- return
- }
- 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 syncCustomerRiskLevelReq.IdNo == "" {
- err = exception.New(exception.SyncAccountStatusError)
- h.FailedResult("证号号码不能为空", result)
- return
- }
- idBeginDate, parseErr := time.Parse(time.DateOnly, syncCustomerRiskLevelReq.IdBeginDate)
- if parseErr != nil {
- err = exception.New(exception.SyncAccountStatusError)
- h.FailedResult("身份证有效开始时间不合法["+syncCustomerRiskLevelReq.IdBeginDate+"]", result)
- return
- }
- idEndDate, parseErr := time.Parse(time.DateOnly, syncCustomerRiskLevelReq.IdEndDate)
- if parseErr != nil {
- err = exception.New(exception.SyncAccountStatusError)
- h.FailedResult("身份证有效结束时间不合法["+syncCustomerRiskLevelReq.IdEndDate+"]", result)
- return
- }
- 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.SyncAccountStatusError)
- return
- }
- result = h.InitWrapData("同步开户信息成功")
- h.SuccessResult("success", syncCustomerRiskLevelReq, result)
- return
- })
- }
- type SyncCustomerRiskLevelReq struct {
- CustInfo CustInfo `json:"custInfo"`
- RiskInfo RiskInfo `json:"riskInfo"`
- }
- type CustInfo struct {
- MobileTel string `json:"mobile_tel"`
- DealMobileTel string `json:"deal_mobile_tel"`
- ClientName string `json:"client_name"`
- IdKind string `json:"id_kind"`
- IdNo string `json:"id_no"`
- }
- 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 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"`
- }
|