196 lines
5.2 KiB
Go
196 lines
5.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.zkcoi.com/zkcoi/meshray/internal/service"
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// AdminHandler 管理员 Handler
|
|
type AdminHandler struct {
|
|
userService *service.UserService
|
|
restartCoreSvc *service.RestartCoreService
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewAdminHandler 创建管理员 Handler
|
|
func NewAdminHandler(userService *service.UserService, logger *zap.Logger) *AdminHandler {
|
|
return &AdminHandler{
|
|
userService: userService,
|
|
restartCoreSvc: service.NewRestartCoreService(logger),
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// GetProfile 获取管理员信息
|
|
func (h *AdminHandler) GetProfile(c *gin.Context) {
|
|
// 从上下文获取用户 ID(由 JWT 中间件注入)
|
|
userID, exists := c.Get("user_id")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "未认证"})
|
|
return
|
|
}
|
|
|
|
// 获取用户信息
|
|
user, err := h.userService.GetUserByID(userID.(uint))
|
|
if err != nil {
|
|
h.logger.Error("获取管理员信息失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取信息失败"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"data": gin.H{
|
|
"id": user.ID,
|
|
"username": user.Username,
|
|
"email": user.Email,
|
|
"role": user.Role,
|
|
"status": user.Status,
|
|
"created_at": user.CreatedAt,
|
|
},
|
|
})
|
|
}
|
|
|
|
// UpdateProfileRequest 更新资料请求
|
|
type UpdateProfileRequest struct {
|
|
Username string `json:"username"`
|
|
Email string `json:"email"`
|
|
Password string `json:"password"` // 可选,留空则不修改
|
|
}
|
|
|
|
// UpdateProfile 更新管理员资料
|
|
func (h *AdminHandler) UpdateProfile(c *gin.Context) {
|
|
var req UpdateProfileRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
|
|
return
|
|
}
|
|
|
|
// 从上下文获取当前用户名(用于验证)
|
|
currentUsername, _ := c.Get("username")
|
|
|
|
// 如果修改了用户名,需要验证不为空
|
|
if req.Username != "" && req.Username != currentUsername {
|
|
// 用户名不能为空
|
|
if len(req.Username) < 3 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "用户名至少 3 个字符"})
|
|
return
|
|
}
|
|
}
|
|
|
|
// 如果提供了密码,验证长度
|
|
if req.Password != "" && len(req.Password) < 6 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "密码至少 6 个字符"})
|
|
return
|
|
}
|
|
|
|
// 如果提供了邮箱,验证格式
|
|
if req.Email != "" {
|
|
if len(req.Email) < 5 || len(req.Email) > 255 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "邮箱格式无效"})
|
|
return
|
|
}
|
|
}
|
|
|
|
// 调用服务层更新
|
|
err := h.userService.UpdateAdminProfile(req.Username, req.Email, req.Password)
|
|
if err != nil {
|
|
h.logger.Error("更新管理员资料失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
h.logger.Info("管理员资料已更新",
|
|
zap.String("username", req.Username),
|
|
zap.Bool("password_changed", req.Password != ""))
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "资料已更新",
|
|
"data": gin.H{
|
|
"username": req.Username,
|
|
"email": req.Email,
|
|
"password_changed": req.Password != "",
|
|
},
|
|
})
|
|
}
|
|
|
|
// ChangePassword 修改密码
|
|
func (h *AdminHandler) ChangePassword(c *gin.Context) {
|
|
var req ChangePasswordRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
|
|
return
|
|
}
|
|
|
|
// 从上下文获取用户 ID
|
|
userID, exists := c.Get("user_id")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "未认证"})
|
|
return
|
|
}
|
|
|
|
// 调用服务层修改密码
|
|
err := h.userService.ChangePassword(userID.(uint), &service.ChangePasswordRequest{
|
|
OldPassword: req.OldPassword,
|
|
NewPassword: req.NewPassword,
|
|
})
|
|
if err != nil {
|
|
h.logger.Error("修改密码失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
h.logger.Info("密码修改成功",
|
|
zap.Uint("user_id", userID.(uint)))
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "密码已修改",
|
|
})
|
|
}
|
|
|
|
// AdminRestartCoreRequest 重启核心服务请求(管理员接口)
|
|
type AdminRestartCoreRequest struct {
|
|
Force bool `json:"force"` // 是否强制重启
|
|
}
|
|
|
|
// RestartCore 重启核心服务
|
|
func (h *AdminHandler) RestartCore(c *gin.Context) {
|
|
var req AdminRestartCoreRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
|
|
return
|
|
}
|
|
|
|
// 从上下文获取用户 ID(验证管理员权限)
|
|
userID, exists := c.Get("user_id")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "未认证"})
|
|
return
|
|
}
|
|
|
|
// 验证是否为管理员
|
|
user, err := h.userService.GetUserByID(userID.(uint))
|
|
if err != nil || user.Role != "admin" {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "需要管理员权限"})
|
|
return
|
|
}
|
|
|
|
// 调用服务层重启核心
|
|
err = h.restartCoreSvc.RestartCore()
|
|
if err != nil {
|
|
h.logger.Error("重启核心服务失败", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
h.logger.Info("核心服务已重启",
|
|
zap.Uint("user_id", userID.(uint)),
|
|
zap.Bool("force", req.Force))
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "核心服务正在重启",
|
|
})
|
|
}
|