Files
filestoragesystem/go/internal/controller/admin.go
T
2026-08-23 00:48:10 +08:00

355 lines
8.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package controller
import (
"github.com/gin-gonic/gin"
"filestoragesystem/internal/repository"
"filestoragesystem/internal/utils"
)
// AdminController 系统管理控制器
type AdminController struct {
*Base
}
// NewAdminController 创建系统管理控制器
func NewAdminController(b *Base) *AdminController { return &AdminController{Base: b} }
// ---- 用户管理 ----
// ListUsers 用户列表
func (ctl *AdminController) ListUsers(c *gin.Context) {
page, pageSize := utils.ParsePage(c)
users, total, err := ctl.svc.User.AdminListUsers(
c.Query("keyword"), c.Query("role_id"), c.Query("status"), page, pageSize)
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OKPage(c, users, total, page, pageSize)
}
// GetUser 用户详情
func (ctl *AdminController) GetUser(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
u, err := ctl.svc.User.AdminGetUser(id)
if err != nil {
utils.NotFound(c, "用户不存在")
return
}
utils.OK(c, u)
}
type adminCreateUserReq struct {
Username string `json:"username" binding:"required"`
Email string `json:"email" binding:"required"`
Password string `json:"password" binding:"required"`
RoleID uint `json:"role_id"`
StorageLimit int64 `json:"storage_limit"`
}
// CreateUser 创建用户
func (ctl *AdminController) CreateUser(c *gin.Context) {
var req adminCreateUserReq
if !bindJSON(c, &req) {
return
}
u, err := ctl.svc.User.AdminCreateUser(req.Username, req.Email, req.Password, req.RoleID, req.StorageLimit)
if err != nil {
ctl.svc.RecordOpLog(ctl.opCtx(c), "create", "user", 0, req.Username, false, err.Error())
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "create", "user", u.ID, u.Username, true, "")
utils.OK(c, u)
}
type adminUpdateUserReq struct {
Email string `json:"email"`
RoleID uint `json:"role_id"`
StorageLimit int64 `json:"storage_limit"`
}
// UpdateUser 编辑用户
func (ctl *AdminController) UpdateUser(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
var req adminUpdateUserReq
if !bindJSON(c, &req) {
return
}
u, err := ctl.svc.User.AdminUpdateUser(id, req.Email, req.RoleID, req.StorageLimit)
if err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "user", id, u.Username, true, "")
utils.OK(c, u)
}
// DeleteUser 删除用户
func (ctl *AdminController) DeleteUser(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
if err := ctl.svc.User.AdminDeleteUser(id); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "delete", "user", id, "", true, "")
utils.OKMsg(c, "用户已删除")
}
type setUserStatusReq struct {
Status int8 `json:"status"` // 1启用 0禁用(不加required,0为合法值)
}
// SetUserStatus 启用/禁用用户
func (ctl *AdminController) SetUserStatus(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
var req setUserStatusReq
if !bindJSON(c, &req) {
return
}
if req.Status != 0 && req.Status != 1 {
utils.FailMsg(c, "status仅支持0或1")
return
}
if err := ctl.svc.User.AdminSetUserStatus(id, req.Status); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "user", id, "status", true, "")
utils.OKMsg(c, "状态已更新")
}
type assignRoleReq struct {
RoleID uint `json:"role_id" binding:"required"`
}
// AssignRole 修改用户角色
func (ctl *AdminController) AssignRole(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
var req assignRoleReq
if !bindJSON(c, &req) {
return
}
if err := ctl.svc.User.AdminAssignRole(id, req.RoleID); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "user", id, "role", true, "")
utils.OKMsg(c, "角色已更新")
}
type resetPasswordReq struct {
Password string `json:"password" binding:"required"`
}
// ResetPassword 重置用户密码
func (ctl *AdminController) ResetPassword(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
var req resetPasswordReq
if !bindJSON(c, &req) {
return
}
if err := ctl.svc.User.AdminResetPassword(id, req.Password); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "user", id, "password", true, "")
utils.OKMsg(c, "密码已重置")
}
// ---- 系统设置 ----
// GetSettings 获取全部设置
func (ctl *AdminController) GetSettings(c *gin.Context) {
groups, err := ctl.svc.Admin.GetSettings()
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OK(c, groups)
}
// GetSettingsByGroup 按分组获取设置
func (ctl *AdminController) GetSettingsByGroup(c *gin.Context) {
group := c.Param("group")
settings, err := ctl.svc.Admin.GetSettingsByGroup(group)
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OK(c, settings)
}
// UpdateSettings 批量更新设置
func (ctl *AdminController) UpdateSettings(c *gin.Context) {
var req map[string]string
if !bindJSON(c, &req) {
return
}
if err := ctl.svc.Admin.UpdateSettings(req); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "system", 0, "settings", true, "")
utils.OKMsg(c, "设置已更新")
}
// UpdateSettingsByGroup 按分组更新设置
func (ctl *AdminController) UpdateSettingsByGroup(c *gin.Context) {
var req map[string]string
if !bindJSON(c, &req) {
return
}
if err := ctl.svc.Admin.UpdateSettings(req); err != nil {
utils.FailMsg(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "update", "system", 0, "settings:"+c.Param("group"), true, "")
utils.OKMsg(c, "设置已更新")
}
// ---- 日志管理 ----
// ListOperationLogs 操作日志列表
func (ctl *AdminController) ListOperationLogs(c *gin.Context) {
page, pageSize := utils.ParsePage(c)
f := repository.OpLogFilter{
Username: c.Query("username"),
Action: c.Query("action"),
Status: c.Query("status"),
Days: parseIntQuery(c, "days", 0),
Page: page,
PageSize: pageSize,
}
if uid := parseUintQuery(c, "user_id"); uid > 0 {
f.UserID = &uid
}
logs, total, err := ctl.svc.Admin.ListOperationLogs(f)
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OKPage(c, logs, total, page, pageSize)
}
// GetOperationLog 操作日志详情
func (ctl *AdminController) GetOperationLog(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
l, err := ctl.svc.Admin.GetOperationLog(id)
if err != nil {
utils.NotFound(c, "日志不存在")
return
}
utils.OK(c, l)
}
// ListSystemLogs 系统日志列表
func (ctl *AdminController) ListSystemLogs(c *gin.Context) {
page, pageSize := utils.ParsePage(c)
f := repository.SysLogFilter{
Level: c.Query("level"),
Module: c.Query("module"),
Days: parseIntQuery(c, "days", 0),
Page: page,
PageSize: pageSize,
}
logs, total, err := ctl.svc.Admin.ListSystemLogs(f)
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OKPage(c, logs, total, page, pageSize)
}
// GetSystemLog 系统日志详情
func (ctl *AdminController) GetSystemLog(c *gin.Context) {
id, ok := paramID(c)
if !ok {
return
}
l, err := ctl.svc.Admin.GetSystemLog(id)
if err != nil {
utils.NotFound(c, "日志不存在")
return
}
utils.OK(c, l)
}
// CleanupLogs 清理历史日志
func (ctl *AdminController) CleanupLogs(c *gin.Context) {
days := parseIntQuery(c, "days", 30)
opDeleted, sysDeleted, err := ctl.svc.Admin.CleanupLogs(days)
if err != nil {
utils.ServerError(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "delete", "system", 0, "logs", true, "")
utils.OK(c, gin.H{
"days": days,
"operation_logs_deleted": opDeleted,
"system_logs_deleted": sysDeleted,
})
}
// ---- 数据备份 ----
// Backup 手动备份数据库
func (ctl *AdminController) Backup(c *gin.Context) {
name, err := ctl.svc.Admin.BackupDatabase()
if err != nil {
utils.ServerError(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "create", "system", 0, "backup:"+name, true, "")
utils.OK(c, gin.H{"name": name})
}
// ListBackups 备份列表
func (ctl *AdminController) ListBackups(c *gin.Context) {
list, err := ctl.svc.Admin.ListBackups()
if err != nil {
utils.ServerError(c, err.Error())
return
}
utils.OK(c, list)
}
// DownloadBackup 下载备份文件
func (ctl *AdminController) DownloadBackup(c *gin.Context) {
name := c.Query("name")
path, err := ctl.svc.Admin.BackupPath(name)
if err != nil {
utils.NotFound(c, err.Error())
return
}
ctl.svc.RecordOpLog(ctl.opCtx(c), "download", "system", 0, "backup:"+name, true, "")
c.FileAttachment(path, name)
}
// SiteStatus 公开站点状态接口
func (ctl *AdminController) SiteStatus(c *gin.Context) {
utils.OK(c, ctl.svc.Admin.SiteStatus())
}