116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"loveuer/utodo/internal/model"
|
|
"loveuer/utodo/internal/opt"
|
|
"loveuer/utodo/pkg/database/db"
|
|
"loveuer/utodo/pkg/resp"
|
|
"loveuer/utodo/pkg/tool"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
func Login() fiber.Handler {
|
|
return func(c fiber.Ctx) error {
|
|
type Req struct {
|
|
Username string `json:"username"`
|
|
Phone string `json:"phone"`
|
|
Email string `json:"email"`
|
|
Password string `json:"password" validate:"required,min=8"`
|
|
}
|
|
|
|
var (
|
|
err error
|
|
req Req
|
|
op = new(model.User)
|
|
token string
|
|
)
|
|
|
|
if err = c.Bind().JSON(&req); err != nil {
|
|
return resp.R400(c, "", nil, err.Error())
|
|
}
|
|
|
|
tx := db.Default.Session(tool.TimeoutCtx(c.Context(), 5), db.Config{Debug: opt.Cfg.Debug}).
|
|
Model(&model.User{})
|
|
|
|
conds := make([]string, 0)
|
|
|
|
if req.Username != "" {
|
|
conds = append(conds, fmt.Sprintf("username = %q", req.Username))
|
|
}
|
|
|
|
if req.Phone != "" {
|
|
conds = append(conds, fmt.Sprintf("phone = %q", req.Phone))
|
|
}
|
|
|
|
if req.Email != "" {
|
|
conds = append(conds, fmt.Sprintf("email = %q", req.Email))
|
|
}
|
|
|
|
if len(conds) == 0 {
|
|
return resp.R400(c, "", nil, "username, phone or email is required")
|
|
}
|
|
|
|
tx = tx.Where("deleted_at = 0 AND (" + strings.Join(conds, " OR ") + ")")
|
|
|
|
if err = tx.First(op).Error; err != nil {
|
|
return resp.R400(c, "用户信息错误, 登录失败", nil, err.Error())
|
|
}
|
|
|
|
if !tool.ComparePassword(req.Password, op.Password) {
|
|
return resp.R400(c, "用户信息错误, 登录失败", nil, "密码错误")
|
|
}
|
|
|
|
op.LastLoginAt = time.Now().UnixMilli()
|
|
|
|
if err = db.Default.Session(tool.TimeoutCtx(c.Context(), 5)).
|
|
Model(&model.User{}).
|
|
Where("id = ?", op.Id).
|
|
Updates(map[string]any{
|
|
"last_login_at": op.LastLoginAt,
|
|
}).Error; err != nil {
|
|
return resp.R500(c, "登录失败", nil, err.Error())
|
|
}
|
|
|
|
if token, err = model.UserJWT.Generate(op); err != nil {
|
|
return resp.R500(c, "登录失败", nil, err.Error())
|
|
}
|
|
|
|
return resp.R200(c, map[string]any{
|
|
"token": token,
|
|
"user": op,
|
|
})
|
|
}
|
|
}
|
|
|
|
func Verify(key string) fiber.Handler {
|
|
if key == "" {
|
|
key = "Authorization"
|
|
}
|
|
|
|
return func(c fiber.Ctx) error {
|
|
token := c.Get(key)
|
|
|
|
if token == "" {
|
|
return resp.R401(c, "", nil, "token is required")
|
|
}
|
|
|
|
token = strings.TrimPrefix(token, "Bearer ")
|
|
|
|
user, err := model.UserJWT.Parse(token)
|
|
if err != nil {
|
|
return resp.R401(c, "", nil, err.Error())
|
|
}
|
|
|
|
c.Locals("user", user)
|
|
|
|
return resp.R200(c, fiber.Map{
|
|
"user": user,
|
|
"token": token,
|
|
})
|
|
}
|
|
}
|