583 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			583 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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()
 | 
						||
}
 |