feat: register

v3
veypi 4 months ago
parent 807d1d5e93
commit 46a0f2f0fb

@ -16,7 +16,7 @@ build:
@go build -o ./build/oa
fmt:
@goctl api format --dir ./api
@goctl api format --dir ./protoc/api/
gen_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)
gen_api:
@goctl api format --dir ./protoc/api/
@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:
@go run main.go -f ./etc/main.yaml

@ -32,8 +32,10 @@ func New(code int, msg string) *CodeErr {
}
var (
AuthFailed = New(401, "auth failed")
AuthExpired = New(401, "auth expired")
AuthInvalid = New(401, "auth invalid")
ArgsInvalid = New(http.StatusUnprocessableEntity, "args invalid")
AuthFailed = New(401, "auth failed")
AuthExpired = New(401, "auth expired")
AuthInvalid = New(401, "auth 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"
"github.com/go-sql-driver/mysql"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
)
@ -23,7 +24,8 @@ func Response(w http.ResponseWriter, resp interface{}, err error) {
code = e.Code
msg = e.Msg
case *mysql.MySQLError:
code = http.StatusUnprocessableEntity
logx.Info(e.Error())
code = http.StatusBadRequest
msg = e.Message
}
w.WriteHeader(code)

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

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

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

@ -2,10 +2,17 @@ package user
import (
"context"
"database/sql"
"strings"
"time"
"oa/errs"
"oa/internal/svc"
"oa/internal/types"
"oa/models"
"github.com/google/uuid"
"github.com/veypi/utils"
"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
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 {
Appname string `json:"username"`
Password string `json:"password"`
Pas string `query:"pas"`
Pa string `path:"pa"`
}
type AppResp struct {
@ -14,9 +16,10 @@ type AppResp struct {
}
type LoginReq struct {
Id string `json:"id"`
Code string `json:"code"`
Verify string `json:"verify"`
Id string `path:"id"`
Client string `json:"client"`
Pwd string `json:"pwd"`
Typ string `json:"typ,optional"`
}
type RegReq struct {

@ -35,14 +35,14 @@ type (
}
Token struct {
Code string `db:"code"`
Created time.Time `db:"created"`
Updated time.Time `db:"updated"`
Expired time.Time `db:"expired"`
ClientId string `db:"client_id"`
AppId string `db:"app_id"`
UserId string `db:"user_id"`
Meta sql.NullString `db:"meta"`
Code string `db:"code"`
Created time.Time `db:"created"`
Updated time.Time `db:"updated"`
Expired time.Time `db:"expired"`
ClientId string `db:"client_id"`
AppId string `db:"app_id"`
UserId string `db:"user_id"`
Meta string `db:"meta"`
}
)

@ -25,6 +25,8 @@ type (
userModel interface {
Insert(ctx context.Context, data *User) (sql.Result, 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)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id string) error
@ -36,19 +38,19 @@ type (
}
User struct {
Id string `db:"id"` // User UUID
Created time.Time `db:"created"`
Updated time.Time `db:"updated"`
Username string `db:"username"`
Nickname string `db:"nickname"`
Email string `db:"email"`
Phone string `db:"phone"`
Icon string `db:"icon"`
RealCode string `db:"_real_code"`
CheckCode string `db:"_check_code"`
Status int64 `db:"status"` // 状态0ok1disabled
Used int64 `db:"used"`
Space int64 `db:"space"`
Id string `db:"id"` // User UUID
Created time.Time `db:"created"`
Updated time.Time `db:"updated"`
Username string `db:"username"`
Nickname string `db:"nickname"`
Email sql.NullString `db:"email"`
Phone sql.NullString `db:"phone"`
Icon string `db:"icon"`
RealCode string `db:"_real_code"`
CheckCode string `db:"_check_code"`
Status int64 `db:"status"` // 状态0ok1disabled
Used int64 `db:"used"`
Space int64 `db:"space"`
}
)
@ -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) {
var resp User
query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", userRows, m.table)

@ -1,38 +1,38 @@
import "base.api"
type (
// 定义登录接口的请求体
AppReq {
appname string `json:"username"`
Password string `json:"password"`
}
// 定义登录接口的响应体
AppResp{
Id int64 `json:"id"`
Name string `json:"name"`
Token string `json:"token"`
ExpireAt string `json:"expireAt"`
}
// 定义登录接口的请求体
AppReq {
appname string `json:"username"`
Password string `json:"password"`
Pas string `query:"pas"`
Pa string `path:"pa"`
}
// 定义登录接口的响应体
AppResp {
Id int64 `json:"id"`
Name string `json:"name"`
Token string `json:"token"`
ExpireAt string `json:"expireAt"`
}
)
@server (
// 代表当前 service 代码块下的路由生成代码时都会被放到 app 目录下
group: app
// 定义路由前缀为 "/v1"
prefix: /api/app
// 代表当前 service 代码块下的路由生成代码时都会被放到 app 目录下
group: app
// 定义路由前缀为 "/v1"
prefix: /api/app
)
// 定义 HTTP 服务
// 微服务名称为 main生成的代码目录和配置文件将和 user 值相关
service main {
// 定义 http.HandleFunc 转换的 go 文件名称及方法
@handler Login
// 定义接口
// 请求方法为 post
// 路由为 /app/login
// 请求体为 LoginReq
// 响应体为 LoginResp响应体必须有 returns 关键字修饰
post /login (AppReq) returns (AppResp)
service main {
// 定义 http.HandleFunc 转换的 go 文件名称及方法
@handler Login
// 定义接口
// 请求方法为 post
// 路由为 /app/login
// 请求体为 LoginReq
// 响应体为 LoginResp响应体必须有 returns 关键字修饰
post /login/:pa (AppReq) returns (AppResp)
}

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

@ -1,62 +1,59 @@
import "base.api"
type (
LoginReq {
id string `json:"id"`
code string `json:"code"`
verify string `json:"verify"`
}
RegReq {
username string `json:"username"`
pwd string `json:"pwd"`
}
getReq {
Id int64 `path:"id"`
}
listReq {
Username string `query:"username"`
}
userResp {
Id string `json:"id"`
Created uint `json:"created"`
Updated uint `json:"updated"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Phone string `json:"phone"`
Icon string `json:"icon"`
Status int64 `json:"status"` // 状态0ok1disabled
Used int64 `json:"used"`
Space int64 `json:"space"`
}
LoginReq {
id string `path:"id"`
client string `json:"client"`
pwd string `json:"pwd"`
typ string `json:"typ,optional"`
}
RegReq {
username string `json:"username"`
pwd string `json:"pwd"`
}
getReq {
Id int64 `path:"id"`
}
listReq {
Username string `query:"username"`
}
userResp {
Id string `json:"id"`
Created uint `json:"created"`
Updated uint `json:"updated"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Phone string `json:"phone"`
Icon string `json:"icon"`
Status int64 `json:"status"` // 状态0ok1disabled
Used int64 `json:"used"`
Space int64 `json:"space"`
}
)
@server (
group: user
prefix: /api/user
group: user
prefix: /api/user
)
service main {
@handler Login
head / (LoginReq) returns ()
@handler Login
head /:id (LoginReq)
@handler Reg
post / (RegReq) returns ()
@handler Reg
post / (RegReq)
}
@server (
group: user
middleware: Auth
prefix: /api/user
group: user
middleware: Auth
prefix: /api/user
)
service main {
@handler get
get /:id (getReq) returns (userResp)
@handler get
get /:id (getReq) returns (userResp)
@handler list
get / (listReq) returns ([]userResp)
@handler list
get / (listReq) returns ([]userResp)
}

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

Loading…
Cancel
Save