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,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"mysql.go",
"redis.go",
],
importpath = "go-common/app/interface/main/web-goblin/dao/share",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-goblin/conf:go_default_library",
"//app/interface/main/web-goblin/model/share:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log: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"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,46 @@
package share
import (
"context"
"go-common/app/interface/main/web-goblin/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/stat/prom"
)
// Dao dao struct.
type Dao struct {
// config
c *conf.Config
// db
db *sql.DB
// redis
redis *redis.Pool
}
// New new dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// config
c: c,
db: sql.NewMySQL(c.DB.Goblin),
redis: redis.NewPool(c.Redis.Config),
}
return
}
// Ping ping dao
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
return
}
return
}
// PromError stat and log.
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}

View File

@@ -0,0 +1,44 @@
package share
import (
"context"
"fmt"
"time"
shamdl "go-common/app/interface/main/web-goblin/model/share"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_shaSub = 100
_shasSQL = "SELECT id,mid,day_count,cycle,share_date,ctime,mtime FROM gb_share_%s WHERE mid = ? and cycle = ?"
)
func shaHit(mid int64) string {
return fmt.Sprintf("%02d", mid%_shaSub)
}
// Shares get shares.
func (d *Dao) Shares(c context.Context, mid int64) (res []*shamdl.Share, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_shasSQL, shaHit(mid)), mid, time.Now().Format("200601")); err != nil {
log.Error("Shares d.db.Query(%d) error(%v)", mid, err)
return
}
defer rows.Close()
for rows.Next() {
r := new(shamdl.Share)
if err = rows.Scan(&r.ID, &r.Mid, &r.DayCount, &r.Cycle, &r.ShareDate, &r.Ctime, &r.Mtime); err != nil {
log.Error("Shares:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}

View File

@@ -0,0 +1,60 @@
package share
import (
"context"
"fmt"
"go-common/library/cache/redis"
"go-common/library/log"
)
const _keySha = "sm_%d"
func keyShare(mid int64) string {
return fmt.Sprintf(_keySha, mid)
}
// SharesCache get shares from cache.
func (d *Dao) SharesCache(c context.Context, mid int64) (res map[string]int64, err error) {
var (
key = keyShare(mid)
conn = d.redis.Get(c)
)
defer conn.Close()
if res, err = redis.Int64Map(conn.Do("HGETALL", key)); err != nil {
log.Error("HGETALL %v failed error(%v)", key, err)
}
return
}
// SetSharesCache back cache from db.
func (d *Dao) SetSharesCache(c context.Context, expire int, mid int64, shares map[string]int64) (err error) {
var (
key = keyShare(mid)
conn = d.redis.Get(c)
)
defer conn.Close()
args := redis.Args{}.Add(key)
for k, v := range shares {
args = args.Add(k).Add(v)
}
if err = conn.Send("HMSET", args...); err != nil {
log.Error("conn.Send(HMSET, %s, %d) error(%v)", key, err)
return
}
if err = conn.Send("EXPIRE", key, expire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, expire, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}

View File

@@ -0,0 +1,65 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"channel_test.go",
"dao_test.go",
"pgc_test.go",
"recruit_test.go",
"ugc_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/web-goblin/conf:go_default_library",
"//app/interface/main/web-goblin/model/web:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"channel.go",
"dao.go",
"pgc.go",
"recruit.go",
"ugc.go",
],
importpath = "go-common/app/interface/main/web-goblin/dao/web",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-goblin/conf:go_default_library",
"//app/interface/main/web-goblin/model/web:go_default_library",
"//library/database/elastic:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata: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"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,31 @@
package web
import (
"context"
"time"
"go-common/app/interface/main/web-goblin/model/web"
)
const _cardSQL = "SELECT id,title,tag_id,card_type,card_value,recommand_reason,recommand_state,priority FROM channel_card WHERE stime<? AND etime>? AND `check`=2 AND is_delete=0 ORDER BY priority DESC"
// ChCard channel card.
func (d *Dao) ChCard(ctx context.Context, now time.Time) (res map[int64][]*web.ChCard, err error) {
res = map[int64][]*web.ChCard{}
rows, err := d.showDB.Query(ctx, _cardSQL, now, now)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
c := &web.ChCard{}
if err = rows.Scan(&c.ID, &c.Title, &c.ChannelID, &c.Type, &c.Value, &c.Reason, &c.ReasonType, &c.Pos); err != nil {
return
}
res[c.ChannelID] = append(res[c.ChannelID], c)
}
if err = rows.Err(); err != nil {
return
}
return
}

View File

@@ -0,0 +1,22 @@
package web
import (
"context"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestWebChCard(t *testing.T) {
convey.Convey("ChCard", t, func(c convey.C) {
var (
ctx = context.Background()
now = time.Now()
)
res, err := d.ChCard(ctx, now)
convey.So(err, convey.ShouldBeNil)
convey.So(res, convey.ShouldNotBeNil)
convey.Printf("%+v", res)
})
}

View File

@@ -0,0 +1,56 @@
package web
import (
"context"
"go-common/app/interface/main/web-goblin/conf"
"go-common/library/database/elastic"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
const (
_pgcFullURL = "/ext/internal/archive/channel/content"
_pgcIncreURL = "/ext/internal/archive/channel/content/change"
)
// Dao dao .
type Dao struct {
c *conf.Config
db *sql.DB
showDB *sql.DB
httpR *bm.Client
pgcFullURL, pgcIncreURL string
ela *elastic.Elastic
}
// New init mysql db .
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Goblin),
showDB: sql.NewMySQL(c.DB.Show),
httpR: bm.NewClient(c.SearchClient),
pgcFullURL: c.Host.PgcURI + _pgcFullURL,
pgcIncreURL: c.Host.PgcURI + _pgcIncreURL,
ela: elastic.NewElastic(c.Es),
}
return
}
// Close close the resource .
func (d *Dao) Close() {
}
// Ping dao ping .
func (d *Dao) Ping(c context.Context) error {
return nil
}
// PromError stat and log .
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}

