509 lines
14 KiB
Go
509 lines
14 KiB
Go
package controllers
|
||
|
||
import (
|
||
"Quincy_admin/config"
|
||
"Quincy_admin/schemas"
|
||
"Quincy_admin/services"
|
||
"Quincy_admin/utils"
|
||
"fmt"
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
type UserController struct {
|
||
service *services.UserService
|
||
config *config.Config
|
||
}
|
||
|
||
func NewUserController(service *services.UserService) *UserController {
|
||
return &UserController{service: service, config: config.LoadConfig()}
|
||
}
|
||
|
||
// Create 创建用户
|
||
// @Summary 创建用户
|
||
// @Description 创建用户
|
||
// @Tags 用户管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param user body schemas.CreateUser true "用户信息"
|
||
// @Success 200 {object} utils.Response{data=schemas.UserResponse}
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/register [post]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) Create(ctx *gin.Context) {
|
||
var user schemas.CreateUser
|
||
if err := ctx.ShouldBindJSON(&user); err != nil {
|
||
utils.Error(ctx, http.StatusBadRequest, "无效的请求数据,JSON解析错误")
|
||
return
|
||
}
|
||
|
||
// 检查邮箱是否重复
|
||
email, err := c.service.IsEmailExists(user.Email)
|
||
if err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
if email > 0 {
|
||
utils.Error(ctx, http.StatusBadRequest, "邮箱已存在")
|
||
return
|
||
}
|
||
|
||
if err := c.service.CreateUser(&user); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
|
||
user.Password = ""
|
||
response := map[string]string{
|
||
"sessioncode": user.SessionCode,
|
||
}
|
||
utils.Success(ctx, response)
|
||
}
|
||
|
||
// GetByID 获取用户信息
|
||
// @Summary 获取用户信息
|
||
// @Description 获取用户信息
|
||
// @Tags 用户管理
|
||
// @Produce json
|
||
// @Success 200 {object} utils.Response{data=schemas.UserInfo}
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 404 {object} utils.Response
|
||
// @Router /user/getinfo [get]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) GetByID(ctx *gin.Context) {
|
||
scode, err := getCode(ctx)
|
||
if err != nil {
|
||
utils.Error(ctx, http.StatusUnauthorized, "用户ID不存在")
|
||
return
|
||
}
|
||
|
||
if scode == "" {
|
||
utils.Error(ctx, http.StatusBadRequest, "无效的用户编码")
|
||
return
|
||
}
|
||
|
||
user, err := c.service.GetUserByID(scode)
|
||
if err != nil {
|
||
utils.Error(ctx, http.StatusNotFound, "用户不存在")
|
||
return
|
||
}
|
||
|
||
if user.RoleCode == 0 {
|
||
utils.Fail(ctx, http.StatusForbidden, "未分配权限")
|
||
return
|
||
}
|
||
|
||
// 不返回密码等敏感信息
|
||
user.Password = ""
|
||
utils.Success(ctx, user)
|
||
}
|
||
|
||
// Update 更新用户信息
|
||
// @Summary 更新用户信息
|
||
// @Description 更新用户信息
|
||
// @Tags 用户管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param user body schemas.UpdateUser true "用户信息"
|
||
// @Success 200 {object} utils.Response{data=string}
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/update [put]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) Update(ctx *gin.Context) {
|
||
|
||
var user schemas.UpdateUser
|
||
if err := ctx.ShouldBindJSON(&user); err != nil {
|
||
utils.Error(ctx, http.StatusBadRequest, "无效的请求数据")
|
||
return
|
||
}
|
||
|
||
// 防止修改超级管理员账户(ID=1)
|
||
if user.ID == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "无权限修改超级管理员账户")
|
||
return
|
||
}
|
||
|
||
if _, err := c.service.UpdateUser(&user); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, err.Error())
|
||
return
|
||
}
|
||
|
||
user.Password = ""
|
||
utils.Success(ctx, user.ID)
|
||
}
|
||
|
||
// UpdateStatus 禁用/启用用户
|
||
// @Summary 禁用/启用用户
|
||
// @Description 禁用/启用用户
|
||
// @Tags 用户管理
|
||
// @Param id path string true "用户ID"
|
||
// @Param status query int false "启用状态(1:启用,0:停用)"
|
||
// @Success 200 {object} utils.Response
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/{id} [put]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) UpdateStatus(ctx *gin.Context) {
|
||
idstr := ctx.Param("id")
|
||
|
||
id, err := strconv.Atoi(idstr)
|
||
if err != nil || id <= 0 {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 id 必须是有效的整数")
|
||
return
|
||
}
|
||
|
||
// 防止修改超级管理员账户(ID=1)
|
||
if id == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "无权限修改超级管理员账户")
|
||
return
|
||
}
|
||
|
||
status := ctx.Query("status")
|
||
if status == "" {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 status 不能为空")
|
||
return
|
||
}
|
||
|
||
statusValue, err := strconv.Atoi(status)
|
||
if err != nil || (statusValue != 0 && statusValue != 1) {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 status 必须是0或1")
|
||
return
|
||
}
|
||
|
||
// 直接传递整数值到服务层
|
||
if err := c.service.UpdateStatus(id, statusValue); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "操作失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
if statusValue == 1 {
|
||
utils.Success(ctx, "启用成功")
|
||
} else {
|
||
utils.Success(ctx, "停用成功")
|
||
}
|
||
}
|
||
|
||
// Login 用户登录
|
||
// @Summary 用户登录
|
||
// @Description 用户登录验证
|
||
// @Tags 用户管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param login body schemas.LoginRequest true "req"
|
||
// @Success 200 {object} utils.Response{data=schemas.UserResponse}
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 401 {object} utils.Response
|
||
// @Failure 403 {object} utils.Response
|
||
// @Router /user/login [post]
|
||
func (c *UserController) Login(ctx *gin.Context) {
|
||
var loginReq schemas.LoginRequest
|
||
|
||
if err := ctx.ShouldBindJSON(&loginReq); err != nil {
|
||
utils.Fail(ctx, http.StatusBadRequest, "无效的登录数据")
|
||
return
|
||
}
|
||
|
||
user, err := c.service.GetUserByUsername(loginReq.Username)
|
||
if err != nil {
|
||
// 记录失败登录日志
|
||
err := c.service.RecordLoginLog(0, loginReq.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 0, "用户不存在")
|
||
if err != nil {
|
||
return
|
||
}
|
||
utils.Fail(ctx, http.StatusUnauthorized, "用户不存在")
|
||
return
|
||
}
|
||
|
||
// 更新最后登录时间
|
||
if err := c.service.UpdateLastLoginTime(user.SessionCode); err != nil {
|
||
// 记录失败登录日志
|
||
err := c.service.RecordLoginLog(0, loginReq.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 0, "系统错误")
|
||
if err != nil {
|
||
return
|
||
}
|
||
utils.Fail(ctx, http.StatusInternalServerError, "系统错误")
|
||
return
|
||
}
|
||
|
||
if user.Status == schemas.UserStatusDisabled {
|
||
// 记录失败登录日志
|
||
err := c.service.RecordLoginLog(user.ID, user.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 0, "用户已被锁定")
|
||
if err != nil {
|
||
return
|
||
}
|
||
utils.Fail(ctx, http.StatusForbidden, "用户已被锁定")
|
||
return
|
||
}
|
||
|
||
if user.RoleCode == 0 {
|
||
// 记录失败登录日志
|
||
err := c.service.RecordLoginLog(user.ID, user.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 0, "未分配权限")
|
||
if err != nil {
|
||
return
|
||
}
|
||
utils.Fail(ctx, http.StatusForbidden, "未分配权限")
|
||
return
|
||
}
|
||
|
||
if !c.service.VerifyPassword(loginReq.Password, user.Password) {
|
||
// 记录失败登录日志
|
||
err := c.service.RecordLoginLog(user.ID, user.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 0, "密码错误")
|
||
if err != nil {
|
||
return
|
||
}
|
||
utils.Fail(ctx, http.StatusUnauthorized, "密码错误")
|
||
return
|
||
}
|
||
|
||
// 记录成功登录日志
|
||
err = c.service.RecordLoginLog(user.ID, user.Username, ctx.ClientIP(), ctx.Request.UserAgent(), 1, "")
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
user.Password = ""
|
||
|
||
//err = c.service.StoreLoginSession(user.SessionCode, user, 24*time.Hour)
|
||
//if err != nil {
|
||
// utils.Error(ctx, http.StatusInternalServerError, "登录失败")
|
||
// return
|
||
//}
|
||
|
||
// 生成 JWT token
|
||
token, err := utils.GenerateToken(user.ID, user.Username, user.SessionCode, user.RoleCode)
|
||
if err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "生成令牌失败")
|
||
return
|
||
}
|
||
|
||
// 返回 token 和用户信息
|
||
response := map[string]interface{}{
|
||
"Authorization": token,
|
||
}
|
||
utils.Success(ctx, response)
|
||
}
|
||
|
||
// UserList 获取用户列表
|
||
// @Summary 获取用户列表
|
||
// @Description 获取用户列表
|
||
// @Tags 用户管理
|
||
// @Produce json
|
||
// @Param user body schemas.UserListRequest true "请求体"
|
||
// @Success 200 {object} utils.Response{data=schemas.UserListResponse}
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/list [post]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) UserList(ctx *gin.Context) {
|
||
var req schemas.UserListRequest
|
||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
if req.PageIndex <= 0 || req.PageSize <= 0 || req.PageSize > 100 {
|
||
utils.Error(ctx, http.StatusBadRequest, "分页参数错误")
|
||
return
|
||
}
|
||
|
||
users, total, err := c.service.GetUserList(&req)
|
||
if err != nil {
|
||
fmt.Println("获取用户列表时出错:", err)
|
||
utils.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||
return
|
||
}
|
||
|
||
// 清除用户密码信息
|
||
for _, user := range users {
|
||
user.Password = ""
|
||
}
|
||
|
||
response := schemas.UserListResponse{
|
||
Item: users,
|
||
Total: total,
|
||
PageIndex: req.PageIndex,
|
||
PageSize: req.PageSize,
|
||
}
|
||
|
||
utils.Success(ctx, response)
|
||
}
|
||
|
||
// UserRoleList 获取角色列表
|
||
// @Summary 获取角色列表
|
||
// @Description 获取角色列表
|
||
// @Tags 用户管理
|
||
// @Produce json
|
||
// @Param role body schemas.RoleListRequest true "req"
|
||
// @Success 200 {object} utils.Response{data=schemas.RoleResponseList}
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/rolelist [post]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) UserRoleList(ctx *gin.Context) {
|
||
var req schemas.RoleListRequest
|
||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
if req.PageIndex <= 0 || req.PageSize <= 0 || req.PageSize > 100 {
|
||
utils.Error(ctx, http.StatusBadRequest, "分页参数错误")
|
||
return
|
||
}
|
||
|
||
items, total, err := c.service.GetRoleList(&req)
|
||
if err != nil {
|
||
fmt.Println("获取用户列表时出错:", err)
|
||
utils.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||
return
|
||
}
|
||
|
||
response := schemas.RoleListResponse{
|
||
Item: items,
|
||
Total: total,
|
||
PageIndex: req.PageIndex,
|
||
PageSize: req.PageSize,
|
||
}
|
||
|
||
utils.Success(ctx, response)
|
||
}
|
||
|
||
// AssignRole 用户角色分配
|
||
// @Summary 用户角色分配
|
||
// @Description 用户角色分配
|
||
// @Tags 用户管理
|
||
// @Param user_id query string true "用户ID"
|
||
// @Param role_id query int false "角色ID"
|
||
// @Success 200 {object} utils.Response
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/assign [put]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) AssignRole(ctx *gin.Context) {
|
||
userId := ctx.Query("user_id")
|
||
userIdValue, err := strconv.Atoi(userId)
|
||
if err != nil || userIdValue <= 0 {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 user_id 必须是有效的整数")
|
||
return
|
||
}
|
||
|
||
if userIdValue == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "无权限修改超级管理员账户")
|
||
return
|
||
}
|
||
|
||
roleId := ctx.Query("role_id")
|
||
roleIdValue, err := strconv.Atoi(roleId)
|
||
if err != nil || roleIdValue <= 0 {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 role_id 必须是有效的整数")
|
||
return
|
||
}
|
||
|
||
if roleIdValue == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "禁止分配超级管理员权限")
|
||
return
|
||
}
|
||
|
||
// 直接传递整数值到服务层
|
||
if err := c.service.AssignRole(userIdValue, roleIdValue); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "操作失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
utils.Success(ctx, "")
|
||
}
|
||
|
||
// UpdateRoleStatus 禁用/启用角色
|
||
// @Summary 禁用/启用角色
|
||
// @Description 禁用/启用角色
|
||
// @Tags 用户管理
|
||
// @Param id path string true "角色ID"
|
||
// @Param status query int false "启用状态(1:启用,0:停用)"
|
||
// @Success 200 {object} utils.Response
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/role/{id} [put]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) UpdateRoleStatus(ctx *gin.Context) {
|
||
idstr := ctx.Param("id")
|
||
|
||
id, err := strconv.Atoi(idstr)
|
||
if err != nil || id <= 0 {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 id 必须是有效的整数")
|
||
return
|
||
}
|
||
|
||
// 防止修改超级管理员账户(ID=1)
|
||
if id == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "无权限修改超级管理员账户")
|
||
return
|
||
}
|
||
|
||
status := ctx.Query("status")
|
||
if status == "" {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 status 不能为空")
|
||
return
|
||
}
|
||
|
||
statusValue, err := strconv.Atoi(status)
|
||
if err != nil || (statusValue != 0 && statusValue != 1) {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数 status 必须是0或1")
|
||
return
|
||
}
|
||
|
||
// 直接传递整数值到服务层
|
||
if err := c.service.UpdateRoleStatus(id, statusValue); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "操作失败: "+err.Error())
|
||
return
|
||
}
|
||
|
||
if statusValue == 1 {
|
||
utils.Success(ctx, "启用成功")
|
||
} else {
|
||
utils.Success(ctx, "停用成功")
|
||
}
|
||
}
|
||
|
||
// CreateRole 创建角色
|
||
// @Summary 创建角色
|
||
// @Description 创建角色
|
||
// @Tags 用户管理
|
||
// @Produce json
|
||
// @Param role body schemas.CreateRole true "req"
|
||
// @Success 200 {object} utils.Response
|
||
// @Failure 400 {object} utils.Response
|
||
// @Failure 500 {object} utils.Response
|
||
// @Router /user/role [post]
|
||
// @Security ApiKeyAuth
|
||
func (c *UserController) CreateRole(ctx *gin.Context) {
|
||
var req schemas.CreateRole
|
||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
utils.Error(ctx, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
if req.ID == 1 {
|
||
utils.Error(ctx, http.StatusForbidden, "无权限修改超级管理员账户")
|
||
return
|
||
}
|
||
|
||
// 判断ID是否传入,传了更新,没传新增
|
||
if req.ID > 0 {
|
||
// 更新角色
|
||
if err := c.service.UpdateRole(&req); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "更新失败: "+err.Error())
|
||
return
|
||
}
|
||
utils.Success(ctx, "更新成功")
|
||
} else {
|
||
// 新增角色
|
||
if err := c.service.CreateRole(&req); err != nil {
|
||
utils.Error(ctx, http.StatusInternalServerError, "创建失败: "+err.Error())
|
||
return
|
||
}
|
||
utils.Success(ctx, "创建成功")
|
||
}
|
||
}
|