feat: register

v3
veypi 4 months ago
parent 807d1d5e93
commit 46a0f2f0fb

@ -16,7 +16,7 @@ build:
@go build -o ./build/oa @go build -o ./build/oa
fmt: fmt:
@goctl api format --dir ./api @goctl api format --dir ./protoc/api/
gen_sql: gen_sql:
@goctl model mysql ddl --database oa -d ./models -s ./protoc/sql/20240801061157_base.sql @goctl model mysql ddl --database oa -d ./models -s ./protoc/sql/20240801061157_base.sql
@ -31,7 +31,17 @@ gen_db:
@sqlx migrate --source ./protoc/sql run -D $(db) @sqlx migrate --source ./protoc/sql run -D $(db)
gen_api: gen_api:
@goctl api format --dir ./protoc/api/
@goctl api go -api ./protoc/api/all.api -dir ./ @goctl api go -api ./protoc/api/all.api -dir ./
ts_dir= ../oaweb/composables/api/
gen_ts:
@goctl api ts -api ./protoc/api/user.api -dir $(ts_dir)
@mv $(ts_dir)/main.ts $(ts_dir)/user.ts
@goctl api ts -api ./protoc/api/app.api -dir $(ts_dir)
@mv $(ts_dir)/main.ts $(ts_dir)/app.ts
@goctl api ts -api ./protoc/api/all.api -dir $(ts_dir)
@rm $(ts_dir)/main.ts
run: run:
@go run main.go -f ./etc/main.yaml @go run main.go -f ./etc/main.yaml

@ -35,5 +35,7 @@ var (
AuthFailed = New(401, "auth failed") AuthFailed = New(401, "auth failed")
AuthExpired = New(401, "auth expired") AuthExpired = New(401, "auth expired")
AuthInvalid = New(401, "auth invalid") AuthInvalid = New(401, "auth invalid")
ArgsInvalid = New(http.StatusUnprocessableEntity, "args invalid") ArgsInvalid = New(http.StatusBadRequest, "args invalid")
UserNotFound = New(400, "user not found")
UserPwdInvalid = New(400, "password invalid")
) )

@ -11,6 +11,7 @@ import (
"net/http" "net/http"
"github.com/go-sql-driver/mysql" "github.com/go-sql-driver/mysql"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx" "github.com/zeromicro/go-zero/rest/httpx"
) )
@ -23,7 +24,8 @@ func Response(w http.ResponseWriter, resp interface{}, err error) {
code = e.Code code = e.Code
msg = e.Msg msg = e.Msg
case *mysql.MySQLError: case *mysql.MySQLError:
code = http.StatusUnprocessableEntity logx.Info(e.Error())
code = http.StatusBadRequest
msg = e.Message msg = e.Message
} }
w.WriteHeader(code) w.WriteHeader(code)

@ -5,4 +5,5 @@ import "github.com/zeromicro/go-zero/rest"
type Config struct { type Config struct {
rest.RestConf rest.RestConf
DB string DB string
UUID string
} }

@ -16,7 +16,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
[]rest.Route{ []rest.Route{
{ {
Method: http.MethodPost, Method: http.MethodPost,
Path: "/login", Path: "/login/:pa",
Handler: app.LoginHandler(serverCtx), Handler: app.LoginHandler(serverCtx),
}, },
}, },
@ -25,16 +25,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes( server.AddRoutes(
[]rest.Route{ []rest.Route{
{
Method: http.MethodHead,
Path: "/",
Handler: user.LoginHandler(serverCtx),
},
{ {
Method: http.MethodPost, Method: http.MethodPost,
Path: "/", Path: "/",
Handler: user.RegHandler(serverCtx), Handler: user.RegHandler(serverCtx),
}, },
{
Method: http.MethodHead,
Path: "/:id",
Handler: user.LoginHandler(serverCtx),
},
}, },
rest.WithPrefix("/api/user"), rest.WithPrefix("/api/user"),
) )

@ -20,7 +20,7 @@ func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
} }
l := user.NewLoginLogic(r.Context(), svcCtx) l := user.NewLoginLogic(r.Context(), svcCtx)
err := l.Login(&req) _, err := l.Login(&req)
errs.Response(w, nil, err) errs.Response(w, nil, err)
} }
} }

