149 lines
3.7 KiB
Go
149 lines
3.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/inchstep/server/internal/middleware"
|
|
"github.com/inchstep/server/internal/services"
|
|
)
|
|
|
|
type UserHandler struct {
|
|
userSvc *services.UserService
|
|
jwtSecret string
|
|
}
|
|
|
|
func NewUserHandler(userSvc *services.UserService, jwtSecret string) *UserHandler {
|
|
return &UserHandler{userSvc: userSvc, jwtSecret: jwtSecret}
|
|
}
|
|
|
|
type registerReq struct {
|
|
Phone string `json:"phone" binding:"required,len=11"`
|
|
}
|
|
|
|
func (h *UserHandler) Register(c *gin.Context) {
|
|
var req registerReq
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
middleware.Error(c, http.StatusBadRequest, 400, "手机号格式错误")
|
|
return
|
|
}
|
|
|
|
user, err := h.userSvc.RegisterByPhone(req.Phone)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusConflict, 409, err.Error())
|
|
return
|
|
}
|
|
|
|
token, _ := middleware.GenerateToken(user.ID, h.jwtSecret)
|
|
middleware.Success(c, gin.H{
|
|
"user": user,
|
|
"token": token,
|
|
})
|
|
}
|
|
|
|
type loginReq struct {
|
|
Phone string `json:"phone" binding:"required,len=11"`
|
|
}
|
|
|
|
func (h *UserHandler) Login(c *gin.Context) {
|
|
var req loginReq
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
middleware.Error(c, http.StatusBadRequest, 400, "手机号格式错误")
|
|
return
|
|
}
|
|
|
|
user, err := h.userSvc.GetByPhone(req.Phone)
|
|
if err != nil {
|
|
// 手机号未注册时自动注册
|
|
user, err = h.userSvc.RegisterByPhone(req.Phone)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusInternalServerError, 500, "注册失败")
|
|
return
|
|
}
|
|
}
|
|
|
|
token, _ := middleware.GenerateToken(user.ID, h.jwtSecret)
|
|
middleware.Success(c, gin.H{
|
|
"user": user,
|
|
"token": token,
|
|
})
|
|
}
|
|
|
|
func (h *UserHandler) GetProfile(c *gin.Context) {
|
|
userID := middleware.GetUserID(c)
|
|
user, err := h.userSvc.GetByID(userID)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusNotFound, 404, "用户不存在")
|
|
return
|
|
}
|
|
middleware.Success(c, user)
|
|
}
|
|
|
|
func (h *UserHandler) UpdateProfile(c *gin.Context) {
|
|
userID := middleware.GetUserID(c)
|
|
var updates map[string]interface{}
|
|
if err := c.ShouldBindJSON(&updates); err != nil {
|
|
middleware.Error(c, http.StatusBadRequest, 400, "请求数据格式错误")
|
|
return
|
|
}
|
|
|
|
user, err := h.userSvc.UpdateProfile(userID, updates)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusInternalServerError, 500, err.Error())
|
|
return
|
|
}
|
|
middleware.Success(c, user)
|
|
}
|
|
|
|
func (h *UserHandler) DeleteAccount(c *gin.Context) {
|
|
userID := middleware.GetUserID(c)
|
|
if err := h.userSvc.DeleteAccount(userID); err != nil {
|
|
middleware.Error(c, http.StatusInternalServerError, 500, "注销失败")
|
|
return
|
|
}
|
|
middleware.Success(c, nil)
|
|
}
|
|
|
|
func (h *UserHandler) GetPoints(c *gin.Context) {
|
|
userID := middleware.GetUserID(c)
|
|
user, err := h.userSvc.GetByID(userID)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusNotFound, 404, "用户不存在")
|
|
return
|
|
}
|
|
middleware.Success(c, gin.H{"points": user.Points})
|
|
}
|
|
|
|
// ========== 排行榜 ==========
|
|
|
|
func (h *UserHandler) GetLeaderboard(c *gin.Context) {
|
|
limitStr := c.DefaultQuery("limit", "20")
|
|
limit, err := strconv.Atoi(limitStr)
|
|
if err != nil || limit > 100 {
|
|
limit = 20
|
|
}
|
|
entries, err := h.userSvc.GetLeaderboardByPoints(limit)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusInternalServerError, 500, err.Error())
|
|
return
|
|
}
|
|
middleware.Success(c, entries)
|
|
}
|
|
|
|
// ========== 搜索用户 ==========
|
|
|
|
func (h *UserHandler) SearchUsers(c *gin.Context) {
|
|
q := c.Query("q")
|
|
if q == "" {
|
|
middleware.Success(c, []interface{}{})
|
|
return
|
|
}
|
|
users, err := h.userSvc.SearchUsers(q, 20)
|
|
if err != nil {
|
|
middleware.Error(c, http.StatusInternalServerError, 500, err.Error())
|
|
return
|
|
}
|
|
middleware.Success(c, users)
|
|
}
|