2025-10-28 17:22:27 +08:00

583 lines
13 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 (
"encoding/json"
"os"
"path"
"path/filepath"
"server/models"
"strconv"
"strings"
"time"
beego "github.com/beego/beego/v2/server/web"
)
// FileController 处理文件相关请求
type FileController struct {
beego.Controller
}
// GetAllFiles 获取所有文件信息
func (c *FileController) GetAllFiles() {
files, err := models.GetAllFiles()
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件列表成功",
"data": files,
}
}
c.ServeJSON()
}
// GetFileById 根据ID获取文件信息
func (c *FileController) GetFileById() {
idStr := c.Ctx.Input.Param(":id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "参数错误",
}
c.ServeJSON()
return
}
file, err := models.GetFileById(id)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "文件不存在",
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件成功",
"data": file,
}
}
c.ServeJSON()
}
// GetFilesByTenant 根据租户ID获取文件信息
func (c *FileController) GetFilesByTenant() {
tenantID := c.GetString("tenant_id")
if tenantID == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "租户ID不能为空",
}
c.ServeJSON()
return
}
files, err := models.GetFilesByTenant(tenantID)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件列表成功",
"data": files,
}
}
c.ServeJSON()
}
// GetFilesByCategory 根据分类获取文件信息
func (c *FileController) GetFilesByCategory() {
category := c.GetString("category")
if category == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "分类不能为空",
}
c.ServeJSON()
return
}
files, err := models.GetFilesByCategory(category)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件列表成功",
"data": files,
}
}
c.ServeJSON()
}
// GetFilesByStatus 根据状态获取文件信息
func (c *FileController) GetFilesByStatus() {
statusStr := c.GetString("status")
status, err := strconv.Atoi(statusStr)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "状态参数错误",
}
c.ServeJSON()
return
}
files, err := models.GetFilesByStatus(int8(status))
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件列表成功",
"data": files,
}
}
c.ServeJSON()
}
// CreateFile 创建新文件信息
func (c *FileController) CreateFile() {
var file models.FileInfo
// 解析请求体
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &file); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "请求参数错误",
"error": err.Error(),
}
c.ServeJSON()
return
}
// 从JWT中间件获取用户信息
if userID, ok := c.Ctx.Input.GetData("userId").(int); ok && userID > 0 {
file.UserID = userID
}
if username, ok := c.Ctx.Input.GetData("username").(string); ok && username != "" {
file.UploadBy = username
}
// 验证必填字段
if file.TenantID == "" || file.FileName == "" || file.OriginalName == "" ||
file.FilePath == "" || file.FileType == "" || file.FileExt == "" ||
file.Category == "" || file.UploadBy == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "必填字段不能为空",
}
c.ServeJSON()
return
}
// 添加文件信息
if _, err := models.AddFile(&file); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "创建文件失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "创建文件成功",
"data": file,
}
}
c.ServeJSON()
}
// UpdateFile 更新文件信息
func (c *FileController) UpdateFile() {
idStr := c.Ctx.Input.Param(":id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "参数错误",
}
c.ServeJSON()
return
}
var file models.FileInfo
file.ID = id
// 解析请求体
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &file); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "请求参数错误",
"error": err.Error(),
}
c.ServeJSON()
return
}
// 更新文件信息
if err := models.UpdateFile(&file); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "更新文件失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "更新文件成功",
"data": file,
}
}
c.ServeJSON()
}
// DeleteFile 删除文件信息(软删除)
func (c *FileController) DeleteFile() {
idStr := c.Ctx.Input.Param(":id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "参数错误",
}
c.ServeJSON()
return
}
if err := models.DeleteFile(id); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "删除文件失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "删除文件成功",
}
}
c.ServeJSON()
}
// HardDeleteFile 硬删除文件信息
func (c *FileController) HardDeleteFile() {
idStr := c.Ctx.Input.Param(":id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "参数错误",
}
c.ServeJSON()
return
}
if err := models.HardDeleteFile(id); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "删除文件失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "删除文件成功",
}
}
c.ServeJSON()
}
// GetFileStatistics 获取文件统计信息
func (c *FileController) GetFileStatistics() {
tenantID := c.GetString("tenant_id")
if tenantID == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "租户ID不能为空",
}
c.ServeJSON()
return
}
stats, err := models.GetFileStatistics(tenantID)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取统计信息失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取统计信息成功",
"data": stats,
}
}
c.ServeJSON()
}
// SearchFiles 搜索文件
func (c *FileController) SearchFiles() {
keyword := c.GetString("keyword")
tenantID := c.GetString("tenant_id")
if keyword == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "搜索关键词不能为空",
}
c.ServeJSON()
return
}
if tenantID == "" {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "租户ID不能为空",
}
c.ServeJSON()
return
}
files, err := models.SearchFiles(keyword, tenantID)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "搜索文件失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "搜索文件成功",
"data": files,
}
}
c.ServeJSON()
}
// GetMyFiles 获取当前用户的文件列表
func (c *FileController) GetMyFiles() {
// 从JWT中间件获取用户信息
userID, ok := c.Ctx.Input.GetData("userId").(int)
if !ok || userID <= 0 {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "用户未登录或登录已过期",
}
c.ServeJSON()
return
}
files, err := models.GetFilesByUserID(userID)
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败: " + err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取成功",
"data": files,
}
}
c.ServeJSON()
}
// GetFilesPublic 不需要认证的获取文件信息接口
func (c *FileController) GetFilesPublic() {
files, err := models.GetAllFiles()
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取文件列表失败",
"error": err.Error(),
}
} else {
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "获取文件列表成功",
"data": files,
}
}
c.ServeJSON()
}
// Post 处理文件上传
func (c *FileController) Post() {
// 从JWT中间件获取用户信息
userID, ok := c.Ctx.Input.GetData("userId").(int)
if !ok || userID <= 0 {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "用户未登录或登录已过期",
}
c.ServeJSON()
return
}
username, _ := c.Ctx.Input.GetData("username").(string)
if username == "" {
username = "unknown"
}
// 获取上传的文件
file, header, err := c.GetFile("file")
if err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "获取上传文件失败: " + err.Error(),
}
c.ServeJSON()
return
}
defer file.Close()
// 获取文件基本信息
originalName := header.Filename
fileSize := header.Size
fileExt := strings.ToLower(filepath.Ext(originalName))
fileName := strings.TrimSuffix(originalName, fileExt)
// 获取分类(可选)
category := c.GetString("category")
if category == "" {
category = "未分类"
}
// 获取租户ID可选从请求参数或中间件获取
tenantID := c.GetString("tenant_id")
if tenantID == "" {
tenantID = "default"
}
// 生成日期路径(年/月/日)
now := time.Now()
datePath := now.Format("2006/01/02")
// 目录改成 server 文件夹目录下的 uploads
uploadDir := filepath.Join("uploads", datePath)
// 清理路径
uploadDir = filepath.Clean(uploadDir)
// 确保目录存在
if err := os.MkdirAll(uploadDir, 0755); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "创建上传目录失败: " + err.Error(),
}
c.ServeJSON()
return
}
// 生成唯一文件名(时间戳 + 原始文件名)
timestamp := now.Format("20060102150405")
uniqueFileName := timestamp + "_" + originalName
savePath := path.Join(uploadDir, uniqueFileName)
// 计算相对路径(用于存储到数据库)
relativePath := path.Join("uploads", datePath, uniqueFileName)
// 保存文件
if err := c.SaveToFile("file", savePath); err != nil {
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "保存文件失败: " + err.Error(),
}
c.ServeJSON()
return
}
// 获取文件类型
fileType := "other"
switch fileExt {
case ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp":
fileType = "image"
case ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".txt":
fileType = "document"
case ".mp4", ".avi", ".mov", ".wmv":
fileType = "video"
case ".mp3", ".wav", ".flac":
fileType = "audio"
case ".zip", ".rar", ".7z":
fileType = "archive"
}
// 构造文件URL相对路径
fileURL := "/" + relativePath
// 创建文件信息记录
fileInfo := models.FileInfo{
TenantID: tenantID,
UserID: userID,
FileName: fileName,
OriginalName: originalName,
FilePath: relativePath,
FileURL: fileURL,
FileSize: fileSize,
FileType: fileType,
FileExt: fileExt,
Category: category,
UploadBy: username,
UploadTime: now,
}
// 保存到数据库
id, err := models.AddFile(&fileInfo)
if err != nil {
// 如果数据库保存失败,删除已上传的文件
os.Remove(savePath)
c.Data["json"] = map[string]interface{}{
"success": false,
"message": "保存文件信息失败: " + err.Error(),
}
c.ServeJSON()
return
}
fileInfo.ID = id
// 返回成功响应
c.Data["json"] = map[string]interface{}{
"success": true,
"message": "文件上传成功",
"data": fileInfo,
}
c.ServeJSON()
}