425 lines
9.6 KiB
Go
425 lines
9.6 KiB
Go
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": "个人信息更新成功"})
|
||
}
|