@ -2,10 +2,17 @@ package user
import ( import (
"context" "context"
"database/sql"
"strings"
"time"
"oa/errs"
"oa/internal/svc" "oa/internal/svc"
"oa/internal/types" "oa/internal/types"
"oa/models"
"github.com/google/uuid"
"github.com/veypi/utils"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -23,8 +30,34 @@ func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic
} }
} }
func (l *LoginLogic) Login(req *types.LoginReq) error { func (l *LoginLogic) Login(req *types.LoginReq) (string, error) {
// todo: add your logic here and delete this line // todo: add your logic here and delete this line
m := models.NewUserModel(l.svcCtx.Sqlx())
var u *models.User
var err error
switch req.Typ {
case "email":
u, err = m.FindOneByEmail(l.ctx, sql.NullString{String: req.Id, Valid: true})
case "phone":
u, err = m.FindOneByPhone(l.ctx, sql.NullString{String: req.Id, Valid: true})
default:
u, err = m.FindOneByUsername(l.ctx, req.Id)
}
if err != nil {
return "", errs.UserNotFound.WithErr(err)
}
temp, err := utils.AesDecrypt(u.CheckCode, []byte(req.Pwd))
if err != nil || temp != u.RealCode {
return "", errs.UserPwdInvalid
}
t := models.Token{
Code: strings.ReplaceAll(uuid.New().String(), "-", ""),
Expired: time.Now().Add(time.Hour * 24),
ClientId: req.Client,
AppId: l.svcCtx.Config.UUID,
UserId: u.Id,
}
_, err = models.NewTokenModel(l.svcCtx.Sqlx()).Insert(l.ctx, &t)
return nil return "", err
} }

@ -4,6 +4,8 @@ package types
type AppReq struct { type AppReq struct {
Appname string `json:"username"` Appname string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
Pas string `query:"pas"`
Pa string `path:"pa"`
} }
type AppResp struct { type AppResp struct {
@ -14,9 +16,10 @@ type AppResp struct {
} }
type LoginReq struct { type LoginReq struct {
Id string `json:"id"` Id string `path:"id"`
Code string `json:"code"` Client string `json:"client"`
Verify string `json:"verify"` Pwd string `json:"pwd"`
Typ string `json:"typ,optional"`
} }
type RegReq struct { type RegReq struct {

@ -42,7 +42,7 @@ type (
ClientId string `db:"client_id"` ClientId string `db:"client_id"`
AppId string `db:"app_id"` AppId string `db:"app_id"`
UserId string `db:"user_id"` UserId string `db:"user_id"`
Meta sql.NullString `db:"meta"` Meta string `db:"meta"`
} }
) )

