Commit be9f8aac by 彭芳

[feat]: add a demo

parent a50dbbe4
GOHOSTOS:=$(shell go env GOHOSTOS)
GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
NAME=demo
ifeq ($(GOHOSTOS), windows)
#the `find.exe` is different from `find` in bash/shell.
......@@ -30,7 +31,7 @@ config:
.PHONY: build
# build
build:
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION) -X main.Name=$(NAME)" -o ./bin/ ./...
.PHONY: generate
# generate
......
......@@ -23,7 +23,7 @@ wire
make run
```
## Docker
## Local Run with Docker
```bash
# build
docker build -t <your-docker-image-name> .
......
......@@ -11,6 +11,7 @@ import (
"demo/internal/conf"
"demo/internal/data"
"demo/internal/router"
"demo/internal/router/mid"
"demo/internal/server"
"demo/internal/service"
"github.com/go-kratos/kratos/v2"
......@@ -25,15 +26,21 @@ import (
// wireApp init kratos application.
func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
common := &mid.Common{}
jwt := &mid.Jwt{}
greeterService := service.NewGreeterService(logger)
dataData, cleanup, err := data.NewData(confData, logger)
if err != nil {
return nil, nil, err
}
greeterRepo := data.NewGreeterRepo(dataData, logger)
greeterUsecase := biz.NewGreeterUsecase(greeterRepo, logger)
greeterService := service.NewGreeterService(greeterUsecase)
campaignRepo := data.NewReportRepo(dataData, logger)
reportUsecase := biz.NewReportUsecase(campaignRepo, logger)
reportService := service.NewReportService(reportUsecase, logger)
web := &router.Web{
Common: common,
Jwt: jwt,
Greeter: greeterService,
Report: reportService,
}
httpServer := server.NewHTTPServer(confServer, web, logger)
app := newApp(logger, httpServer)
......
......@@ -5,4 +5,4 @@ server:
data:
database:
driver: mysql
source: adstest:Ey5M6GowXu!7@tcp(ads-mysql-test.adsdesk.cn:13316)/adsdesk_test1?charset=utf8&parseTime=True&loc=Local
source: adstest:Ey5M6GowXu!7@tcp(ads-mysql-test.adsdesk.cn:13316)/adsdesk_test2?charset=utf8&parseTime=True&loc=Local
......@@ -17,6 +17,7 @@ require (
require (
github.com/gin-contrib/pprof v1.4.0
github.com/gin-gonic/gin v1.8.2
github.com/google/uuid v1.3.0
)
require (
......@@ -32,7 +33,6 @@ require (
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/subcommands v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
......
......@@ -3,4 +3,4 @@ package biz
import "github.com/google/wire"
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewGreeterUsecase)
var ProviderSet = wire.NewSet(NewReportUsecase)
package common
const (
// DefaultPage default page
DefaultPage = 1
// DefaultSize default page size
DefaultSize = 10
)
type PageRequest struct {
Page int `form:"page" json:"page" binding:"required"` // 页码
PageSize int `form:"page_size" json:"page_size" binding:"required"` // 每页大小
OrderBy string // 排序字段
OrderByMode string // 排序方式 desc asc
}
func (p *PageRequest) Offset() int {
return (p.getPage() - 1) * p.getPageSize()
}
func (p *PageRequest) Limit() int {
return p.getPageSize()
}
func (p *PageRequest) GetOrderBy(dft string) string {
if p.OrderBy != "" {
return p.OrderBy
}
return dft
}
func (p *PageRequest) GetOrderByMode() string {
if p.OrderByMode != "" {
return p.OrderByMode
}
return "ASC"
}
func (p *PageRequest) getPage() int {
if p.Page == 0 {
return DefaultPage
}
return p.Page
}
func (p *PageRequest) getPageSize() int {
if p.PageSize == 0 {
return DefaultSize
}
return p.PageSize
}
func (p *PageRequest) getTotalPage(total int64) int64 {
size := p.getPageSize()
if total%int64(size) == 0 {
return total / int64(size)
} else {
return total/int64(size) + 1
}
}
func (p *PageRequest) PageInfo(total int64) *PageInfo {
return &PageInfo{
TotalNumber: total,
PageSize: p.getPageSize(),
Page: p.getPage(),
TotalPage: p.getTotalPage(total),
}
}
type PageInfo struct {
TotalNumber int64 `json:"total_number"` // 数据总数
Page int `json:"page"` // 当前页码
PageSize int `json:"page_size"` // 每页大小
TotalPage int64 `json:"total_page"` // 总页码数
}
package biz
import (
"context"
"github.com/go-kratos/kratos/v2/log"
)
// Greeter is a Greeter model.
type Greeter struct {
Hello string
}
// GreeterRepo is a Greater repo.
type GreeterRepo interface {
Save(context.Context, *Greeter) (*Greeter, error)
Update(context.Context, *Greeter) (*Greeter, error)
FindByID(context.Context, int64) (*Greeter, error)
ListByHello(context.Context, string) ([]*Greeter, error)
ListAll(context.Context) ([]*Greeter, error)
}
// GreeterUsecase is a Greeter usecase.
type GreeterUsecase struct {
repo GreeterRepo
log *log.Helper
}
// NewGreeterUsecase new a Greeter usecase.
func NewGreeterUsecase(repo GreeterRepo, logger log.Logger) *GreeterUsecase {
return &GreeterUsecase{repo: repo, log: log.NewHelper(logger)}
}
// CreateGreeter creates a Greeter, and returns the new Greeter.
func (uc *GreeterUsecase) CreateGreeter(ctx context.Context, g *Greeter) (*Greeter, error) {
uc.log.WithContext(ctx).Infof("CreateGreeter: %v", g.Hello)
return uc.repo.Save(ctx, g)
}
package biz
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"demo/internal/biz/common"
)
type ListCampaignRequest struct {
common.PageRequest
StartDate string `form:"start_date" json:"start_date"` // 开始时间
EndDate string `form:"end_date" json:"end_date"` // 结束时间
}
type ListCampaignResponse struct {
List CampaignList `json:"list"` // 数据信息
PageInfo *common.PageInfo `json:"page_info"` // 页码信息
}
type CampaignList []*Campaign
type Campaign struct {
CampaignId string `json:"campaign_id"` // 广告组ID
CampaignName string `json:"campaign_name"` // 广告主组名称
}
// CampaignRepo is a Report camRepo.
type CampaignRepo interface {
List(ctx context.Context, customerId int64, req *ListCampaignRequest) (int64, CampaignList, error)
}
// ReportUsecase is a Report usecase.
type ReportUsecase struct {
camRepo CampaignRepo
log *log.Helper
}
// NewReportUsecase new a Report usecase.
func NewReportUsecase(repo CampaignRepo, logger log.Logger) *ReportUsecase {
return &ReportUsecase{camRepo: repo, log: log.NewHelper(logger)}
}
// ListCampaignData list campaign data.
func (p *ReportUsecase) ListCampaignData(ctx context.Context, customerId int64, req *ListCampaignRequest) (*ListCampaignResponse, error) {
p.log.WithContext(ctx).Infof("req: %v", req)
// todo 参数校验
total, list, err := p.camRepo.List(ctx, customerId, req)
if err != nil {
return nil, err
}
return &ListCampaignResponse{
List: list,
PageInfo: req.PageInfo(total),
}, nil
}
package data
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"demo/internal/biz"
)
type campaignRepo struct {
data *Data
log *log.Helper
}
func NewReportRepo(data *Data, logger log.Logger) biz.CampaignRepo {
return &campaignRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (p *campaignRepo) List(ctx context.Context, customerId int64, req *biz.ListCampaignRequest) (int64, biz.CampaignList, error) {
var list biz.CampaignList
db := p.data.db.Table("ads_report_campaign_day").
Select("campaign_id, campaign_name").
Where("customer_id = ?", customerId)
var total int64
if err := db.Count(&total).Error; err != nil {
return 0, nil, err
}
if err := db.Limit(req.Limit()).Offset(req.Offset()).Scan(&list).Error; err != nil {
return total, nil, err
}
return total, list, nil
}
......@@ -15,7 +15,7 @@ import (
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewGreeterRepo)
var ProviderSet = wire.NewSet(NewData, NewReportRepo)
// Data .
type Data struct {
......
package data
import (
"context"
"fmt"
"demo/internal/biz"
"github.com/go-kratos/kratos/v2/log"
)
type greeterRepo struct {
data *Data
log *log.Helper
}
// NewGreeterRepo .
func NewGreeterRepo(data *Data, logger log.Logger) biz.GreeterRepo {
return &greeterRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (r *greeterRepo) Save(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
var s []int64
if err := r.data.db.Table("ads_media_account").
Where("media_code =? ", "qianchuan").
Pluck("advertiser_id", &s).Error; err != nil {
r.log.Info("select err:", err)
}
g.Hello = fmt.Sprint(g.Hello, " advertiser_id list: ", s)
return g, nil
}
func (r *greeterRepo) Update(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
return g, nil
}
func (r *greeterRepo) FindByID(context.Context, int64) (*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListByHello(context.Context, string) ([]*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListAll(context.Context) ([]*biz.Greeter, error) {
return nil, nil
}
package mid
import (
"net/http"
"github.com/gin-gonic/gin"
"demo/internal/util"
)
type Jwt struct {
}
func (p *Jwt) CheckToken(c *gin.Context) {
headerToken := c.Request.Header.Get(util.Token)
if util.DefaultToken != headerToken {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
util.RequestKey: c.GetString(util.RequestKey),
"code": http.StatusUnauthorized,
"message": "token 校验失败",
})
return
}
c.Set(util.CustomerId, util.DefaultCustomerId)
c.Next()
}
package mid
import (
"fmt"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"demo/internal/util"
)
type Common struct {
}
// SetRequestId 设置接口的request_id
func (p *Common) SetRequestId(c *gin.Context) {
reqId := strings.Replace(uuid.New().String(), "-", "", -1)
now := time.Now().Format("20060102150405")
c.Set(util.RequestKey, fmt.Sprintf("%s%s", now, reqId))
}
// PassMethods 过滤所有的Options, Head Method Requests
func (p *Common) PassMethods(c *gin.Context) {
if c.Request.Method == "OPTIONS" || c.Request.Method == "HEAD" {
c.AbortWithStatusJSON(200, gin.H{"success": "success"})
return
}
}
package mid
import "github.com/google/wire"
// ProviderSet is mid providers.
var ProviderSet = wire.NewSet(
wire.Struct(new(Common), "*"),
wire.Struct(new(Jwt), "*"),
)
......@@ -2,9 +2,12 @@ package router
import (
"github.com/google/wire"
"demo/internal/router/mid"
)
// ProviderSet is router providers.
var ProviderSet = wire.NewSet(
wire.Struct(new(Web), "*"),
mid.ProviderSet,
)
......@@ -6,14 +6,19 @@ import (
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
"demo/internal/router/mid"
"demo/internal/service"
)
type Web struct {
Common *mid.Common
Jwt *mid.Jwt
Greeter *service.GreeterService
Report *service.ReportService
}
func (p *Web) RouterInit(engine *gin.Engine) {
engine.Use(p.Common.SetRequestId, p.Common.PassMethods)
engine.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{"code": "404", "msg": "PageNo not found"})
})
......@@ -21,5 +26,9 @@ func (p *Web) RouterInit(engine *gin.Engine) {
// eg: go tool pprof http://localhost:8000/api/pprof/profile
pprof.Register(engine, "/api/pprof")
// add api
engine.GET("/helloworld/:name", p.Greeter.SayHello)
engine.GET("/hello/:name", p.Greeter.SayHello)
api := engine.Group("/api", p.Jwt.CheckToken)
{
api.POST("/report", p.Report.ListCampaignData)
}
}
package service
import (
"net/http"
"github.com/gin-gonic/gin"
"demo/internal/util"
)
// ResponseError 公共返回错误处理
func ResponseError(c *gin.Context, err error) {
c.AbortWithStatusJSON(http.StatusOK, gin.H{
util.RequestKey: c.GetString(util.RequestKey),
"code": http.StatusInternalServerError,
"message": err.Error(),
})
}
// ResponseSuccess 返回成功参数
func ResponseSuccess(c *gin.Context, result ...interface{}) {
if len(result) > 0 {
c.JSON(http.StatusOK, gin.H{
util.RequestKey: c.GetString(util.RequestKey),
"code": http.StatusOK,
"message": util.StatusOK,
"data": result[0],
})
} else {
c.JSON(http.StatusOK, gin.H{
util.RequestKey: c.GetString(util.RequestKey),
"code": http.StatusOK,
"message": util.StatusOK,
})
}
}
......@@ -2,32 +2,25 @@ package service
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"demo/internal/biz"
"github.com/go-kratos/kratos/v2/log"
)
// GreeterService is a greeter service.
type GreeterService struct {
uc *biz.GreeterUsecase
log *log.Helper
}
// NewGreeterService new a greeter service.
func NewGreeterService(uc *biz.GreeterUsecase) *GreeterService {
return &GreeterService{uc: uc}
func NewGreeterService(logger log.Logger) *GreeterService {
return &GreeterService{log: log.NewHelper(logger)}
}
// SayHello implements helloworld.GreeterServer.
// SayHello say hello
func (s *GreeterService) SayHello(ctx *gin.Context) {
name := ctx.Param("name")
g, err := s.uc.CreateGreeter(ctx, &biz.Greeter{Hello: name})
if err != nil {
return
}
ctx.AbortWithStatusJSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("hello %s", g.Hello),
})
s.log.Info("request Param:", name)
ResponseSuccess(ctx, fmt.Sprintf("hello %s", name))
return
}
package service
import (
"github.com/gin-gonic/gin"
"github.com/go-kratos/kratos/v2/log"
"demo/internal/biz"
"demo/internal/util"
)
type ReportService struct {
uc *biz.ReportUsecase
log *log.Helper
}
// NewReportService new a report service.
func NewReportService(uc *biz.ReportUsecase, logger log.Logger) *ReportService {
return &ReportService{uc: uc, log: log.NewHelper(logger)}
}
// ListCampaignData 查询广告组数据报表
func (p *ReportService) ListCampaignData(ctx *gin.Context) {
var req biz.ListCampaignRequest
if err := ctx.ShouldBind(&req); err != nil {
ResponseError(ctx, err)
return
}
customerId := ctx.GetInt64(util.CustomerId)
data, err := p.uc.ListCampaignData(ctx, customerId, &req)
if err != nil {
ResponseError(ctx, err)
return
}
ResponseSuccess(ctx, data)
}
......@@ -3,4 +3,4 @@ package service
import "github.com/google/wire"
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewGreeterService)
var ProviderSet = wire.NewSet(NewGreeterService, NewReportService)
package util
const (
RequestKey = "request_id"
Token = "token"
DefaultToken = "44444"
CustomerId = "customer_id"
DefaultCustomerId = "10025"
StatusOK = "ok"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment