Files
Quincy_admin/controllers/com_controller.go
2026-03-26 22:13:03 +08:00

172 lines
4.8 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 controllers
import (
"Quincy_admin/config"
"Quincy_admin/schemas"
"Quincy_admin/services"
"Quincy_admin/utils"
"fmt"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/gin-gonic/gin"
)
type CommonController struct {
service *services.CommonService
config *config.Config
}
func NewCommonController(service *services.CommonService) *CommonController {
return &CommonController{service: service, config: config.LoadConfig()}
}
// GetLoginLogList 获取系统登录日志
// @Summary 系统登录日志
// @Description 系统登录日志
// @Tags 系统管理
// @Produce json
// @Param role body schemas.LoginLogListRequest true "req"
// @Success 200 {object} utils.Response{data=schemas.LoginLog}
// @Failure 500 {object} utils.Response
// @Router /system/log/login/list [post]
// @Security ApiKeyAuth
func (c *CommonController) GetLoginLogList(ctx *gin.Context) {
var req schemas.LoginLogListRequest
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.GetLoginLogList(&req)
if err != nil {
fmt.Println("获取用户列表时出错:", err)
utils.Error(ctx, http.StatusInternalServerError, "获取日志列表失败")
return
}
response := schemas.LoginLogListResponse{
Item: items,
Total: total,
PageIndex: req.PageIndex,
PageSize: req.PageSize,
}
utils.Success(ctx, response)
}
// DownloadLogFile 下载日志文件
// @Summary 下载日志文件
// @Description 下载指定的日志文件内容
// @Tags 系统管理
// @Produce application/octet-stream
// @Param filename query string true "日志文件名"
// @Success 200 {file} file "日志文件内容"
// @Failure 400 {object} utils.Response
// @Failure 404 {object} utils.Response
// @Failure 500 {object} utils.Response
// @Router /system/log/download [get]
// @Security ApiKeyAuth
// DownloadLogFile 下载日志文件
func (c *CommonController) DownloadLogFile(ctx *gin.Context) {
filename := ctx.Query("filename")
if filename == "" {
utils.Error(ctx, http.StatusBadRequest, "参数 filename 不能为空")
return
}
// 验证文件名安全性
if strings.Contains(filename, "..") || strings.Contains(filename, "/") || strings.Contains(filename, "\\") {
utils.Error(ctx, http.StatusBadRequest, "无效的文件名")
return
}
// 使用 filepath.Join 处理跨平台路径分隔符
filePath := filepath.Join(c.config.Log.Path, filename)
// 检查文件是否存在
if _, err := os.Stat(filePath); os.IsNotExist(err) {
utils.Error(ctx, http.StatusNotFound, "日志文件不存在")
return
}
// 对文件名进行编码以支持中文
encodedFilename := url.QueryEscape(filename)
// 设置响应头
ctx.Header("Content-Description", "File Transfer")
ctx.Header("Content-Transfer-Encoding", "binary")
ctx.Header("Content-Disposition", "attachment; filename*=UTF-8''"+encodedFilename)
ctx.Header("Content-Type", "application/octet-stream")
// 返回文件内容
ctx.File(filePath)
}
// ViewLogFile 查看日志文件内容
// @Summary 查看日志文件内容
// @Description 返回指定日志文件的内容
// @Tags 系统管理
// @Produce json
// @Param filename query string true "日志文件名"
// @Param lines query int false "返回行数默认100行"
// @Success 200 {object} utils.Response{data=string}
// @Failure 400 {object} utils.Response
// @Failure 404 {object} utils.Response
// @Failure 500 {object} utils.Response
// @Router /system/log/view [get]
// @Security ApiKeyAuth
// ViewLogFile 查看日志文件内容
func (c *CommonController) ViewLogFile(ctx *gin.Context) {
filename := ctx.Query("filename")
if filename == "" {
utils.Error(ctx, http.StatusBadRequest, "参数 filename 不能为空")
return
}
linesStr := ctx.Query("lines")
lines := 100 // 默认返回100行
if linesStr != "" {
var err error
lines, err = strconv.Atoi(linesStr)
if err != nil || lines <= 0 {
utils.Error(ctx, http.StatusBadRequest, "参数 lines 必须是正整数")
return
}
if lines > 1000 {
lines = 1000 // 限制最大行数
}
}
// 验证文件名安全性
if strings.Contains(filename, "..") || strings.Contains(filename, "/") || strings.Contains(filename, "\\") {
utils.Error(ctx, http.StatusBadRequest, "无效的文件名")
return
}
// 使用配置文件中的日志目录
f := c.config.Log.Path + "/" + filename
// 读取文件内容
content, err := c.service.ReadLastLines(f, lines)
if err != nil {
if os.IsNotExist(err) {
utils.Error(ctx, http.StatusNotFound, "日志文件不存在")
} else {
utils.Error(ctx, http.StatusInternalServerError, "读取日志文件失败: "+err.Error())
}
return
}
utils.Success(ctx, content)
}