代码拉取完成,页面将自动刷新
package controller
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"gitee.com/linqwen/momo/igin"
"gitee.com/linqwen/momo/rbac"
"gitee.com/linqwen/momo/utils"
"github.com/gin-gonic/gin"
)
type fileCtl struct{}
func FileRouter(router igin.IRouterGroup) {
c := fileCtl{}
r := router.Group("filemgr")
r.GET("/", rbac.Auth.HasPermit("srv_filemgr"), c.PageByDTO)
r.POST("/", rbac.Auth.HasPermit("srv_filemgr_add"), c.Create)
r.GET("/:id", rbac.Auth.HasPermit("srv_filemgr_view"), c.GetById)
r.POST("/deletes", rbac.Auth.HasPermit("srv_filemgr_delete"), c.Delete)
r.GET("/down", c.DownByFileName)
}
const baseDir = "data/files"
const tempDir = "data/files/temp"
// 初始化目录
func init() {
if err := os.MkdirAll(baseDir, os.ModePerm); err != nil {
fmt.Println("创建目录失败:", err)
os.Exit(1)
}
fmt.Printf(" - log目录初始化完成:%v\n", baseDir)
}
func (bc *fileCtl) Create(c igin.IContext) {
file, err := c.FormFile("file")
if err != nil {
utils.ResponseApiError(c, 400, "bindjson error", err.Error())
return
}
filePath := filepath.Join(baseDir, file.Filename)
if err := c.SaveUploadedFile(file, filePath); err != nil {
utils.ResponseApiError(c, 400, "bindjson error", err.Error())
return
}
utils.ResponseApiOk(c, "OK", filePath)
}
// PageByDTO 列出指定目录下的所有文件并分页返回
func (bc *fileCtl) PageByDTO(c igin.IContext) {
files, err := os.ReadDir(baseDir)
if err != nil {
utils.ResponseApiError(c, http.StatusInternalServerError, "无法读取目录", err.Error())
return
}
// 直接使用 interface{} 类型的切片存储文件信息
var volist1 []interface{}
for _, file := range files {
filePath := filepath.Join(baseDir, file.Name())
fileInfo, _ := os.Stat(filePath)
fileInfoMap := map[string]interface{}{
"Id": file.Name(),
"FileName": filepath.Join(baseDir, file.Name()),
"Size": fmt.Sprintf("%.2fMB", float64(fileInfo.Size())/1000000.0),
}
volist1 = append(volist1, fileInfoMap)
}
// 设置分页信息
totalPages := len(volist1)
pageSize := 100
totalPages = (totalPages + pageSize - 1) / pageSize // 计算总页数
result := utils.PaginationResult{
Current: 1,
Size: pageSize,
Total: totalPages,
Pages: totalPages,
Records: volist1,
}
utils.ResponseApiOk(c, "OK", result)
}
// GetById 下载文件
func (bc *fileCtl) GetById(c igin.IContext) {
fileName := c.Param("id")
filePath := filepath.Join(baseDir, fileName)
// 检查文件是否存在
file, err := os.Open(filePath)
if err != nil {
if os.IsNotExist(err) {
c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
}
return
}
defer file.Close()
// 获取文件信息
fileInfo, err := file.Stat()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 设置响应头
c.Header("Content-Disposition", "inline; filename="+fileInfo.Name())
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))
// 将文件内容写入响应体
_, err = io.Copy(c.Writer(), file)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
// Delete 删除文件
func (bc *fileCtl) Delete(c igin.IContext) {
var paths []string
if err := c.BindJSON(&paths); err != nil {
utils.ResponseApiError(c, 400, "解析请求体错误", err.Error())
return
}
// 删除文件
var errors []string
for _, path := range paths {
filePath := filepath.Join(baseDir, path)
if err := os.Remove(filePath); err != nil {
errors = append(errors, fmt.Sprintf("删除文件 %s 失败: %s", filePath, err.Error()))
}
}
if len(errors) > 0 {
c.JSON(http.StatusInternalServerError, gin.H{"errors": errors})
return
}
utils.ResponseApiOk(c, "文件已删除", nil)
}
// GetById 下载文件
func (bc *fileCtl) DownByFileName(c igin.IContext) {
fileName := c.Query("name")
filePath := filepath.Join(tempDir, fileName)
// 检查文件是否存在
file, err := os.Open(filePath)
if err != nil {
if os.IsNotExist(err) {
c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
}
return
}
defer file.Close()
// 获取文件信息
fileInfo, err := file.Stat()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 设置响应头
c.Header("Content-Disposition", "inline; filename="+fileInfo.Name())
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))
// 将文件内容写入响应体
_, err = io.Copy(c.Writer(), file)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。