View File

@@ -0,0 +1,44 @@
package web
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/interface/main/web-goblin/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.web-svr.web-goblin")
flag.Set("conf_token", "b2850ed0834343a9e435809857f5670d")
flag.Set("tree_id", "41730")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/web-goblin-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,65 @@
package web
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
)
// PgcFull pgc full .
func (d *Dao) PgcFull(ctx context.Context, tp int, pn, ps int64, source string) (res interface{}, err error) {
var (
param = url.Values{}
ip = metadata.String(ctx, metadata.RemoteIP)
rs struct {
Code int `json:"code"`
Data interface{} `json:"result"`
}
)
param.Set("bsource", source)
param.Set("season_type", strconv.Itoa(tp))
param.Set("page_no", strconv.FormatInt(pn, 10))
param.Set("page_size", strconv.FormatInt(ps, 10))
if err = d.httpR.Get(ctx, d.pgcFullURL, ip, param, &rs); err != nil {
log.Error("d.httpR.Get err(%v)", err)
return
}
if rs.Code != ecode.OK.Code() {
err = ecode.Int(rs.Code)
return
}
res = rs.Data
return
}
// PgcIncre pgc increment .
func (d *Dao) PgcIncre(ctx context.Context, tp int, pn, ps, start, end int64, source string) (res interface{}, err error) {
var (
param = url.Values{}
ip = metadata.String(ctx, metadata.RemoteIP)
)
var rs struct {
Code int `json:"code"`
Data interface{} `json:"result"`
}
param.Set("bsource", source)
param.Set("season_type", strconv.Itoa(tp))
param.Set("page_no", strconv.FormatInt(pn, 10))
param.Set("page_size", strconv.FormatInt(ps, 10))
param.Set("start_ts", strconv.FormatInt(start, 10))
param.Set("end_ts", strconv.FormatInt(end, 10))
if err = d.httpR.Get(ctx, d.pgcIncreURL, ip, param, &rs); err != nil {
log.Error("d.httpR.Get url(%s) err(%s)", d.pgcIncreURL+"?"+param.Encode(), err)
return
}
if rs.Code != ecode.OK.Code() {
err = ecode.Int(rs.Code)
return
}
res = rs.Data
return
}

