Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

21
app/admin/main/card/BUILD Normal file
View File

@@ -0,0 +1,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/card/cmd:all-srcs",
"//app/admin/main/card/conf:all-srcs",
"//app/admin/main/card/dao:all-srcs",
"//app/admin/main/card/model:all-srcs",
"//app/admin/main/card/server/http:all-srcs",
"//app/admin/main/card/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,8 @@
# v1.0.3
1. res = nil
# v1.0.2
1. fix sql
# v1.0.1
1. add group log
# v1.0.0
1. 卡片商城一期

View File

@@ -0,0 +1,7 @@
# Owner
zhaogangtao
yubaihai
# Author
yubaihai
# Reviewer

View File

@@ -0,0 +1,13 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- yubaihai
- zhaogangtao
labels:
- admin
- admin/main/card
- main
options:
no_parent_owners: true
reviewers:
- yubaihai

View File

@@ -0,0 +1,12 @@
# card-admin
# 项目简介
1.
# 编译环境
# 依赖包
# 编译执行

View File

@@ -0,0 +1 @@
# HTTP API文档

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["test.toml"],
importpath = "go-common/app/admin/main/card/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/server/http:go_default_library",
"//app/admin/main/card/service:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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,47 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/admin/main/card/conf"
"go-common/app/admin/main/card/server/http"
"go-common/app/admin/main/card/service"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
log.Info("card-admin start")
trace.Init(conf.Conf.Tracer)
defer trace.Close()
ecode.Init(conf.Conf.Ecode)
svc := service.New(conf.Conf)
http.Init(conf.Conf, svc)
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
svc.Close()
log.Info("card-admin exit")
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,47 @@
version = "1.0.0"
user = "nobody"
pid = "/tmp/card-admin.pid"
dir = "./"
unameTicker = "1m"
[bm]
addr = "0.0.0.0:7891"
maxListen = 1000
timeout = "1s"
[orm]
dsn = "root:123456@tcp(127.0.0.1:3306)/bilibili_card?timeout=3s&readTimeout=3s&writeTimeout=3s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout = "4h"
[memcache]
name = "card-service"
proto = "tcp"
addr = "172.18.33.60:11233"
idle = 5
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "24h"
[permit]
[permit.Memcache]
name = "go-business/auth"
proto = "tcp"
addr = "172.18.33.61:11232"
active = 10
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[bfs]
key = "b2f31180234e497c"
secret = "e96a241fb05f449502420d9271b2ed"
host = "http://uat-bfs.bilibili.co"
timeout = 1000
maxFileSize = 5242880

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/admin/main/card/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/conf:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/trace:go_default_library",
"//vendor/github.com/BurntSushi/toml: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,96 @@
package conf
import (
"errors"
"flag"
"go-common/library/conf"
"go-common/library/database/orm"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/trace"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config .
type Config struct {
Log *log.Config
BM *bm.ServerConfig
Tracer *trace.Config
Ecode *ecode.Config
ORM *orm.Config
//auth
Permit *permit.Config2
// bfs
Bfs *Bfs
}
// Bfs reprensents the bfs config
type Bfs struct {
Key string
Secret string
Host string
Timeout int
MaxFileSize int
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,60 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"bfs.go",
"dao.go",
"mysql.go",
],
importpath = "go-common/app/admin/main/card/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/model:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/pkg/errors: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"],
)
go_test(
name = "go_default_test",
srcs = [
"bfs_test.go",
"dao_test.go",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,88 @@
package dao
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"net/http"
"strconv"
"time"
"go-common/app/admin/main/card/conf"
"go-common/library/ecode"
"go-common/library/log"
)
// bfs info
const (
_uploadURL = "/bfs/%s/%s"
_template = "%s\n%s\n%s\n%d\n"
_method = "PUT"
_bucket = "vip"
)
// Upload upload picture or log file to bfs
func (d *Dao) Upload(c context.Context, fileName string, fileType string, data []byte, bfs *conf.Bfs) (location string, err error) {
var (
req *http.Request
resp *http.Response
code int
client = &http.Client{Timeout: time.Duration(bfs.Timeout) * time.Millisecond}
url = fmt.Sprintf(bfs.Host+_uploadURL, _bucket, fileName)
)
// prepare the data of the file and init the request
buf := new(bytes.Buffer)
_, err = buf.Write(data)
if err != nil {
log.Error("Upload.buf.Write.error(%v)", err)
err = ecode.RequestErr
return
}
if req, err = http.NewRequest(_method, url, buf); err != nil {
log.Error("http.NewRequest() Upload(%v) error(%v)", url, err)
return
}
timing := time.Now().Unix()
// request setting
authorization := authorize(bfs.Key, bfs.Secret, _method, _bucket, fileName, timing)
req.Header.Set("Date", fmt.Sprint(timing))
req.Header.Set("Authorization", authorization)
req.Header.Set("Content-Type", fileType)
resp, err = client.Do(req)
// response treatment
if err != nil {
log.Error("Bfs client.Do(%s) error(%v)", url, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("Bfs status code error:%v", resp.StatusCode)
return
}
code, err = strconv.Atoi(resp.Header.Get("code"))
if err != nil || code != 200 {
err = fmt.Errorf("Bfs response code error:%v", code)
return
}
location = resp.Header.Get("Location")
return
}
// authorize returns authorization for upload file to bfs
func authorize(key, secret, method, bucket, file string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf(_template, method, bucket, file, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoUpload(t *testing.T) {
convey.Convey("Upload", t, func(ctx convey.C) {
var (
c = context.Background()
fileName = ""
fileType = "png"
data = []byte("")
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.Upload(c, fileName, fileType, data, d.c.Bfs)
ctx.Convey("Then err should be nil.location should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,46 @@
package dao
import (
"context"
"go-common/app/admin/main/card/conf"
"go-common/library/database/orm"
"github.com/jinzhu/gorm"
)
// Dao dao
type Dao struct {
c *conf.Config
DB *gorm.DB
}
// New init mysql db
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
// db
DB: orm.NewMySQL(c.ORM),
}
d.initORM()
return
}
func (d *Dao) initORM() {
d.DB.LogMode(true)
}
// Close close the resource.
func (d *Dao) Close() {
if d.DB != nil {
d.DB.Close()
}
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) (err error) {
if d.DB != nil {
err = d.DB.DB().PingContext(c)
}
return
}

View File

@@ -0,0 +1,35 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/card/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.card-admin")
flag.Set("conf_token", "8c94348df107609cea7a865d80fd6e23")
flag.Set("tree_id", "59197")
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/card-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,193 @@
package dao
import (
"bytes"
"context"
"strconv"
"go-common/app/admin/main/card/model"
"go-common/library/xstr"
"github.com/pkg/errors"
)
// AddGroup add group info.
func (d *Dao) AddGroup(c context.Context, arg *model.AddGroup) error {
return d.DB.Table("card_group").Create(arg).Error
}
// UpdateGroup update group info.
func (d *Dao) UpdateGroup(c context.Context, arg *model.UpdateGroup) error {
return d.DB.Table("card_group").Where("id=?", arg.ID).Update(map[string]interface{}{
"name": arg.Name,
"state": arg.State,
"operator": arg.Operator,
}).Error
}
// Cards query cards.
func (d *Dao) Cards(c context.Context) (res []*model.Card, err error) {
err = d.DB.Table("card_info").Order("order_num desc").Where("state = 0 AND deleted = 0").Find(&res).Error
return
}
// CardsByGid query cards by group id.
func (d *Dao) CardsByGid(c context.Context, gid int64) (res []*model.Card, err error) {
err = d.DB.Table("card_info").Order("order_num desc").Where("group_id=?", gid).Where("deleted = 0").Find(&res).Error
return
}
// CardsByIds query cards by ids.
func (d *Dao) CardsByIds(c context.Context, ids []int64) (res []*model.Card, err error) {
err = d.DB.Table("card_info").Order("order_num desc").Where("id in (?)", ids).Where("deleted = 0").Find(&res).Error
return
}
// GroupsByIds query groups by ids.
func (d *Dao) GroupsByIds(c context.Context, ids []int64) (res []*model.CardGroup, err error) {
err = d.DB.Table("card_group").Order("order_num desc").Where("id in (?)", ids).Where("deleted = 0").Find(&res).Error
return
}
// AddCard add card.
func (d *Dao) AddCard(arg *model.AddCard) error {
return d.DB.Table("card_info").Create(arg).Error
}
// CardByName get card by name.
func (d *Dao) CardByName(name string) (res *model.Card, err error) {
res = new(model.Card)
q := d.DB.Table("card_info").Where("name=?", name).First(res)
if q.Error != nil {
if q.RecordNotFound() {
err = nil
res = nil
return
}
err = errors.Wrapf(err, "card by name")
}
return
}
// GroupByName get group by name.
func (d *Dao) GroupByName(name string) (res *model.CardGroup, err error) {
res = new(model.CardGroup)
q := d.DB.Table("card_group").Where("name=?", name).First(res)
if q.Error != nil {
if q.RecordNotFound() {
err = nil
res = nil
return
}
err = errors.Wrapf(err, "card_group by name")
}
return
}
// UpdateCard update card.
func (d *Dao) UpdateCard(req *model.UpdateCard) error {
args := map[string]interface{}{}
args["name"] = req.Name
args["state"] = req.State
args["is_hot"] = req.IsHot
args["operator"] = req.Operator
if req.CardURL != "" {
args["card_url"] = req.CardURL
}
if req.BigCradURL != "" {
args["big_crad_url"] = req.BigCradURL
}
return d.DB.Table("card_info").Where("id=?", req.ID).Update(args).Error
}
// UpdateCardState update card state.
func (d *Dao) UpdateCardState(c context.Context, id int64, state int8) error {
return d.DB.Table("card_info").Where("id=?", id).Update("state", state).Error
}
// DeleteCard delete card.
func (d *Dao) DeleteCard(c context.Context, id int64) error {
return d.DB.Table("card_info").Where("id=?", id).Delete(&model.Card{}).Error
}
// DeleteGroup delete group.
func (d *Dao) DeleteGroup(c context.Context, id int64) error {
return d.DB.Table("card_group").Where("id=?", id).Delete(&model.CardGroup{}).Error
}
// UpdateGroupState update group state.
func (d *Dao) UpdateGroupState(c context.Context, id int64, state int8) error {
return d.DB.Table("card_group").Where("id=?", id).Update("state", state).Error
}
// MaxCardOrder max card order num.
func (d *Dao) MaxCardOrder() (max int64, err error) {
err = d.DB.Table("card_info").Select("MAX(order_num)").Row().Scan(&max)
return
}
// MaxGroupOrder max card group order num.
func (d *Dao) MaxGroupOrder() (max int64, err error) {
err = d.DB.Table("card_group").Select("MAX(order_num)").Row().Scan(&max)
return
}
// BatchUpdateCardOrder update card order.
func (d *Dao) BatchUpdateCardOrder(c context.Context, cs []*model.Card) error {
var (
buf bytes.Buffer
ids []int64
)
buf.WriteString("UPDATE card_info SET order_num = CASE id")
for _, v := range cs {
buf.WriteString(" WHEN ")
buf.WriteString(strconv.FormatInt(v.ID, 10))
buf.WriteString(" THEN ")
buf.WriteString(strconv.FormatInt(v.OrderNum, 10))
ids = append(ids, v.ID)
}
buf.WriteString(" END WHERE id IN (")
buf.WriteString(xstr.JoinInts(ids))
buf.WriteString(");")
return d.DB.Exec(buf.String()).Error
}
// BatchUpdateCardGroupOrder update card order.
func (d *Dao) BatchUpdateCardGroupOrder(c context.Context, cs []*model.CardGroup) error {
var (
buf bytes.Buffer
ids []int64
)
buf.WriteString("UPDATE card_group SET order_num = CASE id")
for _, v := range cs {
buf.WriteString(" WHEN ")
buf.WriteString(strconv.FormatInt(v.ID, 10))
buf.WriteString(" THEN ")
buf.WriteString(strconv.FormatInt(v.OrderNum, 10))
ids = append(ids, v.ID)
}
buf.WriteString(" END WHERE id IN (")
buf.WriteString(xstr.JoinInts(ids))
buf.WriteString(");")
return d.DB.Exec(buf.String()).Error
}
// Groups query groups.
func (d *Dao) Groups(c context.Context, arg *model.ArgQueryGroup) (res []*model.CardGroup, err error) {
q := d.DB.Table("card_group").Where("deleted = 0")
if arg.GroupID > 0 {
q = q.Where("id = ?", arg.GroupID)
}
if arg.State > -1 {
q = q.Where("state = ?", arg.State)
}
if err = q.Order("order_num desc").Find(&res).Error; err != nil {
if q.RecordNotFound() {
err = nil
return
}
err = errors.Wrapf(err, "card group list")
return
}
return
}

View File

@@ -0,0 +1,311 @@
package dao
import (
"context"
"fmt"
"testing"
"time"
"go-common/app/admin/main/card/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddGroup(t *testing.T) {
convey.Convey("AddGroup", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &model.AddGroup{
Name: fmt.Sprintf("%v", time.Now().Unix()),
State: 0,
Operator: "superman",
OrderNum: time.Now().Unix(),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddGroup(c, arg)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpdateGroup(t *testing.T) {
convey.Convey("UpdateGroup", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &model.UpdateGroup{
ID: 1,
Name: fmt.Sprintf("%v", time.Now().UnixNano()),
State: 0,
Operator: "superman",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpdateGroup(c, arg)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCards(t *testing.T) {
convey.Convey("Cards", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Cards(c)
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 TestDaoGroupByName(t *testing.T) {
convey.Convey("GroupByName", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.GroupByName("te123156544664st")
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCardByName(t *testing.T) {
convey.Convey("CardByName", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.CardByName("tes...t")
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCardsByGid(t *testing.T) {
convey.Convey("CardsByGid", t, func(ctx convey.C) {
var (
c = context.Background()
gid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.CardsByGid(c, gid)
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 TestDaoCardsByIds(t *testing.T) {
convey.Convey("CardsByIds", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1, 2, 3, 4, 5}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.CardsByIds(c, ids)
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 TestDaoGroupsByIds(t *testing.T) {
convey.Convey("GroupsByIds", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1, 2, 3, 4, 5}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GroupsByIds(c, ids)
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 TestDaoAddCard(t *testing.T) {
convey.Convey("AddCard", t, func(ctx convey.C) {
var (
arg = &model.AddCard{
Name: fmt.Sprintf("%v", time.Now().Unix()),
State: 0,
Operator: "superman",
OrderNum: time.Now().Unix(),
CardURL: "http://www.baidu.com",
BigCradURL: "http://www.baidu.com",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCard(arg)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpdateCard(t *testing.T) {
convey.Convey("UpdateCard", t, func(ctx convey.C) {
var (
req = &model.UpdateCard{
ID: 1,
Name: fmt.Sprintf("%v", time.Now().UnixNano()),
State: 0,
Operator: "superman",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpdateCard(req)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpdateCardState(t *testing.T) {
convey.Convey("UpdateCardState", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(0)
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpdateCardState(c, id, state)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDeleteCard(t *testing.T) {
convey.Convey("DeleteCard", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DeleteCard(c, id)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDeleteGroup(t *testing.T) {
convey.Convey("DeleteGroup", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DeleteGroup(c, id)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpdateGroupState(t *testing.T) {
convey.Convey("UpdateGroupState", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(0)
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpdateGroupState(c, id, state)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoMaxCardOrder(t *testing.T) {
convey.Convey("MaxCardOrder", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
max, err := d.MaxCardOrder()
ctx.Convey("Then err should be nil.max should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(max, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoMaxGroupOrder(t *testing.T) {
convey.Convey("MaxGroupOrder", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
max, err := d.MaxGroupOrder()
ctx.Convey("Then err should be nil.max should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(max, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBatchUpdateCardOrder(t *testing.T) {
convey.Convey("BatchUpdateCardOrder", t, func(ctx convey.C) {
var (
c = context.Background()
cs = []*model.Card{{
ID: 1, OrderNum: 1},
{ID: 2, OrderNum: 2}}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.BatchUpdateCardOrder(c, cs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoBatchUpdateCardGroupOrder(t *testing.T) {
convey.Convey("BatchUpdateCardGroupOrder", t, func(ctx convey.C) {
var (
c = context.Background()
cs = []*model.CardGroup{{ID: 2, OrderNum: 2}, {ID: 1, OrderNum: 1}}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.BatchUpdateCardGroupOrder(c, cs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGroups(t *testing.T) {
convey.Convey("Groups", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &model.ArgQueryGroup{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Groups(c, arg)
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(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"model.go",
"params.go",
],
importpath = "go-common/app/admin/main/card/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
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,33 @@
package model
import "time"
// Card info.
type Card struct {
ID int64 `json:"id" gorm:"primary_key"`
Name string `json:"name" gorm:"column:name"`
State int32 `json:"state" gorm:"column:state"`
Deleted int32 `json:"deleted" gorm:"column:deleted"`
IsHot int32 `json:"is_hot" gorm:"column:is_hot"`
CardURL string `json:"card_url" gorm:"column:card_url"`
BigCradURL string `json:"big_crad_url" gorm:"column:big_crad_url"`
CardType int32 `json:"card_type" gorm:"column:card_type"`
OrderNum int64 `json:"order_num" gorm:"column:order_num"`
GroupID int64 `json:"group_id" gorm:"column:group_id"`
Operator string `json:"operator" gorm:"column:operator"`
Ctime time.Time `json:"-" gorm:"-"`
Mtime time.Time `json:"-" gorm:"-"`
}
// CardGroup card group info.
type CardGroup struct {
ID int64 `json:"id" gorm:"primary_key"`
Name string `json:"name" gorm:"column:name"`
State int8 `json:"state" gorm:"column:state"`
Deleted int8 `json:"deleted" gorm:"column:deleted"`
Operator string `json:"operator" gorm:"column:operator"`
OrderNum int64 `json:"order_num" gorm:"column:order_num"`
Ctime time.Time `json:"-" gorm:"-"`
Mtime time.Time `json:"-" gorm:"-"`
Cards []*Card `json:"cards,omitempty" gorm:"-"`
}

View File

@@ -0,0 +1,76 @@
package model
// ArgQueryGroup query group arg.
type ArgQueryGroup struct {
GroupID int64 `form:"group_id"`
State int8 `form:"state" default:"-1"`
}
// ArgQueryCards query cards arg.
type ArgQueryCards struct {
GroupID int64 `form:"group_id"`
}
// ArgState update state.
type ArgState struct {
ID int64 `form:"id" validate:"required,min=1,gte=1"`
State int8 `form:"state"`
}
// ArgID arg id.
type ArgID struct {
ID int64 `form:"id" validate:"required,min=1,gte=1"`
}
// ArgIds ids arg.
type ArgIds struct {
Ids []int64 `form:"ids,split" validate:"min=1,max=50"`
}
// AddGroup add group arg.
type AddGroup struct {
Name string `form:"name" validate:"required" gorm:"column:name"`
State int8 `form:"state" gorm:"column:state"`
Operator string `gorm:"column:operator"`
OrderNum int64 `gorm:"column:order_num"`
}
// UpdateGroup update group arg.
type UpdateGroup struct {
Name string `form:"name" validate:"required" gorm:"column:name"`
State int8 `form:"state" gorm:"column:state"`
Operator string `gorm:"column:operator"`
ID int64 `form:"id" validate:"required,min=1,gte=1"`
}
// AddCard add card arg.
type AddCard struct {
Name string `json:"name" gorm:"column:name" form:"name" validate:"required"`
State int32 `json:"state" gorm:"column:state" form:"state" `
IsHot int32 `json:"is_hot" gorm:"column:is_hot" form:"is_hot"`
CardURL string `json:"card_url" gorm:"column:card_url"`
BigCradURL string `json:"big_crad_url" gorm:"column:big_crad_url"`
CardType int32 `json:"card_type" gorm:"column:card_type" form:"card_type"`
OrderNum int64 `json:"order_num" gorm:"column:order_num"`
Operator string `json:"operator" gorm:"column:operator"`
GroupID int64 `json:"group_id" gorm:"column:group_id" form:"group_id" validate:"required"`
CardFileType string `gorm:"-"`
CardBody []byte `gorm:"-"`
BigCardFileType string `gorm:"-"`
BigCardBody []byte `gorm:"-"`
}
// UpdateCard update card info.
type UpdateCard struct {
ID int64 `form:"id" validate:"required,min=1,gte=1"`
Name string `json:"name" gorm:"column:name" form:"name" validate:"required"`
State int32 `json:"state" gorm:"column:state" form:"state" `
IsHot int32 `json:"is_hot" gorm:"column:is_hot" form:"is_hot"`
CardURL string `json:"card_url" gorm:"column:card_url"`
BigCradURL string `json:"big_crad_url" gorm:"column:big_crad_url"`
Operator string `json:"operator" gorm:"column:operator"`
CardFileType string `gorm:"-"`
CardBody []byte `gorm:"-"`
BigCardFileType string `gorm:"-"`
BigCardBody []byte `gorm:"-"`
}

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"card.go",
"http.go",
],
importpath = "go-common/app/admin/main/card/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/model:go_default_library",
"//app/admin/main/card/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/http/blademaster/middleware/permit: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,230 @@
package http
import (
"io/ioutil"
"mime/multipart"
"net/http"
"go-common/app/admin/main/card/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
func groups(c *bm.Context) {
var err error
arg := new(model.ArgQueryGroup)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(srv.GroupList(c, arg))
}
func cards(c *bm.Context) {
var err error
arg := new(model.ArgQueryCards)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(srv.CardsByGid(c, arg.GroupID))
}
func addGroup(c *bm.Context) {
var err error
username, ok := c.Get("username")
if !ok {
c.JSON(nil, ecode.AccessDenied)
return
}
arg := new(model.AddGroup)
arg.Operator = username.(string)
if err = c.Bind(arg); err != nil {
return
}
if len(arg.Name) > _maxnamelen {
c.JSON(nil, ecode.CardNameTooLongErr)
return
}
c.JSON(nil, srv.AddGroup(c, arg))
}
func updateGroup(c *bm.Context) {
var err error
username, ok := c.Get("username")
if !ok {
c.JSON(nil, ecode.AccessDenied)
return
}
arg := new(model.UpdateGroup)
arg.Operator = username.(string)
if err = c.Bind(arg); err != nil {
return
}
if len(arg.Name) > _maxnamelen {
c.JSON(nil, ecode.CardNameTooLongErr)
return
}
c.JSON(nil, srv.UpdateGroup(c, arg))
}
func addCard(c *bm.Context) {
var err error
username, ok := c.Get("username")
if !ok {
c.JSON(nil, ecode.AccessDenied)
return
}
arg := new(model.AddCard)
arg.Operator = username.(string)
if err = c.BindWith(arg, binding.FormMultipart); err != nil {
return
}
if len(arg.Name) > _maxnamelen {
c.JSON(nil, ecode.CardNameTooLongErr)
return
}
if arg.CardBody, arg.CardFileType, err = file(c, "card_url"); err != nil {
c.JSON(nil, err)
return
}
if arg.CardFileType == "" {
c.JSON(nil, ecode.CardImageEmptyErr)
return
}
if arg.BigCardBody, arg.BigCardFileType, err = file(c, "big_crad_url"); err != nil {
c.JSON(nil, err)
return
}
if arg.BigCardFileType == "" {
c.JSON(nil, ecode.CardImageEmptyErr)
return
}
c.JSON(nil, srv.AddCard(c, arg))
}
func updateCard(c *bm.Context) {
var err error
username, ok := c.Get("username")
if !ok {
c.JSON(nil, ecode.AccessDenied)
return
}
arg := new(model.UpdateCard)
arg.Operator = username.(string)
if err = c.BindWith(arg, binding.FormMultipart); err != nil {
return
}
if len(arg.Name) > _maxnamelen {
c.JSON(nil, ecode.CardNameTooLongErr)
return
}
if arg.CardBody, arg.CardFileType, err = file(c, "card_url"); err != nil {
c.JSON(nil, err)
return
}
if arg.BigCardBody, arg.BigCardFileType, err = file(c, "big_crad_url"); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, srv.UpdateCard(c, arg))
}
func cardStateChange(c *bm.Context) {
var err error
arg := new(model.ArgState)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.UpdateCardState(c, arg))
}
func deleteCard(c *bm.Context) {
var err error
arg := new(model.ArgID)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.DeleteCard(c, arg.ID))
}
func groupStateChange(c *bm.Context) {
var err error
arg := new(model.ArgState)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.UpdateGroupState(c, arg))
}
func deleteGroup(c *bm.Context) {
var err error
arg := new(model.ArgID)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.DeleteGroup(c, arg.ID))
}
func cardOrderChange(c *bm.Context) {
var err error
arg := new(model.ArgIds)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.CardOrderChange(c, arg))
}
func groupOrderChange(c *bm.Context) {
var err error
arg := new(model.ArgIds)
if err = c.Bind(arg); err != nil {
return
}
c.JSON(nil, srv.GroupOrderChange(c, arg))
}
func file(c *bm.Context, name string) (body []byte, filetype string, err error) {
var file multipart.File
if file, _, err = c.Request.FormFile(name); err != nil {
if err == http.ErrMissingFile {
err = nil
return
}
err = ecode.RequestErr
return
}
if file == nil {
return
}
defer file.Close()
if body, err = ioutil.ReadAll(file); err != nil {
err = ecode.RequestErr
return
}
filetype = http.DetectContentType(body)
if err = checkImgFileType(filetype); err != nil {
return
}
err = checkFileBody(body)
return
}
func checkImgFileType(filetype string) error {
switch filetype {
case "image/jpeg", "image/jpg":
case "image/png":
default:
return ecode.VipFileTypeErr
}
return nil
}
func checkFileBody(body []byte) error {
if len(body) == 0 {
return ecode.FileNotExists
}
if len(body) > cf.Bfs.MaxFileSize {
return ecode.FileTooLarge
}
return nil
}

View File

@@ -0,0 +1,61 @@
package http
import (
"net/http"
"go-common/app/admin/main/card/conf"
"go-common/app/admin/main/card/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
)
const _maxnamelen = 18
var (
srv *service.Service
cf *conf.Config
permitSvc *permit.Permit
)
// Init init
func Init(c *conf.Config, svc *service.Service) {
srv = svc
permitSvc = permit.New2(nil)
cf = c
engine := bm.DefaultServer(c.BM)
route(engine)
if err := engine.Start(); err != nil {
log.Error("bm Start error(%v)", err)
panic(err)
}
}
func route(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
group := e.Group("/x/admin/card", permitSvc.Permit2("CARD"))
group.GET("/group/list", groups)
group.POST("/group/add", addGroup)
group.POST("/group/modify", updateGroup)
group.POST("/group/state/change", groupStateChange)
group.POST("/group/delete", deleteGroup)
group.POST("/group/order", groupOrderChange)
group.POST("/order", cardOrderChange)
group.POST("/add", addCard)
group.POST("/modify", updateCard)
group.GET("/list", cards)
group.POST("/state/change", cardStateChange)
group.POST("/delete", deleteCard)
}
func ping(c *bm.Context) {
if err := srv.Ping(c); err != nil {
log.Error("ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(map[string]interface{}{}, nil)
}

View File

@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"card.go",
"service.go",
],
importpath = "go-common/app/admin/main/card/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/dao:go_default_library",
"//app/admin/main/card/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup: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"],
)
go_test(
name = "go_default_test",
srcs = ["card_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/card/conf:go_default_library",
"//app/admin/main/card/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,198 @@
package service
import (
"context"
"go-common/app/admin/main/card/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// CardsByGid get cards by gid.
func (s *Service) CardsByGid(c context.Context, gid int64) ([]*model.Card, error) {
return s.dao.CardsByGid(c, gid)
}
// UpdateCardState update card state.
func (s *Service) UpdateCardState(c context.Context, req *model.ArgState) error {
return s.dao.UpdateCardState(c, req.ID, req.State)
}
// DeleteCard delete card.
func (s *Service) DeleteCard(c context.Context, id int64) error {
return s.dao.DeleteCard(c, id)
}
// UpdateGroupState update group state.
func (s *Service) UpdateGroupState(c context.Context, req *model.ArgState) error {
return s.dao.UpdateGroupState(c, req.ID, req.State)
}
// DeleteGroup delete group.
func (s *Service) DeleteGroup(c context.Context, id int64) error {
return s.dao.DeleteGroup(c, id)
}
// GroupList group list.
func (s *Service) GroupList(c context.Context, req *model.ArgQueryGroup) (res []*model.CardGroup, err error) {
if res, err = s.dao.Groups(c, req); err != nil {
return
}
if len(res) <= 0 {
return
}
var cs []*model.Card
if cs, err = s.dao.Cards(c); err != nil {
return
}
tmp := make(map[int64][]*model.Card, len(res))
for _, v := range cs {
if len(tmp[v.GroupID]) <= 0 {
tmp[v.GroupID] = []*model.Card{}
}
tmp[v.GroupID] = append(tmp[v.GroupID], v)
}
for _, v := range res {
v.Cards = tmp[v.ID]
}
return
}
// CardOrderChange card order change.
func (s *Service) CardOrderChange(c context.Context, req *model.ArgIds) (err error) {
var cs []*model.Card
if cs, err = s.dao.CardsByIds(c, req.Ids); err != nil {
return
}
if len(req.Ids) != len(cs) {
err = ecode.CardIDNotFoundErr
return
}
orders := make(map[int]*model.Card, len(cs))
for i, v := range cs {
orders[i] = v
}
us := []*model.Card{}
for i, v := range req.Ids {
if orders[i].ID != v {
us = append(us, &model.Card{ID: v, OrderNum: orders[i].OrderNum})
}
}
if len(us) > 0 {
err = s.dao.BatchUpdateCardOrder(c, us)
}
return
}
// GroupOrderChange group order change.
func (s *Service) GroupOrderChange(c context.Context, req *model.ArgIds) (err error) {
var cs []*model.CardGroup
if cs, err = s.dao.GroupsByIds(c, req.Ids); err != nil {
return
}
if len(req.Ids) != len(cs) {
err = ecode.CardIDNotFoundErr
return
}
orders := make(map[int]*model.CardGroup, len(cs))
for i, v := range cs {
orders[i] = v
}
us := []*model.CardGroup{}
for i, v := range req.Ids {
if orders[i].ID != v {
us = append(us, &model.CardGroup{ID: v, OrderNum: orders[i].OrderNum})
}
}
if len(us) > 0 {
err = s.dao.BatchUpdateCardGroupOrder(c, us)
}
return
}
// AddCard add card.
func (s *Service) AddCard(c context.Context, req *model.AddCard) (err error) {
var exist *model.Card
if exist, err = s.dao.CardByName(req.Name); err != nil || exist != nil {
return ecode.CardNameExistErr
}
var g errgroup.Group
g.Go(func() (err error) {
if req.CardURL, err = s.dao.Upload(c, "", req.CardFileType, req.CardBody, s.c.Bfs); err != nil {
log.Error("d.Upload iconURL(%+v) error(%v)", req, err)
}
return
})
g.Go(func() (err error) {
if req.BigCradURL, err = s.dao.Upload(c, "", req.BigCardFileType, req.BigCardBody, s.c.Bfs); err != nil {
log.Error("d.Upload bigCardURL(%+v) error(%v)", req, err)
}
return
})
if err = g.Wait(); err != nil {
return
}
if req.CardURL == "" || req.BigCradURL == "" {
err = ecode.CardFileUploadFaildErr
return
}
var order int64
if order, err = s.dao.MaxCardOrder(); err != nil {
return
}
order++
req.OrderNum = order
err = s.dao.AddCard(req)
return
}
// UpdateCard update card.
func (s *Service) UpdateCard(c context.Context, req *model.UpdateCard) (err error) {
var g errgroup.Group
g.Go(func() (err error) {
if req.CardFileType != "" {
if req.CardURL, err = s.dao.Upload(c, "", req.CardFileType, req.CardBody, s.c.Bfs); err != nil {
log.Error("d.Upload iconURL(%+v) error(%v)", req, err)
}
}
return
})
g.Go(func() (err error) {
if req.BigCardFileType != "" {
if req.BigCradURL, err = s.dao.Upload(c, "", req.BigCardFileType, req.BigCardBody, s.c.Bfs); err != nil {
log.Error("d.Upload bigCardURL(%+v) error(%v)", req, err)
}
}
return
})
if err = g.Wait(); err != nil {
return
}
err = s.dao.UpdateCard(req)
return
}
// AddGroup add group.
func (s *Service) AddGroup(c context.Context, req *model.AddGroup) (err error) {
var exist *model.CardGroup
if exist, err = s.dao.GroupByName(req.Name); err != nil {
log.Error("s.dao.GroupByName(%+v) error(%v)", req, err)
return
}
if exist != nil {
return ecode.CardGroupNameExistErr
}
var order int64
if order, err = s.dao.MaxGroupOrder(); err != nil {
return
}
order++
req.OrderNum = order
return s.dao.AddGroup(c, req)
}
// UpdateGroup update group.
func (s *Service) UpdateGroup(c context.Context, req *model.UpdateGroup) error {
return s.dao.UpdateGroup(c, req)
}

View File

@@ -0,0 +1,100 @@
package service
import (
"context"
"flag"
"testing"
"time"
"go-common/app/admin/main/card/conf"
"go-common/app/admin/main/card/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
c = context.TODO()
s *Service
)
func init() {
var (
err error
)
flag.Set("conf", "../cmd/test.toml")
if err = conf.Init(); err != nil {
panic(err)
}
c = context.Background()
if s == nil {
s = New(conf.Conf)
}
time.Sleep(time.Second)
}
// go test -test.v -test.run TestCardsByGid
func TestCardsByGid(t *testing.T) {
Convey("TestCardsByGid ", t, func() {
card, err := s.CardsByGid(c, 2)
t.Logf("v(%v)", card)
So(err, ShouldBeNil)
})
}
func TestUpdateCardState(t *testing.T) {
Convey("TestUpdateCardState ", t, func() {
err := s.UpdateCardState(c, &model.ArgState{ID: 1, State: 1})
So(err, ShouldBeNil)
})
}
func TestDeleteCard(t *testing.T) {
Convey("TestDeleteCard ", t, func() {
err := s.DeleteCard(c, 1)
So(err, ShouldBeNil)
})
}
func TestUpdateGroupState(t *testing.T) {
Convey("TestUpdateGroupState ", t, func() {
err := s.UpdateGroupState(c, &model.ArgState{ID: 2, State: 1})
So(err, ShouldBeNil)
})
}
func TestDeleteGroup(t *testing.T) {
Convey("TestDeleteGroup ", t, func() {
err := s.DeleteGroup(c, 2)
So(err, ShouldBeNil)
})
}
// go test -test.v -test.run TestGroupList
func TestGroupList(t *testing.T) {
Convey("TestGroupList ", t, func() {
card, err := s.GroupList(c, &model.ArgQueryGroup{GroupID: 2})
t.Logf("v(%v)", card)
So(err, ShouldBeNil)
})
}
func TestCardOrderChange(t *testing.T) {
Convey("TestCardOrderChange ", t, func() {
err := s.CardOrderChange(c, &model.ArgIds{Ids: []int64{2, 3}})
So(err, ShouldBeNil)
})
}
func TestGroupOrderChange(t *testing.T) {
Convey("TestGroupOrderChange ", t, func() {
err := s.GroupOrderChange(c, &model.ArgIds{Ids: []int64{1}})
So(err, ShouldBeNil)
})
}
func TestAddGroup(t *testing.T) {
Convey("TestAddGroup ", t, func() {
err := s.AddGroup(c, &model.AddGroup{Name: "test17", State: 0})
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/admin/main/card/conf"
"go-common/app/admin/main/card/dao"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
return s
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}