- 添加用户认证模块 (JWT + 密码管理) - 添加 ChatGPT 账户管理功能 - 添加卡密管理功能 (创建、批量生成、查询) - 添加邀请功能 - 配置数据库迁移和路由系统
139 lines
3.1 KiB
Go
139 lines
3.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"gpt-manager-go/internal/auth"
|
|
"gpt-manager-go/internal/repository"
|
|
)
|
|
|
|
// AuthHandler 认证处理器
|
|
type AuthHandler struct {
|
|
adminRepo *repository.AdminRepository
|
|
}
|
|
|
|
// NewAuthHandler 创建认证处理器
|
|
func NewAuthHandler(adminRepo *repository.AdminRepository) *AuthHandler {
|
|
return &AuthHandler{adminRepo: adminRepo}
|
|
}
|
|
|
|
// LoginRequest 登录请求
|
|
type LoginRequest struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
// LoginResponse 登录响应
|
|
type LoginResponse struct {
|
|
Success bool `json:"success"`
|
|
Message string `json:"message"`
|
|
Token string `json:"token,omitempty"`
|
|
User *UserInfo `json:"user,omitempty"`
|
|
}
|
|
|
|
// UserInfo 用户信息
|
|
type UserInfo struct {
|
|
ID int `json:"id"`
|
|
Username string `json:"username"`
|
|
Email string `json:"email"`
|
|
IsSuperAdmin bool `json:"is_super_admin"`
|
|
}
|
|
|
|
// Login 登录接口
|
|
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
respondJSON(w, http.StatusMethodNotAllowed, LoginResponse{
|
|
Success: false,
|
|
Message: "Method not allowed",
|
|
})
|
|
return
|
|
}
|
|
|
|
var req LoginRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
respondJSON(w, http.StatusBadRequest, LoginResponse{
|
|
Success: false,
|
|
Message: "Invalid request body",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 验证必填字段
|
|
if req.Username == "" || req.Password == "" {
|
|
respondJSON(w, http.StatusBadRequest, LoginResponse{
|
|
Success: false,
|
|
Message: "Username and password are required",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 查找用户
|
|
admin, err := h.adminRepo.FindByUsername(req.Username)
|
|
if err != nil {
|
|
respondJSON(w, http.StatusInternalServerError, LoginResponse{
|
|
Success: false,
|
|
Message: "Internal server error",
|
|
})
|
|
return
|
|
}
|
|
|
|
if admin == nil {
|
|
respondJSON(w, http.StatusUnauthorized, LoginResponse{
|
|
Success: false,
|
|
Message: "Invalid username or password",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 检查账号是否激活
|
|
if !admin.IsActive {
|
|
respondJSON(w, http.StatusForbidden, LoginResponse{
|
|
Success: false,
|
|
Message: "Account is disabled",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 验证密码
|
|
if !auth.CheckPassword(req.Password, admin.PasswordHash) {
|
|
respondJSON(w, http.StatusUnauthorized, LoginResponse{
|
|
Success: false,
|
|
Message: "Invalid username or password",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 生成 Token
|
|
token, err := auth.GenerateToken(admin.ID, admin.Username, admin.IsSuperAdmin)
|
|
if err != nil {
|
|
respondJSON(w, http.StatusInternalServerError, LoginResponse{
|
|
Success: false,
|
|
Message: "Failed to generate token",
|
|
})
|
|
return
|
|
}
|
|
|
|
// 更新最后登录时间
|
|
_ = h.adminRepo.UpdateLastLogin(admin.ID)
|
|
|
|
respondJSON(w, http.StatusOK, LoginResponse{
|
|
Success: true,
|
|
Message: "Login successful",
|
|
Token: token,
|
|
User: &UserInfo{
|
|
ID: admin.ID,
|
|
Username: admin.Username,
|
|
Email: admin.Email,
|
|
IsSuperAdmin: admin.IsSuperAdmin,
|
|
},
|
|
})
|
|
}
|
|
|
|
// respondJSON 返回 JSON 响应
|
|
func respondJSON(w http.ResponseWriter, status int, data interface{}) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(status)
|
|
json.NewEncoder(w).Encode(data)
|
|
}
|