package services import ( "encoding/json" "eta/eta_api/models" "eta/eta_api/services/alarm_msg" "eta/eta_api/utils" "fmt" "io/ioutil" "net/http" "net/url" "strings" ) // SendSmsCode 发送国内短信 func SendSmsCode(mobile, vCode, tplId string) (flag bool) { if mobile == "" || vCode == "" || tplId == "" { return } var ( err error res string ) defer func() { if err != nil { tips := fmt.Sprintf("短信验证码发送失败, Err: %s; Result: %s", err.Error(), res) utils.FileLog.Info("%s", tips) go alarm_msg.SendAlarmMsg(tips, 2) } }() // 获取配置好的短信模版 smsCond := ` AND conf_key = ? ` smsPars := make([]interface{}, 0) smsPars = append(smsPars, "SmsJhgnAppKey") conf := new(models.BusinessConf) conf, e := conf.GetItemByCondition(smsCond, smsPars) if e != nil { if e.Error() == utils.ErrNoRow() { err = fmt.Errorf("请先配置聚合短信Appkey") return } err = fmt.Errorf("获取聚合短信配置信息失败, Err: %s", e.Error()) return } if conf.ConfVal == "" { err = fmt.Errorf("请先配置聚合短信Appkey") return } result, e := sendSms(conf.ConfVal, mobile, tplId, vCode) if e != nil { err = fmt.Errorf("send sms err: %s", e.Error()) return } res = string(result) var netReturn map[string]interface{} if e = json.Unmarshal(result, &netReturn); e != nil { err = fmt.Errorf("json unmarshal err: %s", e.Error()) return } errCode, ok := netReturn["error_code"].(float64) if !ok { err = fmt.Errorf("result code err") return } // 忽略错误的手机号码这种错误 if errCode != 0 && errCode != 205401 { err = fmt.Errorf("err code %f", errCode) return } // 发送成功 if errCode == 0 { flag = true } return } // sendSms 发送国内短信 func sendSms(jhGnAppKey, mobile, tplId, code string) (rs []byte, err error) { var Url *url.URL apiURL := "http://v.juhe.cn/sms/send" //初始化参数 param := url.Values{} //配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参 param.Set("mobile", mobile) //接受短信的用户手机号码 param.Set("tpl_id", tplId) //您申请的短信模板ID,根据实际情况修改 tplVal := fmt.Sprintf(`#code#=%s&#m#=%d`, code, utils.VerifyCodeExpireMinute) param.Set("tpl_value", tplVal) //您设置的模板变量,根据实际情况 param.Set("key", jhGnAppKey) //应用APPKEY(应用详细页查询) Url, err = url.Parse(apiURL) if err != nil { fmt.Printf("解析url错误:\r\n%v", err) return nil, err } //如果参数中有中文参数,这个方法会进行URLEncode Url.RawQuery = param.Encode() resp, err := http.Get(Url.String()) if err != nil { fmt.Println("err:", err) return nil, err } defer resp.Body.Close() return ioutil.ReadAll(resp.Body) } // SendSmsCodeGj 发送国际短信 //func SendSmsCodeGj(mobile, vCode, areaNum, tplId string) bool { // var err error // defer func() { // if err != nil { // tips := fmt.Sprintf("短信验证码发送失败, Err: %s", err.Error()) // utils.FileLog.Info("%s", tips) // go alarm_msg.SendAlarmMsg(tips, 2) // } // }() // // 获取配置好的短信模版 // smsCond := ` AND conf_key = ? ` // smsPars := make([]interface{}, 0) // smsPars = append(smsPars, "SmsJhgjAppKey") // conf := new(models.BusinessConf) // conf, e := conf.GetItemByCondition(smsCond, smsPars) // if e != nil { // if e.Error() == utils.ErrNoRow() { // err = fmt.Errorf("请先配置聚合短信Appkey") // return false // } // err = fmt.Errorf("获取聚合短信配置信息失败, Err: %s", e.Error()) // return false // } // if conf.ConfVal == "" { // err = fmt.Errorf("请先配置聚合短信Appkey") // return false // } // result, err := sendSmsGj(conf.ConfVal, mobile, vCode, areaNum, tplId) // if err != nil { // fmt.Println("发送短信失败") // return false // } // fmt.Println("result", string(result)) // var netReturn map[string]interface{} // err = json.Unmarshal(result, &netReturn) // if err != nil { // err = fmt.Errorf("短信验证码发送失败, Err:" + err.Error() + ";Result:" + string(result)) // return false // } // if netReturn["error_code"].(float64) == 0 { // fmt.Printf("接口返回result字段是:\r\n%v", netReturn["result"]) // return true // } else { // // 忽略错误的手机号码这种错误 // if netReturn["error_code"].(float64) != 205401 { // err = fmt.Errorf("短信验证码发送失败, Result:" + string(result)) // } // return false // } //} // sendSmsGj 发送国际短信 func sendSmsGj(jhGjAppKey, mobile, code, areaNum, tplId, tplValue string) (rs []byte, err error) { var Url *url.URL apiURL := "http://v.juhe.cn/smsInternational/send.php" //初始化参数 param := url.Values{} //配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参 param.Set("mobile", mobile) //接受短信的用户手机号码 //param.Set("tplId", "10054") //您申请的短信模板ID,根据实际情况修改 param.Set("tplId", tplId) //您申请的短信模板ID,根据实际情况修改 if strings.Contains(tplValue, "#code#=%s") { tplValue = strings.Replace(tplValue, "#code#=%s", "#code#="+code, 1) } if strings.Contains(tplValue, "#m#=%d") { tplValue = strings.Replace(tplValue, "#m#=%d", fmt.Sprintf("#m#=%d", utils.VerifyCodeExpireMinute), 1) } //param.Set("tplValue", "#code#="+code) //您设置的模板变量,根据实际情况 param.Set("tplValue", tplValue) //您设置的模板变量,根据实际情况 param.Set("key", jhGjAppKey) //应用APPKEY(应用详细页查询) param.Set("areaNum", areaNum) //应用APPKEY(应用详细页查询) Url, err = url.Parse(apiURL) if err != nil { fmt.Printf("解析url错误:\r\n%v", err) return nil, err } //如果参数中有中文参数,这个方法会进行URLEncode Url.RawQuery = param.Encode() resp, err := http.Get(Url.String()) if err != nil { fmt.Println("err:", err) return nil, err } utils.FileLog.Info("sendSmsGj:param:" + Url.String()) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) utils.FileLog.Info("sendSmsGj:result:" + string(body)) return body, err } type SmsClient interface { SendUserLoginCode(UserLoginSmsCodeReq) (UserLoginSmsCodeResult, error) } func NewSmsClient() (cli SmsClient, err error) { confMap, e := models.GetBusinessConf() if e != nil { err = fmt.Errorf("GetBusinessConf err: %s", e.Error()) return } if confMap[models.BusinessConfSmsClient] == models.BusinessConfClientFlagNanHua { return new(NanHuaSms), nil } return new(HzSms), nil } type HzSms struct{} type UserLoginSmsCodeReq struct { TelAreaCode string `description:"区号"` Mobile string `description:"手机号"` VerifyCode string `description:"短信验证码"` } type UserLoginSmsCodeResult struct { Success bool `description:"发送是否成功"` Message string `description:"提示信息"` RequestId string `description:"发送ID,用于回查发送状态"` } // SendUserLoginCode 发送用户登录验证码 func (cli *HzSms) SendUserLoginCode(req UserLoginSmsCodeReq) (result UserLoginSmsCodeResult, err error) { if req.Mobile == "" || req.VerifyCode == "" { err = fmt.Errorf("参数有误, Mobile: %s, VerifyCode: %s", req.Mobile, req.VerifyCode) return } confMap, e := models.GetBusinessConf() if e != nil { err = fmt.Errorf("GetBusinessConf err: %s", e.Error()) return } // 国内短信 var netReturn map[string]interface{} if req.TelAreaCode == utils.TelAreaCodeHome { tplId := confMap[models.BusinessConfLoginSmsTpId] if tplId == "" { err = fmt.Errorf("请先配置短信模板") return } appKey := confMap[models.BusinessConfSmsJhgnAppKey] if appKey == "" { err = fmt.Errorf("请先配置聚合短信AppKey") return } smsRes, e := sendSms(appKey, req.Mobile, tplId, req.VerifyCode) if e != nil { err = fmt.Errorf("send sms err: %s", e.Error()) return } if e = json.Unmarshal(smsRes, &netReturn); e != nil { err = fmt.Errorf("json unmarshal err: %s", e.Error()) return } } // 国际短信 if req.TelAreaCode != utils.TelAreaCodeHome { tplId := confMap[models.BusinessConfLoginSmsGjTpId] if tplId == "" { err = fmt.Errorf("请先配置短信模板") return } appKey := confMap[models.BusinessConfSmsJhgjAppKey] if appKey == "" { err = fmt.Errorf("请先配置聚合短信AppKey") return } tplValue := confMap[models.BusinessConfSmsJhgjVariable] if tplValue == "" { // 默认初版变量 tplValue = "#code#=%s" } smsRes, e := sendSmsGj(appKey, req.Mobile, req.VerifyCode, req.TelAreaCode, tplId, tplValue) if e != nil { err = fmt.Errorf("send gj sms err: %s", e.Error()) return } if e = json.Unmarshal(smsRes, &netReturn); e != nil { err = fmt.Errorf("json unmarshal err: %s", e.Error()) return } } errCode, ok := netReturn["error_code"].(float64) if !ok { err = fmt.Errorf("result code err") return } // 忽略错误的手机号码这种错误 if errCode != 0 && errCode != 205401 { err = fmt.Errorf("err code %f", errCode) return } // 发送成功 if errCode == 0 { result.Success = true } return }