View File

@@ -0,0 +1,48 @@
package web
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestWebPgcFull(t *testing.T) {
convey.Convey("PgcFull", t, func(ctx convey.C) {
var (
c = context.Background()
tp = int(1)
pn = int64(1)
ps = int64(10)
source = "youku"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PgcFull(c, tp, pn, ps, source)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestWebPgcIncre(t *testing.T) {
convey.Convey("PgcIncre", t, func(ctx convey.C) {
var (
c = context.Background()
tp = int(2)
pn = int64(1)
ps = int64(10)
start = int64(1505876448)
end = int64(1505876450)
source = "youku"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PgcIncre(c, tp, pn, ps, start, end, source)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,37 @@
package web
import (
"context"
"encoding/json"
xhttp "net/http"
"net/url"
"go-common/app/interface/main/web-goblin/model/web"
"go-common/library/ecode"
"go-common/library/log"
)
// Recruit .
func (d *Dao) Recruit(ctx context.Context, param url.Values, route *web.Params) (res json.RawMessage, err error) {
var (
req *xhttp.Request
rs json.RawMessage
mokaURI = d.c.Recruit.MokaURI + "/" + route.Route + "/" + d.c.Recruit.Orgid
)
if route.JobID != "" {
mokaURI = mokaURI + "/" + route.JobID
}
param.Del("route")
param.Del("job_id")
if req, err = xhttp.NewRequest("GET", mokaURI+"?"+param.Encode(), nil); err != nil {
log.Error("Recruit xhttp.NewRequest url(%s) error(%v)", mokaURI, err)
return
}
if err = d.httpR.Do(ctx, req, &rs); err != nil {
log.Error("Recruit d.httpR.Do url(%s) error(%v)", mokaURI, err)
err = ecode.NothingFound
return
}
res = rs
return
}

View File

@@ -0,0 +1,32 @@
package web
import (
"context"
"net/url"
"testing"
"go-common/app/interface/main/web-goblin/model/web"
"github.com/smartystreets/goconvey/convey"
)
func TestWebRecruit(t *testing.T) {
convey.Convey("Recruit", t, func(ctx convey.C) {
var (
c = context.Background()
params = url.Values{}
ru = &web.Params{
Route: "v1/jobs",
}
)
params.Set("mode", "social")
ctx.Convey("When everything gose positive", func(ctx convey.C) {
httpMock("GET", "https://api.mokahr.com/v1/jobs/bilibili").Reply(200).JSON(`{jobs:[], "total": 245}`)
res, err := d.Recruit(c, params, ru)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,31 @@
package web
import (
"context"
"time"
webmdl "go-common/app/interface/main/web-goblin/model/web"
"go-common/library/database/elastic"
"go-common/library/log"
)
const _ugcIncre = "web_goblin"
// UgcIncre ugc increment .
func (d *Dao) UgcIncre(ctx context.Context, pn, ps int, start, end int64) (res []*webmdl.SearchAids, err error) {
var (
startStr, endStr string
rs struct {
Result []*webmdl.SearchAids `json:"result"`
}
)
startStr = time.Unix(start, 0).Format("2006-01-02 15:04:05")
endStr = time.Unix(end, 0).Format("2006-01-02 15:04:05")
r := d.ela.NewRequest(_ugcIncre).WhereRange("mtime", startStr, endStr, elastic.RangeScopeLoRo).Fields("aid").Fields("action").Index(_ugcIncre).Pn(pn).Ps(ps)
if err = r.Scan(ctx, &rs); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
res = rs.Result
return
}

View File

@@ -0,0 +1,27 @@
package web
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestWebUgcIncre(t *testing.T) {
convey.Convey("UgcIncre", t, func(ctx convey.C) {
var (
c = context.Background()
pn = int(1)
ps = int(10)
start = int64(1505876448)
end = int64(1505876450)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.UgcIncre(c, pn, ps, start, end)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,62 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"qrcode_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-goblin/conf:go_default_library",
"//app/interface/main/web-goblin/model/wechat:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"dao.cache.go",
"dao.go",
"qrcode.go",
],
importpath = "go-common/app/interface/main/web-goblin/dao/wechat",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-goblin/conf:go_default_library",
"//app/interface/main/web-goblin/model/wechat:go_default_library",
"//library/cache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata: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"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,13 @@
package wechat
import (
"context"
"go-common/app/interface/main/web-goblin/model/wechat"
)
//go:generate $GOPATH/src/go-common/app/tool/cache/gen
type _cache interface {
// cache
AccessToken(c context.Context) (*wechat.AccessToken, error)
}

View File

@@ -0,0 +1,49 @@
// Code generated by $GOPATH/src/go-common/app/tool/cache/gen. DO NOT EDIT.
/*
Package wechat is a generated cache proxy package.
It is generated from:
type _cache interface {
// cache
AccessToken(c context.Context) (*wechat.AccessToken, error)
}
*/
package wechat
import (
"context"
"go-common/app/interface/main/web-goblin/model/wechat"
"go-common/library/net/metadata"
"go-common/library/stat/prom"
)
var _ _cache
// AccessToken get data from cache if miss will call source method, then add to cache.
func (d *Dao) AccessToken(c context.Context) (res *wechat.AccessToken, err error) {
addCache := true
res, err = d.CacheAccessToken(c)
if err != nil {
addCache = false
err = nil
}
if res != nil {
prom.CacheHit.Incr("AccessToken")
return
}
prom.CacheMiss.Incr("AccessToken")
res, err = d.RawAccessToken(c)
if err != nil {
return
}
var miss = res
if !addCache {
return
}
d.cache.Save(func() {
d.AddCacheAccessToken(metadata.WithContext(c), miss)
})
return
}

View File

@@ -0,0 +1,36 @@
package wechat
import (
"go-common/app/interface/main/web-goblin/conf"
"go-common/library/cache"
"go-common/library/cache/redis"
bm "go-common/library/net/http/blademaster"
)
// Dao dao struct.
type Dao struct {
// config
c *conf.Config
// redis
redis *redis.Pool
// httpClient
httpClient *bm.Client
// url
wxAccessTokenURL string
wxQrcodeURL string
cache *cache.Cache
}
// New new dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// config
c: c,
redis: redis.NewPool(c.Redis.Config),
httpClient: bm.NewClient(c.HTTPClient),
cache: cache.New(1, 1024),
}
d.wxAccessTokenURL = d.c.Host.Wechat + _accessTokenURI
d.wxQrcodeURL = d.c.Host.Wechat + _qrcodeURI
return
}

View File

@@ -0,0 +1,35 @@
package wechat
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/web-goblin/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.web-svr.web-goblin")
flag.Set("conf_token", "b2850ed0834343a9e435809857f5670d")
flag.Set("tree_id", "41730")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/web-goblin-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,137 @@
package wechat
import (
"context"
"encoding/json"
"net/http"
"net/url"
"strings"
"go-common/app/interface/main/web-goblin/model/wechat"
"go-common/library/cache/redis"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_accessTokenKey = "a_t_k"
_accessTokenURI = "/cgi-bin/token"
_qrcodeURI = "/wxa/getwxacodeunlimit"
)
// RawAccessToken get wechat access token.
func (d *Dao) RawAccessToken(c context.Context) (data *wechat.AccessToken, err error) {
params := url.Values{}
params.Set("grant_type", "client_credential")
params.Set("appid", d.c.Wechat.AppID)
params.Set("secret", d.c.Wechat.Secret)
var req *http.Request
if req, err = http.NewRequest(http.MethodGet, d.wxAccessTokenURL+"?"+params.Encode(), nil); err != nil {
log.Error("AccessToken http.NewRequest error(%v)", err)
return
}
var res struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
AccessToken string `json:"access_token"`
ExpiresIN int64 `json:"expires_in"`
}
if err = d.httpClient.Do(c, req, &res); err != nil {
log.Error("AccessToken d.httpClient.Do error(%v)", err)
return
}
if res.Errcode != ecode.OK.Code() {
log.Error("AccessToken errcode error(%d) msg(%s)", res.Errcode, res.Errmsg)
err = ecode.RequestErr
return
}
data = &wechat.AccessToken{AccessToken: res.AccessToken, ExpiresIn: res.ExpiresIN}
return
}
// Qrcode get qrcode.
func (d *Dao) Qrcode(c context.Context, accessToken, arg string) (qrcode []byte, err error) {
var (
req *http.Request
bs []byte
jsonErr error
)
params := url.Values{}
params.Set("access_token", accessToken)
if req, err = http.NewRequest(http.MethodPost, d.wxQrcodeURL+"?"+params.Encode(), strings.NewReader(arg)); err != nil {
log.Error("Qrcode http.NewRequest error(%v)", err)
return
}
if bs, err = d.httpClient.Raw(c, req); err != nil {
log.Error("Qrcode d.httpClient.Do error(%v)", err)
return
}
var res struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
if jsonErr = json.Unmarshal(bs, &res); jsonErr == nil && res.Errcode != ecode.OK.Code() {
log.Error("Qrcode errcode error(%d) msg(%s)", res.Errcode, res.Errmsg)
err = ecode.RequestErr
return
}
qrcode = bs
return
}
// CacheAccessToken cache access token
func (d *Dao) CacheAccessToken(c context.Context) (data *wechat.AccessToken, err error) {
var (
value []byte
key = _accessTokenKey
conn = d.redis.Get(c)
)
defer conn.Close()
if value, err = redis.Bytes(conn.Do("GET", key)); err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("CacheAccessToken conn.Do(GET, %s) error(%v)", key, err)
}
return
}
data = new(wechat.AccessToken)
if err = json.Unmarshal(value, &data); err != nil {
log.Error("CacheAccessToken json.Unmarshal(%v) error(%v)", value, err)
}
return
}
// AddCacheAccessToken add access token cache
func (d *Dao) AddCacheAccessToken(c context.Context, data *wechat.AccessToken) (err error) {
var (
bs []byte
key = _accessTokenKey
conn = d.redis.Get(c)
)
defer conn.Close()
if bs, err = json.Marshal(data); err != nil {
log.Error("AddCacheAccessToken json.Marshal(%v) error (%v)", data, err)
return
}
if err = conn.Send("SET", key, bs); err != nil {
log.Error("conn.Send(SET, %s, %s) error(%v)", key, string(bs), err)
return
}
expire := data.ExpiresIn - 60
if err = conn.Send("EXPIRE", key, expire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, expire, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}

View File

@@ -0,0 +1,58 @@
package wechat
import (
"context"
"testing"
"go-common/app/interface/main/web-goblin/model/wechat"
"go-common/library/ecode"
"github.com/smartystreets/goconvey/convey"
)
func TestWechatQrcode(t *testing.T) {
convey.Convey("Qrcode", t, func(ctx convey.C) {
var (
c = context.Background()
accessToken = "14_LZVbKTtstzal_T-AfG-EgkUI2WlCdRvKUqhiYKMhNyxsGjzc1K_a1GGWuMPCbX"
arg = `{"page":"","scene":"?avid=34188644"}`
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
qrcode, err := d.Qrcode(c, accessToken, arg)
ctx.Convey("Then err should be nil.qrcode should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, ecode.RequestErr)
ctx.Println(qrcode)
})
})
})
}
func TestWechatAddCacheAccessToken(t *testing.T) {
convey.Convey("AddCacheAccessToken", t, func(ctx convey.C) {
var (
c = context.Background()
data = &wechat.AccessToken{AccessToken: "string", ExpiresIn: 1111}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCacheAccessToken(c, data)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestWechatCacheAccessToken(t *testing.T) {
convey.Convey("CacheAccessToken", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
data, err := d.CacheAccessToken(c)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(data, convey.ShouldNotBeNil)
})
})
})
}