Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["user_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"user.go",
"wechat.go",
],
importpath = "go-common/app/job/main/sms/dao",
tags = ["automanaged"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//app/job/main/sms/model:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/job/main/sms/dao/chuanglan:all-srcs",
"//app/job/main/sms/dao/mengwang:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["client_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//app/service/main/sms/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["client.go"],
importpath = "go-common/app/job/main/sms/dao/chuanglan",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//app/job/main/sms/model:go_default_library",
"//app/service/main/sms/model:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,224 @@
package chuanglan
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"go-common/app/job/main/sms/conf"
"go-common/app/job/main/sms/model"
smsmdl "go-common/app/service/main/sms/model"
"go-common/library/log"
xhttp "go-common/library/net/http/blademaster"
)
// Client .
type Client struct {
conf conf.Provider
client *xhttp.Client
}
type response struct {
Code string `json:"code"`
MsgID string `json:"msgId"`
ErrMsg string `json:"errorMsg"`
Time string `json:"time"`
}
// GetPid get pid
func (v *Client) GetPid() int32 {
return smsmdl.ProviderChuangLan
}
// NewClient new ChuangLan
func NewClient(c *conf.Config) *Client {
return &Client{
conf: *c.Provider,
client: xhttp.NewClient(c.HTTPClient),
}
}
// SendSms send sms
func (v *Client) SendSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
msg := model.SmsPrefix + r.Content
params := make(map[string]interface{})
params["account"] = v.conf.ChuangLanSmsUser
params["password"] = v.conf.ChuangLanSmsPwd
params["phone"] = r.Mobile
params["msg"] = url.QueryEscape(msg)
params["report"] = "true"
uri := v.conf.ChuangLanSmsURL
msgid, err = v.post(ctx, uri, params)
return
}
// SendActSms send act sms
func (v *Client) SendActSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
msg := model.SmsPrefix + r.Content + model.SmsSuffixChuangLan
params := make(map[string]interface{})
params["account"] = v.conf.ChuangLanActUser
params["password"] = v.conf.ChuangLanActPwd
params["phone"] = r.Mobile
params["msg"] = url.QueryEscape(msg)
params["report"] = "true"
uri := v.conf.ChuangLanActURL
msgid, err = v.post(ctx, uri, params)
return
}
// SendBatchActSms send batch act sms
func (v *Client) SendBatchActSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
msgid, err = v.SendActSms(ctx, r)
return
}
// SendInternationalSms send international sms
func (v *Client) SendInternationalSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
msg := model.SmsPrefix + r.Content
params := make(map[string]interface{})
params["account"] = v.conf.ChuangLanInternationUser
params["password"] = v.conf.ChuangLanInternationPwd
params["mobile"] = r.Country + r.Mobile
params["msg"] = msg
uri := v.conf.ChuangLanInternationURL
bytesData, err := json.Marshal(params)
if err != nil {
log.Error("ChuangLan send international Marshal error(%v)", err)
return
}
reader := bytes.NewReader(bytesData)
request, err := http.NewRequest(http.MethodPost, uri, reader)
if err != nil {
log.Error("ChuangLan send international NewRequest err(%v)", err)
return
}
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
type internation struct {
Code string `json:"code"`
Msgid string `json:"msgid"`
Error string `json:"error"`
}
res := &internation{}
if err = v.client.Do(ctx, request, res); err != nil {
log.Error("ChuangLan send international client.Do err(%v)", err)
return
}
if res.Code != "0" {
err = fmt.Errorf("ChuangLan send international sms code(%v) err(%v)", res.Code, res.Error)
return
}
msgid = res.Msgid
return
}
func (v *Client) post(ctx context.Context, uri string, params map[string]interface{}) (msgid string, err error) {
bytesData, err := json.Marshal(params)
if err != nil {
log.Error("ChuangLan Marshal error(%v)", err)
return
}
reader := bytes.NewReader(bytesData)
request, err := http.NewRequest(http.MethodPost, uri, reader)
if err != nil {
log.Error("ChuangLan NewRequest err(%v)", err)
return
}
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
res := &response{}
if err = v.client.Do(ctx, request, res); err != nil {
log.Error("ChuangLan client.Do err(%v)", err)
return
}
if res.Code != "0" {
err = fmt.Errorf("ChuangLan send sms code(%v) err(%v)", res.Code, res.ErrMsg)
return
}
msgid = res.MsgID
log.Info("url(%s) body(%v) resp(%+v)", uri, params, res)
return
}
// Callback .
type Callback struct {
MsgID string `json:"msgId"`
Mobile string `json:"mobile"`
Status string `json:"status"`
Desc string `json:"statusDesc"`
NotifyTime string `json:"notifyTime"`
ReportTime string `json:"reportTime"`
Length string `json:"length"`
}
type callbackResponse struct {
Code int `json:"ret"`
Result []*Callback `json:"result"`
}
// Callback sms callbacks.
func (v *Client) Callback(ctx context.Context, account, pwd, url string, count int) (callbacks []*Callback, err error) {
params := make(map[string]interface{})
params["account"] = account
params["password"] = pwd
params["count"] = strconv.Itoa(count)
bs, err := json.Marshal(params)
if err != nil {
log.Error("ChuangLan sms callback Marshal error(%v)", err)
return
}
request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(bs))
if err != nil {
log.Error("ChuangLan sms callback NewRequest err(%v)", err)
return
}
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
res := &callbackResponse{}
if err = v.client.Do(ctx, request, res); err != nil {
log.Error("ChuangLan sms callback client.Do err(%v)", err)
return
}
if res.Code != 0 {
err = fmt.Errorf("ChuangLan sms callback code(%d)", res.Code)
return
}
callbacks = res.Result
return
}
// CallbackInternational sms callbacks.
func (v *Client) CallbackInternational(ctx context.Context, count int) (callbacks []*Callback, err error) {
params := make(map[string]interface{})
params["account"] = v.conf.ChuangLanInternationUser
params["password"] = v.conf.ChuangLanInternationPwd
params["count"] = strconv.Itoa(count)
bs, err := json.Marshal(params)
if err != nil {
log.Error("ChuangLan international sms callback Marshal error(%v)", err)
return
}
request, err := http.NewRequest(http.MethodPost, v.conf.ChuangLanInternationalCallbackURL, bytes.NewReader(bs))
if err != nil {
log.Error("ChuangLan international sms callback NewRequest err(%v)", err)
return
}
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
type intCallbackResponse struct {
Code int `json:"code"`
Error string `json:"error"`
Result []*Callback `json:"result"`
}
res := &intCallbackResponse{}
if err = v.client.Do(ctx, request, res); err != nil {
log.Error("ChuangLan international sms callback client.Do err(%v)", err)
return
}
if res.Code != 0 {
err = fmt.Errorf("ChuangLan international sms callback code(%d)", res.Code)
return
}
callbacks = res.Result
return
}

