作者 yangfu
1 package sms 1 package sms
2 2
3 import ( 3 import (
4 - "ability/protocol"  
5 -  
6 - "github.com/astaxie/beego"  
7 - "github.com/astaxie/beego/httplib"  
8 - "gitlab.fjmaimaimai.com/mmm-go/gocomm/common"  
9 - "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" 4 + "encoding/json"
  5 + "errors"
10 ) 6 )
11 7
12 -type ISmsService interface {  
13 - Send(request *protocol.SmsCodeRequest) (err error) 8 +type ISmsServe interface {
  9 + Send() error //调用远端接口发送短信
  10 + TextContent(v ...interface{}) (string, error) //构建短信文本内容
  11 + ValidReturn() (string, error) //检查调用远端接口后的返回内容,可用于记日志等操作
14 } 12 }
15 13
16 -type YunPianSmsService struct{} 14 +type SmsServe struct {
  15 + ToPhone string
  16 + UseTpl string
  17 + smsContent string //非导出
  18 + serveReturn *YunPainReturn //非导出
  19 +}
17 20
18 -func assertImplement() {  
19 - var _ ISmsService = (*YunPianSmsService)(nil) 21 +type YunPainReturn struct {
  22 + Code int `json:"code"` //0代表发送成功,其他code代表出错,详细见"返回值说明"页面
  23 + Msg string `json:"msg"` //例如""发送成功"",或者相应错误信息
  24 + Count int `json:"count"` //发送成功短信的计费条数(计费条数:70个字一条,超出70个字时按每67字一条计费)
  25 + Mobile string `json:"string"` //发送手机号
  26 + Fee float64 `json:"fee"` //扣费金额,单位:元,类型:双精度浮点型/double
  27 + Sid int64 `json:"sid"` //短信id,64位整型
20 } 28 }
21 29
22 -//发送 30 +func NewSmsServe(toPhone string, useTpl string) *SmsServe {
  31 + return &SmsServe{
  32 + ToPhone: toPhone,
  33 + UseTpl: useTpl,
  34 + serveReturn: nil,
  35 + }
  36 +}
23 37
24 -func (s *YunPianSmsService) Send(request *protocol.SmsCodeRequest) (err error) {  
25 - var (  
26 - resp *YunPianResponse  
27 - )  
28 - log.Debug("[sms] mobile:", request.Phone, " content:", request.Content)  
29 - if beego.BConfig.RunMode != "prod" {  
30 - return 38 +//Send 短信服务发送动作
  39 +func (s *SmsServe) Send() error {
  40 + if len(s.ToPhone) == 0 {
  41 + return nil
31 } 42 }
32 - post := httplib.Post(beego.AppConfig.String("yunpian_sms_sdk_url"))  
33 - post.Param("apikey", beego.AppConfig.String("yunpian_app_key"))  
34 - post.Param("mobile", request.Phone)  
35 - post.Param("text", request.Content)  
36 - if err = post.ToJSON(&resp); err != nil {  
37 - return 43 + //TODO
  44 + //发送短信
  45 + //获取并设置返回值
  46 + return nil
  47 +}
  48 +
  49 +// TextContent 短信正文内容设置
  50 +func (s *SmsServe) TextContent(v ...interface{}) (string, error) {
  51 + tpl, err := getSmsTpl(s.UseTpl)
  52 + if err != nil {
  53 + return "", err
38 } 54 }
39 - if resp.Code != 0 || resp.Mobile != request.Phone {  
40 - log.Error("yunpian send sms code:", resp.Code, " error msg:", resp.Msg)  
41 - err = common.NewErrorWithMsg(1, resp.Msg) 55 + t, err := tpl.ParseTpl(v)
  56 + if err != nil {
  57 + return "", err
42 } 58 }
43 - return nil 59 + s.smsContent = t
  60 + return t, nil
44 } 61 }
45 62
46 -type YunPianResponse struct {  
47 - Code int `json:"code"` //0代表发送成功,其他code代表出错,详细见"返回值说明"页面  
48 - Msg string `json:"msg"` //例如""发送成功"",或者相应错误信息  
49 - Count int `json:"count"` //发送成功短信的计费条数(计费条数:70个字一条,超出70个字时按每67字一条计费)  
50 - Mobile string `json:"string"` //发送手机号  
51 - Fee float64 `json:"fee"` //扣费金额,单位:元,类型:双精度浮点型/double  
52 - Sid int64 `json:"sid"` //短信id,64位整型 63 +//ValidReturn 校验调用远端接口后返回的响应内容
  64 +func (s *SmsServe) ValidReturn() (string, error) {
  65 + if s.serveReturn == nil {
  66 + return "", errors.New("serveReturn is nil")
  67 + }
  68 + str, _ := json.Marshal(s.serveReturn)
  69 + if s.serveReturn.Code != 0 || s.serveReturn.Mobile != s.ToPhone {
  70 + return string(str), errors.New("send sms fail")
  71 + }
  72 + return string(str), nil
53 } 73 }
  1 +package sms
  2 +
  3 +import (
  4 + "errors"
  5 + "fmt"
  6 +)
  7 +
  8 +type ISmsTpl interface {
  9 + ParseTpl(v ...interface{}) (string, error)
  10 + String() string
  11 +}
  12 +
  13 +//注册短信模板
  14 +var smsTpl = map[string]ISmsTpl{
  15 + "10001": SmsTpl{"【云片网】您的验证码是%s", 1},
  16 +}
  17 +
  18 +const (
  19 + TplNotExit string = "tpl not exit"
  20 + TplFormateErr string = "tpl formate error"
  21 +)
  22 +
  23 +type SmsTpl struct {
  24 + Formate string
  25 + ParamNum int
  26 +}
  27 +
  28 +var (
  29 + _ ISmsTpl = SmsTpl{}
  30 +)
  31 +
  32 +//ParseTpl 根据传参填充模板内容
  33 +func (t SmsTpl) ParseTpl(v ...interface{}) (string, error) {
  34 + if len(v) < t.ParamNum {
  35 + return "", errors.New(TplFormateErr)
  36 + }
  37 + return fmt.Sprintf(t.String(), v), nil
  38 +}
  39 +
  40 +//String 返回模板字符串
  41 +func (t SmsTpl) String() string {
  42 + return t.Formate
  43 +}
  44 +
  45 +//getSmsTpl 获取样板
  46 +//TODO 待优化
  47 +func getSmsTpl(code string) (ISmsTpl, error) {
  48 + if tpl, ok := smsTpl[code]; ok {
  49 + return tpl, nil
  50 + }
  51 + return nil, errors.New(TplNotExit)
  52 +}
  1 +package sms
  2 +
  3 +import (
  4 + "ability/protocol"
  5 + "errors"
  6 +
  7 + "github.com/astaxie/beego"
  8 + "github.com/astaxie/beego/httplib"
  9 + "gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
  10 + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
  11 +)
  12 +
  13 +type ISmsService interface {
  14 + Send(request *protocol.SmsCodeRequest) (err error)
  15 + GetSmsTpl(code string, content ...interface{}) (string, error)
  16 +}
  17 +
  18 +type YunPianSmsService struct{}
  19 +
  20 +func assertImplement() {
  21 + var _ ISmsService = (*YunPianSmsService)(nil)
  22 +}
  23 +
  24 +//发送
  25 +
  26 +func (s *YunPianSmsService) Send(request *protocol.SmsCodeRequest) (err error) {
  27 + var (
  28 + resp *YunPianResponse
  29 + )
  30 + log.Debug("[sms] mobile:", request.Phone, " content:", request.Content)
  31 + if beego.BConfig.RunMode != "prod" {
  32 + return
  33 + }
  34 + post := httplib.Post(beego.AppConfig.String("yunpian_sms_sdk_url"))
  35 + post.Param("apikey", beego.AppConfig.String("yunpian_app_key"))
  36 + post.Param("mobile", request.Phone)
  37 + post.Param("text", request.Content)
  38 + if err = post.ToJSON(&resp); err != nil {
  39 + return
  40 + }
  41 + if resp.Code != 0 || resp.Mobile != request.Phone {
  42 + log.Error("yunpian send sms code:", resp.Code, " error msg:", resp.Msg)
  43 + err = common.NewErrorWithMsg(1, resp.Msg)
  44 + }
  45 + return nil
  46 +}
  47 +
  48 +func (s *YunPianSmsService) GetSmsTpl(code string, content ...interface{}) (string, error) {
  49 + // if data, ok := yunPianSmsTpl[code]; !ok {
  50 + // return fmt.Sprintf(data, content...), nil
  51 + // }
  52 +
  53 + return "", errors.New("GetSmsTpl err,code=" + code)
  54 +}
  55 +
  56 +type YunPianResponse struct {
  57 + Code int `json:"code"` //0代表发送成功,其他code代表出错,详细见"返回值说明"页面
  58 + Msg string `json:"msg"` //例如""发送成功"",或者相应错误信息
  59 + Count int `json:"count"` //发送成功短信的计费条数(计费条数:70个字一条,超出70个字时按每67字一条计费)
  60 + Mobile string `json:"string"` //发送手机号
  61 + Fee float64 `json:"fee"` //扣费金额,单位:元,类型:双精度浮点型/double
  62 + Sid int64 `json:"sid"` //短信id,64位整型
  63 +}