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