feat : login
continuous-integration/drone/push Build is passing Details

master
liuhaotian 2022-01-25 17:03:14 +08:00
parent bb95dc0172
commit da57f02191
12 changed files with 277 additions and 3 deletions

View File

@ -9,7 +9,7 @@ import (
"git.icechen.cn/monorepo/backend/pkg/api" "git.icechen.cn/monorepo/backend/pkg/api"
"git.icechen.cn/monorepo/backend/pkg/proto/brahma/murders" "git.icechen.cn/monorepo/backend/pkg/proto/brahma/murders"
"git.icechen.cn/monorepo/backend/pkg/rpc" "git.icechen.cn/monorepo/backend/pkg/rpc"
"github.com/go-playground/validator/v10" validator "github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
ctxLogger "github.com/luizsuper/ctxLoggers" ctxLogger "github.com/luizsuper/ctxLoggers"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -21,8 +21,13 @@ import (
var ( var (
pageIsNotInt = api.WarpFError(errors.New("page 参数错误")) pageIsNotInt = api.WarpFError(errors.New("page 参数错误"))
limitIsNotInt = api.WarpFError(errors.New("limit 参数错误")) limitIsNotInt = api.WarpFError(errors.New("limit 参数错误"))
validate *validator.Validate
) )
func init() {
validate = validator.New()
}
func GetScriptsH(ctx *fiber.Ctx) error { func GetScriptsH(ctx *fiber.Ctx) error {
page := ctx.Query("page", "1") page := ctx.Query("page", "1")
limit := ctx.Query("size", "10") limit := ctx.Query("size", "10")
@ -110,8 +115,6 @@ func GetScriptApi(ctx *fiber.Ctx) error {
return pageIsNotInt return pageIsNotInt
} }
validate := validator.New()
err = validate.Var(p, "gte=0") err = validate.Var(p, "gte=0")
if err != nil { if err != nil {
ctxLogger.Error(ctx.UserContext(), limitIsNotInt.Error(), zap.String("limit", limit)) ctxLogger.Error(ctx.UserContext(), limitIsNotInt.Error(), zap.String("limit", limit))

View File

@ -0,0 +1,50 @@
package handler
import (
"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/service"
"git.icechen.cn/monorepo/backend/pkg/api"
"github.com/gofiber/fiber/v2"
ctxLogger "github.com/luizsuper/ctxLoggers"
"github.com/pkg/errors"
"go.uber.org/zap"
"strconv"
)
var (
idIsNotInt = api.WarpFError(errors.New("类型不是int"))
illegalInt = api.WarpFError(errors.New("非法类型"))
codeIsNull = api.WarpFError(errors.New("传入code为空"))
)
func Login(ctx *fiber.Ctx) error {
code := ctx.Query("code", "")
if code == "" {
ctxLogger.Error(ctx, codeIsNull.Error())
return codeIsNull
}
appType := ctx.Query("type", "")
l, err := strconv.Atoi(appType)
if err != nil {
ctxLogger.Error(ctx, idIsNotInt.Error(), zap.String("appType is ", appType))
return idIsNotInt
}
//目前暂定的appId
err = validate.Var(l, "oneof=1 2 3")
if err != nil {
ctxLogger.Error(ctx, illegalInt.Error(), zap.String("appType is ", appType))
return illegalInt
}
err = service.Login(ctx.UserContext(), code, appType)
if err != nil {
ctxLogger.Error(ctx, "login err", zap.String("reason", err.Error()))
return err
}
return ctx.JSON(success(nil))
}

View File

@ -0,0 +1,11 @@
package model
type Business struct {
address string
point float64
tags string
pictures []string
Uuid string
Phone string
Scripts *[]Scripts `json:"tags,omitempty" gorm:"many2many:business_scripts;foreignKey:Uuid;joinForeignKey:CategoryUid;References:Uuid;JoinReferences:TagUid" valid:"no_empty"`
}

View File

@ -0,0 +1,13 @@
package model
//todo:建立一个公共的model
type Dm struct {
address string
point float64
tags string
pictures []string
Uuid string
Phone string
Scripts *[]Scripts `json:"tags,omitempty" gorm:"many2many:business_scripts;foreignKey:Uuid;joinForeignKey:CategoryUid;References:Uuid;JoinReferences:TagUid" valid:"no_empty"`
}

View File

@ -0,0 +1,4 @@
package model
type model struct {
}

View File

@ -0,0 +1,30 @@
package model
import (
"context"
"git.icechen.cn/monorepo/backend/pkg/orm"
"time"
)
type Token struct {
Tokenid string `json:"tokenid" gorm:"column:tokenid"` // token 唯一id
OpenID string `json:"openId" gorm:"column:openId"`
TypeID string `json:"typeId" gorm:"column:typeId"`
ExpireTime time.Time `json:"expire_time" gorm:"column:expire_time"`
Level int `json:"level" gorm:"column:level"`
}
func (m *Token) TableName() string {
return "token"
}
func NewToken(ctx context.Context, token *Token) error {
db, err := orm.GetContextDB(ctx)
if err != nil {
return err
}
if err = db.Create(token).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,42 @@
package model
import (
"context"
"git.icechen.cn/monorepo/backend/pkg/orm"
)
type User struct {
NickName string `json:"nick_name" gorm:"column:nick_name"` // 用户昵称
AvatarUrl string `json:"avatar_url" gorm:"column:avatar_url"` // 用户头像图片的 URL。URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选0 代表 640x640 的正方形头像46 表示 46x46 的正方形头像剩余数值以此类推。默认132用户没有头像时该项为空。若用户更换头像原有头像 URL 将失效。
Openid string `json:"openid" gorm:"column:openid"` // 用户唯一标识
SessionKey string `json:"session_key" gorm:"column:session_key"` // 会话密钥
Typeid string `json:"typeid" gorm:"column:typeid"` // 某个小程序的唯一id配置文件里面的key
}
func (m *User) TableName() string {
return "user"
}
func GetUserInfo(ctx context.Context, typeId, openId string) (*User, error) {
db, err := orm.GetContextDB(ctx)
if err != nil {
return nil, err
}
i := new(User)
affected := db.First(i, "typeid = ? AND openid = ?", typeId, openId).RowsAffected
if affected == 1 {
return i, nil
}
return nil, nil
}
func NewUser(ctx context.Context, user *User) error {
db, err := orm.GetContextDB(ctx)
if err != nil {
return err
}
if err = db.Create(user).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,26 @@
package service
import (
"context"
"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/model"
"time"
)
func generateToken(ctx context.Context, user *model.User) error {
m := new(model.Token)
m.OpenID = user.Openid
m.TypeID = user.Typeid
m.Level = 1
if user.AvatarUrl == "" {
m.Level = 0
}
m.ExpireTime = time.Now().Add(8 * time.Hour)
err := model.NewToken(ctx, m)
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,81 @@
package service
import (
"context"
"fmt"
"git.icechen.cn/monorepo/backend/app/brahma/api/murder/internal/model"
"git.icechen.cn/monorepo/backend/pkg/config"
"git.icechen.cn/monorepo/backend/pkg/wx"
ctxLogger "github.com/luizsuper/ctxLoggers"
"math/rand"
"strconv"
"time"
)
var appMap = make(map[string]Applet)
func init() {
a := new(AppletConfig)
err := config.GetConfig(a)
if err != nil {
ctxLogger.Error(nil, err.Error())
panic(err)
}
for _, v := range a.Apps {
appMap[v.Type] = v
}
}
type AppletConfig struct {
Apps []Applet `json:"applet"`
}
type Applet struct {
Type string `json:"type"`
Appid string `json:"appid"`
Secret string `json:"secret"`
}
func Login(ctx context.Context, code, appType string) error {
session, err := wx.Code2Session(appMap[appType].Appid, appMap[appType].Secret, code)
if err != nil {
return err
}
i, err := model.GetUserInfo(ctx, appType, session.OpenId)
if err != nil {
return err
}
if i == nil {
i = new(model.User)
i.Openid = session.OpenId
err = Register(ctx, i, true)
if err != nil {
return err
}
}
err = generateToken(ctx, i)
if err != nil {
return err
}
return nil
}
func Register(ctx context.Context, user *model.User, isNew bool) error {
if isNew {
rand.Seed(time.Now().UnixNano())
intn := rand.Intn(2 ^ 1024)
itoa := strconv.Itoa(intn)
user.NickName = fmt.Sprintf("游客%v", itoa)
}
err := model.NewUser(ctx, user)
if err != nil {
return err
}
return nil
}

View File

@ -20,6 +20,7 @@ const (
category = "/category" category = "/category"
scripts = "/scripts" scripts = "/scripts"
script = "/script" script = "/script"
userInfo = "/userInfo"
) )
var ( var (
@ -114,6 +115,10 @@ func routerInit() {
scriptGroup.Get("", func(ctx *fiber.Ctx) error { scriptGroup.Get("", func(ctx *fiber.Ctx) error {
return handler.GetScriptApi(ctx) return handler.GetScriptApi(ctx)
}) })
userGroup := app.Group(userInfo)
userGroup.Get("login", func(ctx *fiber.Ctx) error {
return handler.Login(ctx)
})
} }

View File

@ -0,0 +1 @@
package servesr

View File

@ -0,0 +1,8 @@
package servesr
type Dm struct {
Name string
Age int
}
//多对多的表