正在显示
7 个修改的文件
包含
163 行增加
和
9 行删除
@@ -6,7 +6,7 @@ require ( | @@ -6,7 +6,7 @@ require ( | ||
6 | github.com/astaxie/beego v1.10.0 | 6 | github.com/astaxie/beego v1.10.0 |
7 | github.com/go-sql-driver/mysql v1.4.1 | 7 | github.com/go-sql-driver/mysql v1.4.1 |
8 | github.com/prometheus/client_golang v1.1.0 | 8 | github.com/prometheus/client_golang v1.1.0 |
9 | - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 | 9 | + github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect |
10 | gitlab.fjmaimaimai.com/mmm-go/gocomm v0.0.1 | 10 | gitlab.fjmaimaimai.com/mmm-go/gocomm v0.0.1 |
11 | google.golang.org/appengine v1.6.2 // indirect | 11 | google.golang.org/appengine v1.6.2 // indirect |
12 | ) | 12 | ) |
@@ -65,6 +65,7 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | @@ -65,6 +65,7 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | ||
65 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | 65 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= |
66 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | 66 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= |
67 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | 67 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= |
68 | +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= | ||
68 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | 69 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
69 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= | 70 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= |
70 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | 71 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= |
@@ -89,8 +90,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 | @@ -89,8 +90,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 | ||
89 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= | 90 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= |
90 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | 91 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
91 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | 92 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
93 | +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
92 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | 94 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
93 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | 95 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
96 | +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= | ||
94 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | 97 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= |
95 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | 98 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= |
96 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | 99 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= |
services/datastore/database.go
0 → 100644
services/datastore/memory.go
0 → 100644
services/filestore/file.go
0 → 100644
1 | +package filestore | ||
2 | + | ||
3 | +//IFileStore TODO文件存储相关 | ||
4 | +type IFileStore interface { | ||
5 | + Auth() error //在获取文件前进行对请求进行检查 | ||
6 | + ReadFile() (string, error) //实际获取文件操作 | ||
7 | + StoreFile() (string, error) //实际存储文件操作 | ||
8 | + DeleteFile() error | ||
9 | +} | ||
10 | + | ||
11 | +// type LocalFileStore struct { | ||
12 | +// } | ||
13 | + | ||
14 | +// type XXXFileStore struct { | ||
15 | +// } |
@@ -3,22 +3,34 @@ package sms | @@ -3,22 +3,34 @@ package sms | ||
3 | import ( | 3 | import ( |
4 | "encoding/json" | 4 | "encoding/json" |
5 | "errors" | 5 | "errors" |
6 | + "fmt" | ||
7 | + "regexp" | ||
8 | + | ||
9 | + "github.com/astaxie/beego" | ||
10 | + "github.com/astaxie/beego/httplib" | ||
6 | ) | 11 | ) |
7 | 12 | ||
13 | +//ISmsServe 短信服务接口协议 | ||
8 | type ISmsServe interface { | 14 | type ISmsServe interface { |
9 | Send() error //调用远端接口发送短信 | 15 | Send() error //调用远端接口发送短信 |
10 | TextContent(v ...interface{}) (string, error) //构建短信文本内容 | 16 | TextContent(v ...interface{}) (string, error) //构建短信文本内容 |
11 | ValidReturn() (string, error) //检查调用远端接口后的返回内容,可用于记日志等操作 | 17 | ValidReturn() (string, error) //检查调用远端接口后的返回内容,可用于记日志等操作 |
18 | + Name() string | ||
12 | } | 19 | } |
13 | 20 | ||
21 | +//SmsServe 生产线上使用的短信服务 | ||
14 | type SmsServe struct { | 22 | type SmsServe struct { |
15 | - ToPhone string | ||
16 | - UseTpl string | ||
17 | - smsContent string //非导出 | ||
18 | - serveReturn *YunPainReturn //非导出 | 23 | + ToPhone string //对方的电话号码 |
24 | + UseTpl string //使用的短信模板 | ||
25 | + smsContent string //非导出,最终发送的短信内容 | ||
26 | + serveReturn *YunPianReturn //非导出,调用远端接口后的响应内容 | ||
19 | } | 27 | } |
20 | 28 | ||
21 | -type YunPainReturn struct { | 29 | +var ( |
30 | + _ ISmsServe = &SmsServe{} | ||
31 | +) | ||
32 | + | ||
33 | +type YunPianReturn struct { | ||
22 | Code int `json:"code"` //0代表发送成功,其他code代表出错,详细见"返回值说明"页面 | 34 | Code int `json:"code"` //0代表发送成功,其他code代表出错,详细见"返回值说明"页面 |
23 | Msg string `json:"msg"` //例如""发送成功"",或者相应错误信息 | 35 | Msg string `json:"msg"` //例如""发送成功"",或者相应错误信息 |
24 | Count int `json:"count"` //发送成功短信的计费条数(计费条数:70个字一条,超出70个字时按每67字一条计费) | 36 | Count int `json:"count"` //发送成功短信的计费条数(计费条数:70个字一条,超出70个字时按每67字一条计费) |
@@ -36,17 +48,34 @@ func NewSmsServe(toPhone string, useTpl string) *SmsServe { | @@ -36,17 +48,34 @@ func NewSmsServe(toPhone string, useTpl string) *SmsServe { | ||
36 | } | 48 | } |
37 | 49 | ||
38 | //Send 短信服务发送动作 | 50 | //Send 短信服务发送动作 |
51 | +//实现接口 ISmsServe | ||
39 | func (s *SmsServe) Send() error { | 52 | func (s *SmsServe) Send() error { |
40 | if len(s.ToPhone) == 0 { | 53 | if len(s.ToPhone) == 0 { |
41 | return nil | 54 | return nil |
42 | } | 55 | } |
43 | - //TODO | 56 | + //校验号码合法性/^1[3456789][0-9]{9}$/ |
57 | + ok, err := regexp.MatchString(`^1[3456789][0-9]{9}$`, s.ToPhone) | ||
58 | + if !ok { | ||
59 | + return fmt.Errorf("ToPhone err:%w", err) | ||
60 | + } | ||
44 | //发送短信 | 61 | //发送短信 |
62 | + var ( | ||
63 | + resp *YunPianReturn | ||
64 | + ) | ||
65 | + post := httplib.Post(beego.AppConfig.String("yunpian_sms_sdk_url")) | ||
66 | + post.Param("apikey", beego.AppConfig.String("yunpian_app_key")) | ||
67 | + post.Param("mobile", s.ToPhone) | ||
68 | + post.Param("text", s.smsContent) | ||
69 | + if err := post.ToJSON(&resp); err != nil { | ||
70 | + return fmt.Errorf("parse yunpian response err:%w ", err) | ||
71 | + } | ||
45 | //获取并设置返回值 | 72 | //获取并设置返回值 |
73 | + s.serveReturn = resp | ||
46 | return nil | 74 | return nil |
47 | } | 75 | } |
48 | 76 | ||
49 | // TextContent 短信正文内容设置 | 77 | // TextContent 短信正文内容设置 |
78 | +//实现接口 ISmsServe | ||
50 | func (s *SmsServe) TextContent(v ...interface{}) (string, error) { | 79 | func (s *SmsServe) TextContent(v ...interface{}) (string, error) { |
51 | tpl, err := getSmsTpl(s.UseTpl) | 80 | tpl, err := getSmsTpl(s.UseTpl) |
52 | if err != nil { | 81 | if err != nil { |
@@ -61,6 +90,7 @@ func (s *SmsServe) TextContent(v ...interface{}) (string, error) { | @@ -61,6 +90,7 @@ func (s *SmsServe) TextContent(v ...interface{}) (string, error) { | ||
61 | } | 90 | } |
62 | 91 | ||
63 | //ValidReturn 校验调用远端接口后返回的响应内容 | 92 | //ValidReturn 校验调用远端接口后返回的响应内容 |
93 | +//实现接口 ISmsServe | ||
64 | func (s *SmsServe) ValidReturn() (string, error) { | 94 | func (s *SmsServe) ValidReturn() (string, error) { |
65 | if s.serveReturn == nil { | 95 | if s.serveReturn == nil { |
66 | return "", errors.New("serveReturn is nil") | 96 | return "", errors.New("serveReturn is nil") |
@@ -71,3 +101,69 @@ func (s *SmsServe) ValidReturn() (string, error) { | @@ -71,3 +101,69 @@ func (s *SmsServe) ValidReturn() (string, error) { | ||
71 | } | 101 | } |
72 | return string(str), nil | 102 | return string(str), nil |
73 | } | 103 | } |
104 | + | ||
105 | +func (s *SmsServe) Name() string { | ||
106 | + return "SmsServe" | ||
107 | +} | ||
108 | + | ||
109 | +//DevSmsServe 开发调试使用的短信服务 | ||
110 | +type DevSmsServe struct { | ||
111 | + ToPhone string //对方的电话号码 | ||
112 | + UseTpl string //使用的短信模板 | ||
113 | + smsContent string //非导出,最终发送的短信内容 | ||
114 | + serveReturn string //非导出,调用远端接口后的响应内容 | ||
115 | +} | ||
116 | + | ||
117 | +var ( | ||
118 | + _ ISmsServe = &DevSmsServe{} | ||
119 | +) | ||
120 | + | ||
121 | +func NewDevSmsServe(toPhone string, useTpl string) *DevSmsServe { | ||
122 | + return &DevSmsServe{ | ||
123 | + ToPhone: toPhone, | ||
124 | + UseTpl: useTpl, | ||
125 | + serveReturn: "", | ||
126 | + } | ||
127 | +} | ||
128 | + | ||
129 | +//Send 实现接口 ISmsServe | ||
130 | +func (s *DevSmsServe) Send() error { | ||
131 | + return nil | ||
132 | +} | ||
133 | + | ||
134 | +//TextContent 实现接口 ISmsServe | ||
135 | +func (s *DevSmsServe) TextContent(v ...interface{}) (string, error) { | ||
136 | + tpl, err := getSmsTpl(s.UseTpl) | ||
137 | + if err != nil { | ||
138 | + return "", err | ||
139 | + } | ||
140 | + t, err := tpl.ParseTpl(v) | ||
141 | + if err != nil { | ||
142 | + return "", err | ||
143 | + } | ||
144 | + s.smsContent = t | ||
145 | + return t, nil | ||
146 | +} | ||
147 | + | ||
148 | +//ValidReturn 实现接口 ISmsServe | ||
149 | +func (s *DevSmsServe) ValidReturn() (string, error) { | ||
150 | + return "ok", nil | ||
151 | +} | ||
152 | + | ||
153 | +func (s *DevSmsServe) Name() string { | ||
154 | + return "DevSmsServe" | ||
155 | +} | ||
156 | + | ||
157 | +//SendSms 发送短信调用出口 TODO | ||
158 | +func SendSms(phone string, code string, param ...interface{}) error { | ||
159 | + var serve ISmsServe | ||
160 | + serve = NewSmsServe(phone, code) | ||
161 | + // serve = NewDevSmsServe(phone, code) | ||
162 | + | ||
163 | + _, err := serve.TextContent(param) | ||
164 | + if err != nil { | ||
165 | + return err | ||
166 | + } | ||
167 | + | ||
168 | + return serve.Send() | ||
169 | +} |
1 | package sms | 1 | package sms |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "bytes" | ||
4 | "errors" | 5 | "errors" |
5 | "fmt" | 6 | "fmt" |
7 | + "html/template" | ||
6 | ) | 8 | ) |
7 | 9 | ||
8 | type ISmsTpl interface { | 10 | type ISmsTpl interface { |
@@ -13,6 +15,9 @@ type ISmsTpl interface { | @@ -13,6 +15,9 @@ type ISmsTpl interface { | ||
13 | //注册短信模板 | 15 | //注册短信模板 |
14 | var smsTpl = map[string]ISmsTpl{ | 16 | var smsTpl = map[string]ISmsTpl{ |
15 | "10001": SmsTpl{"【云片网】您的验证码是%s", 1}, | 17 | "10001": SmsTpl{"【云片网】您的验证码是%s", 1}, |
18 | + "10002": SmsTplUseHtml{ | ||
19 | + `【买买买信息科技】{{.Code}}({{.AppName}}手机验证码,请完成验证),如非本人操作,请忽略本短信`, | ||
20 | + "10002"}, | ||
16 | } | 21 | } |
17 | 22 | ||
18 | const ( | 23 | const ( |
@@ -21,8 +26,8 @@ const ( | @@ -21,8 +26,8 @@ const ( | ||
21 | ) | 26 | ) |
22 | 27 | ||
23 | type SmsTpl struct { | 28 | type SmsTpl struct { |
24 | - Formate string | ||
25 | - ParamNum int | 29 | + Formate string //模板字符串 |
30 | + ParamNum int //模板限定参数数量 | ||
26 | } | 31 | } |
27 | 32 | ||
28 | var ( | 33 | var ( |
@@ -42,6 +47,35 @@ func (t SmsTpl) String() string { | @@ -42,6 +47,35 @@ func (t SmsTpl) String() string { | ||
42 | return t.Formate | 47 | return t.Formate |
43 | } | 48 | } |
44 | 49 | ||
50 | +//SmsTplUseHtml 以html模板方式构建短信模板 | ||
51 | +type SmsTplUseHtml struct { | ||
52 | + Formate string //模板字符串 | ||
53 | + Name string | ||
54 | +} | ||
55 | + | ||
56 | +var ( | ||
57 | + _ ISmsTpl = SmsTplUseHtml{} | ||
58 | +) | ||
59 | + | ||
60 | +func (t SmsTplUseHtml) ParseTpl(v ...interface{}) (string, error) { | ||
61 | + var param interface{} | ||
62 | + if len(v) > 0 { | ||
63 | + param = v[0] | ||
64 | + } | ||
65 | + tpl, err := template.New(t.Name).Parse(t.Formate) | ||
66 | + if err != nil { | ||
67 | + return "", err | ||
68 | + } | ||
69 | + btTpl := bytes.NewBuffer(nil) | ||
70 | + if err = tpl.Execute(btTpl, param); err != nil { | ||
71 | + return "", err | ||
72 | + } | ||
73 | + return btTpl.String(), nil | ||
74 | +} | ||
75 | +func (t SmsTplUseHtml) String() string { | ||
76 | + return t.Formate | ||
77 | +} | ||
78 | + | ||
45 | //getSmsTpl 获取样板 | 79 | //getSmsTpl 获取样板 |
46 | //TODO 待优化 | 80 | //TODO 待优化 |
47 | func getSmsTpl(code string) (ISmsTpl, error) { | 81 | func getSmsTpl(code string) (ISmsTpl, error) { |
-
请 注册 或 登录 后发表评论