From b1e531ce6f009069e765133e95397af4d191c4ed Mon Sep 17 00:00:00 2001 From: Leufolium Date: Wed, 25 Sep 2024 13:13:35 +0800 Subject: [PATCH] by Robin at 20240925 --- api/consts/consts.go | 1 + api/message/request/ZTHY10000001Req.go | 23 +++++ api/message/response/ZTHY10000001Resp.go | 11 +++ app/mix/cmd/main.go | 1 + app/mix/conf/cfg.go | 1 + app/mix/service/logic/veriCode.go | 65 ++++++++++--- app/mix/service/service.go | 2 +- app/mix/service/zthyservice.go | 93 +++++++++++++++++++ etc/mix/mix-local.yaml | 8 +- etc/mix/mix-prod-offline.yaml | 8 +- etc/mix/mix-prod.yaml | 8 +- etc/mix/mix-test-offline.yaml | 8 +- etc/mix/mix-test.yaml | 8 +- etc/mix/resource/esb_routing_table_config.xml | 1 + library/configcenter/configcenter.go | 8 ++ library/mycrypto/cryptoService.go | 3 + library/mycrypto/md5Crypto.go | 25 +++++ library/sms/client.go | 11 +++ 18 files changed, 264 insertions(+), 21 deletions(-) create mode 100644 api/message/request/ZTHY10000001Req.go create mode 100644 api/message/response/ZTHY10000001Resp.go create mode 100644 app/mix/service/zthyservice.go create mode 100644 library/mycrypto/md5Crypto.go diff --git a/api/consts/consts.go b/api/consts/consts.go index 4aa18397..4c1e78bb 100644 --- a/api/consts/consts.go +++ b/api/consts/consts.go @@ -66,6 +66,7 @@ const ( DefaultZoneTextKey = "default_zone_text" AuditTaskCollectionReflectKey = "audit_task_collection_reflect" StreamerFilterKey = "streamer_filter" + SmsSplitRatioKey = "sms_split_ratio" ) // del_flag diff --git a/api/message/request/ZTHY10000001Req.go b/api/message/request/ZTHY10000001Req.go new file mode 100644 index 00000000..3f577938 --- /dev/null +++ b/api/message/request/ZTHY10000001Req.go @@ -0,0 +1,23 @@ +package request + +// 模板短信发送报文 +type ZTHY10000001Req struct { + Username string `json:"username"` + Password string `json:"password"` + TKey string `json:"tKey"` + Signature string `json:"signature"` + TpId string `json:"tpId"` + Ext string `json:"ext"` + Time string `json:"time"` + Extend string `json:"extend"` + Records []*Record `json:"records"` +} + +type Record struct { + Mobile string `json:"mobile"` + TpContent *ValidCodeRecord `json:"tpContent"` +} + +type ValidCodeRecord struct { + ValidCode string `json:"valid_code"` +} diff --git a/api/message/response/ZTHY10000001Resp.go b/api/message/response/ZTHY10000001Resp.go new file mode 100644 index 00000000..5d022150 --- /dev/null +++ b/api/message/response/ZTHY10000001Resp.go @@ -0,0 +1,11 @@ +package response + +import "service/api/message/request" + +type ZTHY10000001Resp struct { + Code int `json:"code"` + Msg string `json:"msg"` + MsgId string `json:"msgId"` + TpId string `json:"tpId"` + InvalidList []*request.Record `json:"invalidList"` +} diff --git a/app/mix/cmd/main.go b/app/mix/cmd/main.go index 8e75e502..c56bacd9 100644 --- a/app/mix/cmd/main.go +++ b/app/mix/cmd/main.go @@ -91,6 +91,7 @@ func main() { service.DefaultVideoModerationTaskResultHandler = service.NewVideoModerationTaskResultHandler() service.DefaultEsbService = service.NewEsbService() service.DefaultHvyogoService = service.NewHvyogoService(cfg.Hvyogo) + service.DefaultZthyService = service.NewZthyService(cfg.Zthy) err = service.DefaultService.Init(cfg) if err != nil { msg := fmt.Sprintf("Service init fail, err: %v", err) diff --git a/app/mix/conf/cfg.go b/app/mix/conf/cfg.go index efac4254..f89ace23 100644 --- a/app/mix/conf/cfg.go +++ b/app/mix/conf/cfg.go @@ -29,4 +29,5 @@ type ConfigSt struct { Yeepay *configcenter.YeepayClientConfig `json:"yeepay" yaml:"yeepay"` SD *configcenter.ConsulServiceDiscovery `json:"sd" yaml:"sd"` // 服务发现 Hvyogo *configcenter.HvyogoConfig `json:"hvyogo" yaml:"hvyogo"` // 慧用工 + Zthy *configcenter.ZthyConfig `json:"zthy" yaml:"zthy"` // 助通融合云 } diff --git a/app/mix/service/logic/veriCode.go b/app/mix/service/logic/veriCode.go index 40d84a3b..d88179d4 100644 --- a/app/mix/service/logic/veriCode.go +++ b/app/mix/service/logic/veriCode.go @@ -3,13 +3,16 @@ package logic import ( "fmt" "math/rand" + "service/api/consts" vericodeproto "service/api/proto/vericode/proto" "service/app/mix/dao" "service/dbstruct" + "service/library/apollo" "service/library/configcenter" "service/library/idgenerator" "service/library/logger" "service/library/mycrypto" + "service/library/redis" "service/library/sms" interceptor "service/library/taginterceptor" "time" @@ -19,16 +22,22 @@ import ( goproto "google.golang.org/protobuf/proto" ) +type SendSmsFunction func(mobilephone string, vericode string) error + type VeriCode struct { - store *dao.Store - cfg *configcenter.DysmsapiConfig + store *dao.Store + cfg *configcenter.DysmsapiConfig + zthySendSmsFunc SendSmsFunction } -func NewVeriCode(store *dao.Store, cfg *configcenter.DysmsapiConfig) (a *VeriCode) { +func NewVeriCode(store *dao.Store, cfg *configcenter.DysmsapiConfig, zthySendSmsFunc SendSmsFunction) (a *VeriCode) { a = &VeriCode{ - store: store, - cfg: cfg, + store: store, + cfg: cfg, + zthySendSmsFunc: zthySendSmsFunc, } + // 临时增加流控标志 + redis.GetRedisClient().Set("sms_index", int64(0), 0) return } @@ -88,19 +97,45 @@ func (p *VeriCode) OpSendVeriCode(ctx *gin.Context, req *vericodeproto.OpSendReq return err } - //3.发送短信 - templateParam := "{\"code\": \"" + vericode + "\"}" - request := &dysmsapi.SendSmsRequest{ - PhoneNumbers: goproto.String(req.MobilePhone), - SignName: goproto.String(p.cfg.SignName), - TemplateCode: goproto.String(p.cfg.TemplateCode), - TemplateParam: goproto.String(templateParam), - } - err := sms.SendSms(request) + // 分流比率 + smsSplitRatio, err := apollo.GetIntValue(consts.SmsSplitRatioKey, apollo.ApolloOpts().SetNamespace("application")) if err != nil { - logger.Error("SendSms failed : %v", err) + logger.Error("Apollo read failed : %v", err) return err } + smsIndex, err := redis.GetRedisClient().GetInt64("sms_index") + if err != nil { + logger.Error("GetInt64 failed : %v", err) + return err + } + err = redis.GetRedisClient().Set("sms_index", (smsIndex+1)%10, 0) + if err != nil { + logger.Error("SetInt64 failed : %v", err) + return err + } + if smsIndex < int64(smsSplitRatio) { + //3.zthy发送短信 + err = p.zthySendSmsFunc(req.MobilePhone, vericode) + if err != nil { + logger.Error("SendSms failed : %v", err) + return err + } + } else { + //3.阿里云发送短信 + templateParam := "{\"code\": \"" + vericode + "\"}" + request := &dysmsapi.SendSmsRequest{ + PhoneNumbers: goproto.String(req.MobilePhone), + SignName: goproto.String(p.cfg.SignName), + TemplateCode: goproto.String(p.cfg.TemplateCode), + TemplateParam: goproto.String(templateParam), + } + err = sms.SendSms(request) + if err != nil { + logger.Error("SendSms failed : %v", err) + return err + } + } + return nil } diff --git a/app/mix/service/service.go b/app/mix/service/service.go index 0664aad9..7d823edb 100644 --- a/app/mix/service/service.go +++ b/app/mix/service/service.go @@ -199,7 +199,7 @@ func (s *Service) Init(c any) (err error) { yeepaycli.Init(cfg.Yeepay) _DefaultToken = logic.NewToken(store, cfg.Crypto) - _DefaultVeriCode = logic.NewVeriCode(store, cfg.Dysmsapi) + _DefaultVeriCode = logic.NewVeriCode(store, cfg.Dysmsapi, DefaultZthyService.SendSms) _DefaultVeriCodeSendTimes = logic.NewVeriCodeSendTimes(store) _DefaultAccount = logic.NewAccount(store) _DefaultProduct = logic.NewProduct(store) diff --git a/app/mix/service/zthyservice.go b/app/mix/service/zthyservice.go new file mode 100644 index 00000000..89fe6930 --- /dev/null +++ b/app/mix/service/zthyservice.go @@ -0,0 +1,93 @@ +package service + +import ( + "encoding/json" + "fmt" + "service/api/message/request" + "service/api/message/response" + "service/bizcommon/util" + "service/library/configcenter" + "service/library/logger" + "service/library/mycrypto" + "time" +) + +var DefaultZthyService *ZthyService + +type ZthyService struct { + Username string + Password string + Signature string + TpId string +} + +func NewZthyService(cfg *configcenter.ZthyConfig) *ZthyService { + return &ZthyService{ + Username: cfg.Username, + Password: cfg.Password, + Signature: cfg.Signature, + TpId: cfg.TpId, + } +} + +func (s *ZthyService) SendSms(mobilephone string, vericode string) error { + record := &request.Record{ + Mobile: mobilephone, + TpContent: &request.ValidCodeRecord{ + ValidCode: vericode, + }, + } + records := make([]*request.Record, 0) + records = append(records, record) + req := &request.ZTHY10000001Req{ + Records: records, + } + rsp, err := s.SendSmsReq(req) + if err != nil { + logger.Error("SendSmsReq fail, req: %v, err: %v", util.ToJson(req), err) + return err + } + if rsp.Code != 200 { + return fmt.Errorf(rsp.Msg) + } + return nil +} + +func (s *ZthyService) SendSmsReq(req *request.ZTHY10000001Req) (rsp *response.ZTHY10000001Resp, err error) { + // 写参 + req.Username = s.Username + req.Signature = s.Signature + req.TpId = s.TpId + // 生成时间戳 + req.TKey = fmt.Sprint(time.Now().Unix()) + // 生成密码 + req.Password, err = mycrypto.CryptoServiceInstance().MD5.EncryptToString([]byte(s.Password + req.TKey)) + if err != nil { + logger.Error("password md5 encryption fail, err: %v", err) + return + } + + // 生成json + msg, err := json.Marshal(req) + if err != nil { + logger.Error("json marshal fail, err: %v", err) + return + } + + // 发送消息 + resp, err := DefaultEsbService.SendMsg("ZTHY10000001", msg) + if err != nil { + logger.Error("SendMsg fail, req: %v, err: %v", util.ToJson(req), err) + return + } + + // 处理返回数据 + rsp = &response.ZTHY10000001Resp{} + err = json.Unmarshal(resp, rsp) + if err != nil { + logger.Error("json unmarshal fail, err: %v", err) + return + } + + return +} diff --git a/etc/mix/mix-local.yaml b/etc/mix/mix-local.yaml index c2b9077e..40d781d7 100644 --- a/etc/mix/mix-local.yaml +++ b/etc/mix/mix-local.yaml @@ -170,4 +170,10 @@ sd: hvyogo: cooperator_id: "C1252339226041655296" - position_id: "P1252701159697682432" \ No newline at end of file + position_id: "P1252701159697682432" + +zthy: + username: "XYDLhy" + password: "e76f4c5afa1d431b20e8856f6c5a08da" + signature: "【铁粉空间】" + tpId: "157478" \ No newline at end of file diff --git a/etc/mix/mix-prod-offline.yaml b/etc/mix/mix-prod-offline.yaml index 1ad22369..22b9c067 100644 --- a/etc/mix/mix-prod-offline.yaml +++ b/etc/mix/mix-prod-offline.yaml @@ -198,4 +198,10 @@ sd: hvyogo: cooperator_id: "C1248233014165520384" - position_id: "P1255937692118577152" \ No newline at end of file + position_id: "P1255937692118577152" + +zthy: + username: "XYDLhy" + password: "e76f4c5afa1d431b20e8856f6c5a08da" + signature: "【铁粉空间】" + tpId: "157478" \ No newline at end of file diff --git a/etc/mix/mix-prod.yaml b/etc/mix/mix-prod.yaml index edb58270..55b0ba3e 100644 --- a/etc/mix/mix-prod.yaml +++ b/etc/mix/mix-prod.yaml @@ -198,4 +198,10 @@ sd: hvyogo: cooperator_id: "C1248233014165520384" - position_id: "P1255937692118577152" \ No newline at end of file + position_id: "P1255937692118577152" + +zthy: + username: "XYDLhy" + password: "e76f4c5afa1d431b20e8856f6c5a08da" + signature: "【铁粉空间】" + tpId: "157478" \ No newline at end of file diff --git a/etc/mix/mix-test-offline.yaml b/etc/mix/mix-test-offline.yaml index 87fefb2f..340b987e 100644 --- a/etc/mix/mix-test-offline.yaml +++ b/etc/mix/mix-test-offline.yaml @@ -179,4 +179,10 @@ yeepay: hvyogo: cooperator_id: "C1252339226041655296" - position_id: "P1252701159697682432" \ No newline at end of file + position_id: "P1252701159697682432" + +zthy: + username: "XYDLhy" + password: "e76f4c5afa1d431b20e8856f6c5a08da" + signature: "【铁粉空间】" + tpId: "157478" \ No newline at end of file diff --git a/etc/mix/mix-test.yaml b/etc/mix/mix-test.yaml index 2922eca9..333945ea 100644 --- a/etc/mix/mix-test.yaml +++ b/etc/mix/mix-test.yaml @@ -198,4 +198,10 @@ sd: hvyogo: cooperator_id: "C1252339226041655296" - position_id: "P1252701159697682432" \ No newline at end of file + position_id: "P1252701159697682432" + +zthy: + username: "XYDLhy" + password: "e76f4c5afa1d431b20e8856f6c5a08da" + signature: "【铁粉空间】" + tpId: "157478" \ No newline at end of file diff --git a/etc/mix/resource/esb_routing_table_config.xml b/etc/mix/resource/esb_routing_table_config.xml index 83b1e8a1..29197563 100644 --- a/etc/mix/resource/esb_routing_table_config.xml +++ b/etc/mix/resource/esb_routing_table_config.xml @@ -4,4 +4,5 @@ https://oapi.hvyogo.com/api/v2/hire/worker/findDetails https://oapi.hvyogo.com/api/distribute/singleDistribute https://oapi.hvyogo.com/api/v2/hire/worker/update + https://api-shss.zthysms.com/v2/sendSmsTp \ No newline at end of file diff --git a/library/configcenter/configcenter.go b/library/configcenter/configcenter.go index aac3e216..15a823bb 100644 --- a/library/configcenter/configcenter.go +++ b/library/configcenter/configcenter.go @@ -200,6 +200,14 @@ type HvyogoConfig struct { PositionId string `json:"position_id" yaml:"position_id"` } +// 助通融合云通信 +type ZthyConfig struct { + Username string `json:"username" yaml:"username"` + Password string `json:"password" yaml:"password"` + Signature string `json:"signature" yaml:"signature"` + TpId string `json:"tpId" yaml:"tpId"` +} + func LoadConfig(configFilePath string, cfg interface{}) error { cfgStr, err := ioutil.ReadFile(configFilePath) if err != nil { diff --git a/library/mycrypto/cryptoService.go b/library/mycrypto/cryptoService.go index ed705cb3..152b27e4 100644 --- a/library/mycrypto/cryptoService.go +++ b/library/mycrypto/cryptoService.go @@ -24,6 +24,7 @@ type CryptoService struct { SHA256 *Sha256Crypto HygSHA1WithRSA *SHAwithRSACrypto HygAES *AesEcbCrypto + MD5 *Md5Crypto } func (cryptoService *CryptoService) Init(cryptoConfig *configcenter.CryptoConfig) (err error) { @@ -52,5 +53,7 @@ func (cryptoService *CryptoService) Init(cryptoConfig *configcenter.CryptoConfig return } + cryptoService.MD5 = NewMd5Crypto() + return } diff --git a/library/mycrypto/md5Crypto.go b/library/mycrypto/md5Crypto.go new file mode 100644 index 00000000..e4cdc2e9 --- /dev/null +++ b/library/mycrypto/md5Crypto.go @@ -0,0 +1,25 @@ +package mycrypto + +import ( + "crypto/md5" + "fmt" +) + +type Md5Crypto struct{} + +func NewMd5Crypto() (md5Crypto *Md5Crypto) { + return &Md5Crypto{} +} + +func (rsaCrypto *Md5Crypto) Encrypt(msg []byte) (encryptedBytes []byte, err error) { + hash := md5.Sum(msg) + encryptedString := fmt.Sprintf("%x", hash) + encryptedBytes = []byte(encryptedString) + return +} + +func (rsaCrypto *Md5Crypto) EncryptToString(msg []byte) (encryptedString string, err error) { + hash := md5.Sum(msg) + encryptedString = fmt.Sprintf("%x", hash) + return +} diff --git a/library/sms/client.go b/library/sms/client.go index d48a8490..8021305f 100644 --- a/library/sms/client.go +++ b/library/sms/client.go @@ -1,6 +1,7 @@ package sms import ( + "fmt" "service/bizcommon/util" "service/library/configcenter" "service/library/logger" @@ -34,8 +35,18 @@ func Init(cfg *configcenter.DysmsapiConfig) (err error) { func SendSms(request *dysmsapi.SendSmsRequest) (err error) { _result, err := defaultDysmsapiClient.SendSms(request) logger.Info("SendSms result:%v", _result) + if _result == nil || _result.Body == nil { + return fmt.Errorf("短信发送失败") + } + if util.DerefInt32(_result.StatusCode) != 200 { + return fmt.Errorf("短信发送失败") + } + if util.DerefString(_result.Body.Code) != "OK" { + return fmt.Errorf(util.DerefString(_result.Body.Message)) + } if err != nil { logger.Error("SendSms failed : %v", err) + return } return }