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() }