LicenseManger/internal/api/user.go

425 lines
9.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package api
import (
"licserver/internal/service"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
type UserHandler struct {
userService *service.UserService
}
func NewUserHandler(userService *service.UserService) *UserHandler {
return &UserHandler{userService: userService}
}
func (h *UserHandler) Login(c *gin.Context) {
var input struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Captcha string `json:"captcha" binding:"required"`
CaptchaId string `json:"captchaId" binding:"required"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 验证验证码
if !h.userService.GetCaptchaService().VerifyImageCaptcha(input.CaptchaId, input.Captcha) {
c.JSON(http.StatusBadRequest, gin.H{"error": "验证码错误"})
return
}
token, err := h.userService.Login(input.Username, input.Password)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
return
}
// 设置 cookie
// c.SetCookie("token", token, 86400, "/", "", false, true) // 24小时过期httpOnly=true
c.JSON(http.StatusOK, gin.H{"token": token})
}
func (h *UserHandler) Register(c *gin.Context) {
var input struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required,min=6"`
Email string `json:"email" binding:"required,email"`
Captcha string `json:"captcha" binding:"required,len=6"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.userService.Register(input.Username, input.Password, input.Email, input.Captcha); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "注册成功"})
}
func (h *UserHandler) ResetPasswordWithToken(c *gin.Context) {
var input struct {
Token string `json:"token" binding:"required"`
NewPassword string `json:"new_password" binding:"required,min=6"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.userService.ResetPasswordWithToken(input.Token, input.NewPassword); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "密码重置成功"})
}
func (h *UserHandler) ResetPassword(c *gin.Context) {
var input struct {
Email string `json:"email" binding:"required,email"`
Captcha string `json:"captcha" binding:"required,len=6"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.userService.ResetPassword(input.Email, input.Captcha); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "重置密码邮件已发送"})
}
func (h *UserHandler) SendRegisterCaptcha(c *gin.Context) {
var input struct {
Email string `json:"email" binding:"required,email"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.userService.SendRegisterCaptcha(input.Email); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "验证码已发送"})
}
func (h *UserHandler) SendResetPasswordCaptcha(c *gin.Context) {
var input struct {
Email string `json:"email" binding:"required,email"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.userService.SendResetPasswordCaptcha(input.Email); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "验证码已发送"})
}
// 在 UserHandler 中添加以下方法
// 获取图片验证码
func (h *UserHandler) GetCaptcha(c *gin.Context) {
id, b64s, err := h.userService.GetCaptchaService().GenerateImageCaptcha()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "生成验证码失败: " + err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"captchaId": id,
"imageBase64": b64s,
})
}
// 验证图片验证码
func (h *UserHandler) VerifyCaptcha(c *gin.Context) {
var input struct {
CaptchaId string `json:"captcha_id" binding:"required"`
Code string `json:"code" binding:"required"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if !h.userService.GetCaptchaService().VerifyImageCaptcha(input.CaptchaId, input.Code) {
c.JSON(http.StatusBadRequest, gin.H{"error": "验证码错误"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "验证成功"})
}
// 获取用户列表
func (h *UserHandler) GetUsers(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
username := c.Query("username")
role := c.Query("role")
users, total, err := h.userService.GetUsers(username, role, page, pageSize)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "获取用户列表成功",
"count": total,
"data": users,
})
}
// 创建用户
func (h *UserHandler) CreateUser(c *gin.Context) {
var input struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Email string `json:"email" binding:"required,email"`
Role string `json:"role" binding:"required,oneof=admin user"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 检查权限
if c.GetString("role") != "admin" {
c.JSON(http.StatusForbidden, gin.H{"error": "需要管理员权限"})
return
}
err := h.userService.CreateUser(input.Username, input.Password, input.Email, input.Role)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "用户创建成功"})
}
// 更新用户
func (h *UserHandler) UpdateUser(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
return
}
var input struct {
Email string `json:"email" binding:"required,email"`
Role string `json:"role" binding:"required,oneof=admin user"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 检查权限
if c.GetString("role") != "admin" {
c.JSON(http.StatusForbidden, gin.H{"error": "需要管理员权限"})
return
}
err = h.userService.UpdateUser(uint(id), input.Email, input.Role)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "用户更新成功"})
}
// 删除用户
func (h *UserHandler) DeleteUser(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
return
}
// 检查权限
if c.GetString("role") != "admin" {
c.JSON(http.StatusForbidden, gin.H{"error": "需要管理员权限"})
return
}
// 不能删除自己
if uint(id) == c.GetUint("userID") {
c.JSON(http.StatusBadRequest, gin.H{"error": "不能删除自己"})
return
}
err = h.userService.DeleteUser(uint(id))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "用户删除成功"})
}
// 获取用户信息
func (h *UserHandler) GetUserInfo(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
return
}
user, err := h.userService.GetUserByID(uint(id))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
return
}
c.JSON(http.StatusOK, user)
}
// 获取当前用户信息
func (h *UserHandler) GetProfile(c *gin.Context) {
userID := c.GetUint("userID")
user, err := h.userService.GetUserByID(userID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
return
}
c.JSON(http.StatusOK, user)
}
// 修改密码
func (h *UserHandler) ChangePassword(c *gin.Context) {
var input struct {
OldPassword string `json:"old_password" binding:"required"`
NewPassword string `json:"new_password" binding:"required,min=6"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
userID := c.GetUint("userID")
err := h.userService.ChangePassword(userID, input.OldPassword, input.NewPassword)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "密码修改成功"})
}
// 在 UserHandler 结构体中添加 UpdateProfile 方法
func (h *UserHandler) UpdateProfile(c *gin.Context) {
var input struct {
Email string `json:"email" binding:"required,email"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
userID := c.GetUint("userID")
if err := h.userService.UpdateProfile(userID, input.Email); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "个人信息更新成功"})
}