View File

@@ -0,0 +1,71 @@
package chuanglan
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/job/main/sms/conf"
"go-common/app/service/main/sms/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
cl *Client
sendLog = &model.ModelSend{
Content: "卍 您的账号正在哔哩哔哩2018动画角色人气大赏活动中进行领票操作验证码为5467当日有效",
}
)
func init() {
dir, _ := filepath.Abs("../../cmd/sms-job-test.toml")
flag.Set("conf", dir)
conf.Init()
cl = NewClient(conf.Conf)
}
func TestGetPid(t *testing.T) {
Convey("test chuanglan get pid", t, func() {
pID := cl.GetPid()
So(pID, ShouldEqual, model.ProviderChuangLan)
})
}
func TestSendSms(t *testing.T) {
Convey("test chuanglan send sms", t, func() {
sendLog.Mobile = ""
msgid, err := cl.SendSms(context.TODO(), sendLog)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendActSms(t *testing.T) {
Convey("test ChuangLan SendActSms", t, func() {
sendLog.Mobile = ""
msgid, err := cl.SendActSms(context.TODO(), sendLog)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendBatchActSms(t *testing.T) {
Convey("test ChuangLan sendBatchActSms", t, func() {
sendLog.Mobile = "" // 187****3870,189****1728
msgid, err := cl.SendBatchActSms(context.TODO(), sendLog)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendInternationalSms(t *testing.T) {
Convey("test ChuangLan SendInternationalSms", t, func() {
sendLog.Mobile = "" // 5344295506
sendLog.Country = "1"
msgid, err := cl.SendInternationalSms(context.TODO(), sendLog)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}

View File

@@ -0,0 +1,47 @@
package dao
import (
"context"
"go-common/app/job/main/sms/conf"
bm "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
// Dao struct info of Dao.
type Dao struct {
c *conf.Config
httpClient *bm.Client
}
var (
errorsCount = prom.BusinessErrCount
infosCount = prom.BusinessInfoCount
)
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
httpClient: bm.NewClient(c.HTTPClient),
}
return
}
// PromError prometheus error count.
func PromError(name string) {
errorsCount.Incr(name)
}
// PromInfo prometheus info count.
func PromInfo(name string) {
infosCount.Incr(name)
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {}
// Ping ping health of db.
func (d *Dao) Ping(c context.Context) (err error) {
return
}

View File

@@ -0,0 +1,48 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["client_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//app/service/main/sms/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["client.go"],
importpath = "go-common/app/job/main/sms/dao/mengwang",
tags = ["automanaged"],
deps = [
"//app/job/main/sms/conf:go_default_library",
"//app/job/main/sms/model:go_default_library",
"//app/service/main/sms/model:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,209 @@
package mengwang
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"time"
"go-common/app/job/main/sms/conf"
"go-common/app/job/main/sms/model"
smsmdl "go-common/app/service/main/sms/model"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// Client .
type Client struct {
c conf.Provider
client *bm.Client
}
type response struct {
Result int `json:"result"`
MsgID int64 `json:"msgid"`
}
// GetPid gets MengWang type ID.
func (v *Client) GetPid() int32 {
return smsmdl.ProviderMengWang
}
// NewClient new MengWang.
func NewClient(c *conf.Config) *Client {
return &Client{
c: *c.Provider,
client: bm.NewClient(c.HTTPClient),
}
}
func (v *Client) post(ctx context.Context, url string, params interface{}, res *response) (err error) {
var bs []byte
if bs, err = json.Marshal(params); err != nil {
log.Error("json.Marshal param(%v) error(%v)", params, err)
return
}
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer([]byte(bs)))
if err != nil {
log.Error("http.NewRequest(%s) param(%v) error(%v)", url, params, err)
return
}
req.Header.Set("Content-Type", "application/json")
if err = v.client.Do(ctx, req, &res); err != nil {
log.Error("client.Do(%s,%v) error(%v)", url, params, err)
return
}
log.Info("url(%s) body(%v) resp(%+v)", url, params, res)
return
}
// SendSms sends MengWang sms.
func (v *Client) SendSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
params := make(map[string]string)
pwd, ts := genPwd(v.c.MengWangSmsUser, v.c.MengWangSmsPwd)
params["userid"] = v.c.MengWangSmsUser
params["pwd"] = pwd
params["timestamp"] = ts
params["mobile"] = r.Mobile
params["content"] = url.QueryEscape(r.Content)
res := new(response)
if err = v.post(ctx, v.c.MengWangSmsURL, params, res); err != nil {
log.Error("mengwang SendSms param(%v) error(%v)", params, err)
return
}
if res.Result != 0 {
err = fmt.Errorf("mengwang SendSms param(%v) error(%v)", params, res.Result)
return
}
msgid = strconv.FormatInt(res.MsgID, 10)
return
}
// SendActSms sends MengWang act sms.
func (v *Client) SendActSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
params := make(map[string]string)
pwd, ts := genPwd(v.c.MengWangActUser, v.c.MengWangActPwd)
r.Content = r.Content + model.SmsSuffix
params["userid"] = v.c.MengWangActUser
params["pwd"] = pwd
params["timestamp"] = ts
params["mobile"] = r.Mobile
params["content"] = url.QueryEscape(r.Content)
res := new(response)
if err = v.post(ctx, v.c.MengWangActURL, params, res); err != nil {
log.Error("mengwang SendActSms param(%v) error(%v)", params, err)
return
}
if res.Result != 0 {
err = fmt.Errorf("mengwang SendActSms param(%v) error(%v)", params, res.Result)
return
}
msgid = strconv.FormatInt(res.MsgID, 10)
return
}
// SendBatchActSms sends multi MengWang act sms.
func (v *Client) SendBatchActSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
params := make(map[string]string)
pwd, ts := genPwd(v.c.MengWangActUser, v.c.MengWangActPwd)
params["userid"] = v.c.MengWangActUser
params["pwd"] = pwd
params["timestamp"] = ts
params["mobile"] = r.Mobile
params["content"] = url.QueryEscape(r.Content + model.SmsSuffix)
res := new(response)
if err = v.post(ctx, v.c.MengWangBatchURL, params, res); err != nil {
log.Error("mengwang SendBatchActSms param(%v) error(%v)", params, err)
return
}
if res.Result != 0 {
err = fmt.Errorf("mengwang SendBatchActSms param(%v) error(%v)", params, res.Result)
return
}
msgid = strconv.FormatInt(res.MsgID, 10)
return
}
// SendInternationalSms sends MengWang international sms.
func (v *Client) SendInternationalSms(ctx context.Context, r *smsmdl.ModelSend) (msgid string, err error) {
params := make(map[string]string)
pwd, ts := genPwd(v.c.MengWangInternationUser, v.c.MengWangInternationPwd)
params["userid"] = v.c.MengWangInternationUser
params["pwd"] = pwd
params["timestamp"] = ts
params["mobile"] = "00" + r.Country + r.Mobile
params["content"] = url.QueryEscape(r.Content)
res := new(response)
if err = v.post(ctx, v.c.MengWangInternationURL, params, res); err != nil {
log.Error("mengwang SendInternationalSms param(%v) error(%v)", params, err)
return
}
if res.Result != 0 {
err = fmt.Errorf("mengwang SendInternationalSms param(%v) error(%v)", params, res.Result)
return
}
msgid = strconv.FormatInt(res.MsgID, 10)
return
}
// Callback .
type Callback struct {
MsgID int64 `json:"msgid"`
Num int `json:"pknum"`
Total int `json:"pktotal"`
Mobile string `json:"mobile"`
SendTime string `json:"stime"`
ReportTime string `json:"rtime"`
Status string `json:"errcode"`
Desc string `json:"errdesc"`
}
type callbackResponse struct {
Result int `json:"result"`
Callbacks []*Callback `json:"rpts"`
}
// Callback .
func (v *Client) Callback(ctx context.Context, user, pwd, url string, count int) (callbacks []*Callback, err error) {
pwd, ts := genPwd(user, pwd)
params := make(map[string]string)
params["userid"] = user
params["pwd"] = pwd
params["timestamp"] = ts
params["retsize"] = strconv.Itoa(count)
bs, err := json.Marshal(params)
if err != nil {
log.Error("json.Marshal param(%v) error(%v)", params, err)
return
}
req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer([]byte(bs)))
if err != nil {
log.Error("http.NewRequest(%s) param(%v) error(%v)", url, params, err)
return
}
req.Header.Set("Content-Type", "application/json")
res := new(callbackResponse)
if err = v.client.Do(ctx, req, &res); err != nil {
log.Error("client.Do(%s,%v) error(%v)", url, params, err)
return
}
if res.Result != 0 {
err = fmt.Errorf("mengwang callback param(%v) res(%+v)", params, res)
return
}
callbacks = res.Callbacks
return
}
func genPwd(user, pwd string) (spwd, ts string) {
ft := time.Now().Format("0102150405")
str := fmt.Sprintf("%s%s%s%s", user, "00000000", pwd, ft)
mh := md5.Sum([]byte(str))
return hex.EncodeToString(mh[:]), ft
}

View File

@@ -0,0 +1,71 @@
package mengwang
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/job/main/sms/conf"
"go-common/app/service/main/sms/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
mw *Client
sl = &model.ModelSend{Mobile: "", Content: "卍 测试短信验证码为5467当日有效 https://search.bilibili.com/all?keyword=你好"} // 17621660828
isl = &model.ModelSend{Country: "852", Mobile: "", Content: "卍 您的账号正在哔哩哔哩2017动画角色人气大赏活动中进行领票操作验证码为5467当日有效"} // 00852 69529378 梦网的香港测试号
)
func init() {
dir, _ := filepath.Abs("../../cmd/sms-job-test.toml")
flag.Set("conf", dir)
conf.Init()
mw = NewClient(conf.Conf)
}
func TestSendSms(t *testing.T) {
Convey("mengwang send sms", t, func() {
msgid, err := mw.SendSms(context.TODO(), sl)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendActSms(t *testing.T) {
Convey("mengwang send act sms", t, func() {
msgid, err := mw.SendActSms(context.TODO(), sl)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendBatchSms(t *testing.T) {
Convey("mengwang send batch sms", t, func() {
msl := sl
msl.Mobile = "" // 17621660828,17621660828
msgid, err := mw.SendActSms(context.TODO(), msl)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestSendInternationalSms(t *testing.T) {
Convey("mengwang send international sms", t, func() {
msgid, err := mw.SendInternationalSms(context.TODO(), isl)
So(err, ShouldBeNil)
t.Logf("msgid(%s)", msgid)
})
}
func TestCallback(t *testing.T) {
Convey("mengwang callback", t, func() {
// callbacks, err := mw.Callback(context.Background(), conf.Conf.Pconf.MengWangSmsUser, conf.Conf.Pconf.MengWangSmsPwd, conf.Conf.Pconf.MengWangSmsCallbackURL, 5)
// So(err, ShouldBeNil)
// t.Logf("callbacks(%d)", len(callbacks))
// for _, v := range callbacks {
// t.Logf("callback(%+v)", v)
// }
})
}

View File

@@ -0,0 +1,30 @@
package dao
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/job/main/sms/model"
"go-common/library/log"
)
// UserMobile get user mobile
func (d *Dao) UserMobile(c context.Context, mid int64) (*model.UserMobile, error) {
res := struct {
Code int `json:"code"`
Data model.UserMobile `json:"data"`
}{}
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
if err := d.httpClient.Get(c, d.c.Sms.PassportMobileURL, "", params, &res); err != nil {
log.Error("d.GetUserMobile(%d) error(%v)", mid, err)
return nil, err
}
if res.Code != 0 {
return nil, fmt.Errorf("GetUserMobile(%d) error, res(%+v)", mid, &res)
}
log.Info("GetUserMobile(%d) res(%+v)", mid, &res)
return &res.Data, nil
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/job/main/sms/conf"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/sms-job-test.toml")
flag.Set("conf", dir)
flag.Parse()
conf.Init()
d = New(conf.Conf)
f(d)
}
}
func Test_GetUserMobile(t *testing.T) {
Convey("get user mobile", t, WithDao(func(d *Dao) {
mob, err := d.UserMobile(context.TODO(), 27515615)
So(err, ShouldBeNil)
So(mob, ShouldNotBeEmpty)
t.Logf("user(%d) mobile(%v)", 27515615, mob)
}))
}

View File

@@ -0,0 +1,81 @@
package dao
import (
"bytes"
"context"
"crypto/md5"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strconv"
"time"
"go-common/library/log"
)
type wechatResp struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
const (
// http://info.bilibili.co/pages/viewpage.action?pageId=5406728
_url = "http://bap.bilibili.co/api/v1/message/add"
)
// SendWechat 发送企业微信消息
func (d *Dao) SendWechat(msg string) (err error) {
log.Error("SendWechat logged error(%s)", msg)
params := map[string]string{
"content": msg,
"timestamp": strconv.FormatInt(time.Now().Unix(), 10),
"token": d.c.Wechat.Token,
"type": "wechat",
"username": d.c.Wechat.Username,
"url": "",
}
params["signature"] = d.sign(params)
b, err := json.Marshal(params)
if err != nil {
log.Error("SendWechat json.Marshal error(%v)", err)
return
}
req, err := http.NewRequest(http.MethodPost, _url, bytes.NewReader(b))
if err != nil {
log.Error("SendWechat NewRequest error(%v), params(%s)", err, string(b))
return
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
res := wechatResp{}
if err = d.httpClient.Do(context.TODO(), req, &res); err != nil {
log.Error("SendWechat Do error(%v), params(%s)", err, string(b))
return
}
if res.Status != 0 {
err = fmt.Errorf("status(%d) msg(%s)", res.Status, res.Msg)
log.Error("SendWechat response error(%v), params(%s)", err, string(b))
}
return
}
func (d *Dao) sign(params map[string]string) string {
var keys []string
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
buf := bytes.Buffer{}
for _, k := range keys {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(url.QueryEscape(k) + "=")
buf.WriteString(url.QueryEscape(params[k]))
}
h := md5.New()
io.WriteString(h, buf.String()+d.c.Wechat.Secret)
return fmt.Sprintf("%x", h.Sum(nil))
}