@ -25,6 +25,8 @@ type (
userModel interface { userModel interface {
Insert(ctx context.Context, data *User) (sql.Result, error) Insert(ctx context.Context, data *User) (sql.Result, error)
FindOne(ctx context.Context, id string) (*User, error) FindOne(ctx context.Context, id string) (*User, error)
FindOneByEmail(ctx context.Context, email sql.NullString) (*User, error)
FindOneByPhone(ctx context.Context, phone sql.NullString) (*User, error)
FindOneByUsername(ctx context.Context, username string) (*User, error) FindOneByUsername(ctx context.Context, username string) (*User, error)
Update(ctx context.Context, data *User) error Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id string) error Delete(ctx context.Context, id string) error
@ -41,8 +43,8 @@ type (
Updated time.Time `db:"updated"` Updated time.Time `db:"updated"`
Username string `db:"username"` Username string `db:"username"`
Nickname string `db:"nickname"` Nickname string `db:"nickname"`
Email string `db:"email"` Email sql.NullString `db:"email"`
Phone string `db:"phone"` Phone sql.NullString `db:"phone"`
Icon string `db:"icon"` Icon string `db:"icon"`
RealCode string `db:"_real_code"` RealCode string `db:"_real_code"`
CheckCode string `db:"_check_code"` CheckCode string `db:"_check_code"`
@ -79,6 +81,34 @@ func (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error
} }
} }
func (m *defaultUserModel) FindOneByEmail(ctx context.Context, email sql.NullString) (*User, error) {
var resp User
query := fmt.Sprintf("select %s from %s where `email` = ? limit 1", userRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, email)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserModel) FindOneByPhone(ctx context.Context, phone sql.NullString) (*User, error) {
var resp User
query := fmt.Sprintf("select %s from %s where `phone` = ? limit 1", userRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, phone)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserModel) FindOneByUsername(ctx context.Context, username string) (*User, error) { func (m *defaultUserModel) FindOneByUsername(ctx context.Context, username string) (*User, error) {
var resp User var resp User
query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", userRows, m.table) query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", userRows, m.table)

@ -1,14 +1,15 @@
import "base.api" import "base.api"
type ( type (
// 定义登录接口的请求体 // 定义登录接口的请求体
AppReq { AppReq {
appname string `json:"username"` appname string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
Pas string `query:"pas"`
Pa string `path:"pa"`
} }
// 定义登录接口的响应体 // 定义登录接口的响应体
AppResp{ AppResp {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Token string `json:"token"` Token string `json:"token"`
@ -22,8 +23,6 @@ type (
// 定义路由前缀为 "/v1" // 定义路由前缀为 "/v1"
prefix: /api/app prefix: /api/app
) )
// 定义 HTTP 服务 // 定义 HTTP 服务
// 微服务名称为 main生成的代码目录和配置文件将和 user 值相关 // 微服务名称为 main生成的代码目录和配置文件将和 user 值相关
service main { service main {
@ -34,5 +33,6 @@ service main {
// 路由为 /app/login // 路由为 /app/login
// 请求体为 LoginReq // 请求体为 LoginReq
// 响应体为 LoginResp响应体必须有 returns 关键字修饰 // 响应体为 LoginResp响应体必须有 returns 关键字修饰
post /login (AppReq) returns (AppResp) post /login/:pa (AppReq) returns (AppResp)
} }

@ -1,4 +1,4 @@
type auth { type auth {
Authorization string `header:"authorization"` Authorization string `header:"authorization"`
} }

@ -1,17 +1,16 @@
import "base.api" import "base.api"
type ( type (
LoginReq { LoginReq {
id string `json:"id"` id string `path:"id"`
code string `json:"code"` client string `json:"client"`
verify string `json:"verify"` pwd string `json:"pwd"`
typ string `json:"typ,optional"`
} }
RegReq { RegReq {
username string `json:"username"` username string `json:"username"`
pwd string `json:"pwd"` pwd string `json:"pwd"`
} }
getReq { getReq {
Id int64 `path:"id"` Id int64 `path:"id"`
} }
@ -37,22 +36,19 @@ type (
group: user group: user
prefix: /api/user prefix: /api/user
) )
service main { service main {
@handler Login @handler Login
head / (LoginReq) returns () head /:id (LoginReq)
@handler Reg @handler Reg
post / (RegReq) returns () post / (RegReq)
} }
@server ( @server (
group: user group: user
middleware: Auth middleware: Auth
prefix: /api/user prefix: /api/user
) )
service main { service main {
@handler get @handler get
get /:id (getReq) returns (userResp) get /:id (getReq) returns (userResp)
@ -60,3 +56,4 @@ service main {
@handler list @handler list
get / (listReq) returns ([]userResp) get / (listReq) returns ([]userResp)
} }

@ -6,8 +6,8 @@ CREATE TABLE IF NOT EXISTS `user`
`username` varchar(255) NOT NULL UNIQUE, `username` varchar(255) NOT NULL UNIQUE,
`nickname` varchar(255) NOT NULL, `nickname` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL, `email` varchar(255) UNIQUE,
`phone` varchar(255) NOT NULL, `phone` varchar(255) UNIQUE,
`icon` varchar(255) NOT NULL DEFAULT "", `icon` varchar(255) NOT NULL DEFAULT "",
`_real_code` varchar(32) NOT NULL, `_real_code` varchar(32) NOT NULL,
`_check_code` varchar(64) NOT NULL, `_check_code` varchar(64) NOT NULL,
@ -127,7 +127,7 @@ CREATE TABLE IF NOT EXISTS `token`
`client_id` varchar(32) NOT NULL, `client_id` varchar(32) NOT NULL,
`app_id` varchar(32) NOT NULL, `app_id` varchar(32) NOT NULL,
`user_id` varchar(32) NOT NULL, `user_id` varchar(32) NOT NULL,
`meta` json, `meta` json NOT NULL,
PRIMARY KEY (`code`) PRIMARY KEY (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Loading…
Cancel
Save