初始化2
This commit is contained in:
@@ -41,6 +41,24 @@ func (c *AuthController) Login(ctx *gin.Context) {
|
||||
utils.Success(ctx, resp)
|
||||
}
|
||||
|
||||
// AppLogin 应用登录(用户名+appId)
|
||||
// POST /api/auth/app-login
|
||||
func (c *AuthController) AppLogin(ctx *gin.Context) {
|
||||
var req dto.AppLoginRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(ctx, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := c.authService.AppLogin(&req)
|
||||
if err != nil {
|
||||
utils.Unauthorized(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, resp)
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
// POST /api/auth/register
|
||||
func (c *AuthController) Register(ctx *gin.Context) {
|
||||
|
||||
@@ -33,7 +33,7 @@ func (c *ChunkUploadController) Init(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := c.chunkService.InitUpload(req.FileName, req.FileSize, req.MD5, req.FolderID, ownerID, req.PolicyID)
|
||||
result, err := c.chunkService.InitUpload(req.FileName, req.FileSize, req.MD5, uint64(req.FolderID), ownerID, req.PolicyID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
@@ -79,6 +79,32 @@ func (c *ChunkUploadController) UploadChunk(ctx *gin.Context) {
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ConfirmChunk 确认MinIO分片上传完成(客户端直传后调用)
|
||||
// POST /api/file/upload/chunk/:uploadId/:index/confirm
|
||||
func (c *ChunkUploadController) ConfirmChunk(ctx *gin.Context) {
|
||||
uploadID := ctx.Param("uploadId")
|
||||
indexStr := ctx.Param("index")
|
||||
|
||||
var index int
|
||||
if _, err := fmt.Sscanf(indexStr, "%d", &index); err != nil {
|
||||
utils.BadRequest(ctx, "分片索引无效")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
ETag string `json:"etag"`
|
||||
}
|
||||
ctx.ShouldBindJSON(&req)
|
||||
|
||||
result, err := c.chunkService.UploadChunkMinIO(uploadID, index, req.ETag)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// Merge 合并分片完成上传
|
||||
// POST /api/file/upload/merge/:uploadId
|
||||
func (c *ChunkUploadController) Merge(ctx *gin.Context) {
|
||||
|
||||
@@ -37,12 +37,24 @@ func (c *FileController) Upload(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取目标文件夹ID
|
||||
folderIDStr := ctx.DefaultQuery("folder_id", "0")
|
||||
// 获取目标文件夹ID(优先查询参数, 其次表单字段)
|
||||
folderIDStr := ctx.DefaultQuery("folder_id", "")
|
||||
if folderIDStr == "" {
|
||||
folderIDStr = ctx.PostForm("folder_id")
|
||||
}
|
||||
if folderIDStr == "" {
|
||||
folderIDStr = "0"
|
||||
}
|
||||
folderID, _ := strconv.ParseUint(folderIDStr, 10, 64)
|
||||
|
||||
// 获取存储策略ID(可选, 0=使用默认策略)
|
||||
policyIDStr := ctx.DefaultQuery("storage_policy_id", "0")
|
||||
policyIDStr := ctx.DefaultQuery("storage_policy_id", "")
|
||||
if policyIDStr == "" {
|
||||
policyIDStr = ctx.PostForm("storage_policy_id")
|
||||
}
|
||||
if policyIDStr == "" {
|
||||
policyIDStr = "0"
|
||||
}
|
||||
storagePolicyID, _ := strconv.ParseUint(policyIDStr, 10, 64)
|
||||
|
||||
// 调用服务层
|
||||
@@ -108,7 +120,8 @@ func (c *FileController) GetDownloadURL(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
downloadURL, err := c.fileService.GetDownloadURL(id)
|
||||
token := ctx.GetHeader("token")
|
||||
downloadURL, err := c.fileService.GetDownloadURL(id, token)
|
||||
if err != nil {
|
||||
utils.NotFound(ctx, err.Error())
|
||||
return
|
||||
@@ -126,7 +139,9 @@ func (c *FileController) GetPreviewURL(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
previewURL, err := c.fileService.GetPreviewURL(id)
|
||||
token := ctx.GetHeader("token")
|
||||
|
||||
previewURL, err := c.fileService.GetPreviewURL(id, token)
|
||||
if err != nil {
|
||||
utils.NotFound(ctx, err.Error())
|
||||
return
|
||||
@@ -221,14 +236,14 @@ func (c *FileController) Move(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
var req struct {
|
||||
TargetFolderID uint64 `json:"target_folder_id" binding:"required"`
|
||||
TargetFolderID dto.StringID `json:"target_folder_id" binding:"required"`
|
||||
}
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(ctx, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.fileService.Move(id, req.TargetFolderID, ownerID); err != nil {
|
||||
if err := c.fileService.Move(id, uint64(req.TargetFolderID), ownerID); err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
@@ -354,3 +369,73 @@ func (c *FileController) ListTrashed(ctx *gin.Context) {
|
||||
|
||||
utils.Success(ctx, results)
|
||||
}
|
||||
|
||||
// GrantPermission 授权文件权限
|
||||
// POST /api/file/:id/grant
|
||||
func (c *FileController) GrantPermission(ctx *gin.Context) {
|
||||
ownerID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.GrantPermissionRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(ctx, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.fileService.GrantPermission(id, ownerID, &req); err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.SuccessWithMessage(ctx, "授权成功", nil)
|
||||
}
|
||||
|
||||
// RevokePermission 撤销文件权限
|
||||
// DELETE /api/file/:id/grant/:permId
|
||||
func (c *FileController) RevokePermission(ctx *gin.Context) {
|
||||
ownerID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
fileID, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
|
||||
permID, err := strconv.ParseUint(ctx.Param("permId"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的权限ID")
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.fileService.RevokePermission(fileID, permID, ownerID); err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.SuccessWithMessage(ctx, "已撤销", nil)
|
||||
}
|
||||
|
||||
// ListPermissions 查看文件的授权列表
|
||||
// GET /api/file/:id/grant
|
||||
func (c *FileController) ListPermissions(ctx *gin.Context) {
|
||||
ownerID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
fileID, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
|
||||
results, err := c.fileService.ListPermissions(fileID, ownerID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, results)
|
||||
}
|
||||
|
||||
@@ -44,8 +44,27 @@ func (c *FolderController) Create(ctx *gin.Context) {
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ListChildren 获取文件夹子项
|
||||
// GET /api/folder/:id/children 或 GET /api/folder/root
|
||||
// GetByBizID 根据业务ID获取文件夹信息
|
||||
// GET /api/folder/by-bizid/:bizid
|
||||
func (c *FolderController) GetByBizID(ctx *gin.Context) {
|
||||
ownerID := middleware.GetCurrentUserID(ctx)
|
||||
bizID := ctx.Param("bizid")
|
||||
if bizID == "" {
|
||||
utils.BadRequest(ctx, "业务ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := c.folderService.GetByBizID(bizID, ownerID)
|
||||
if err != nil {
|
||||
utils.NotFound(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ListChildren 获取文件夹子项(支持分页)
|
||||
// GET /api/folder/:id/children?page=1&page_size=50
|
||||
func (c *FolderController) ListChildren(ctx *gin.Context) {
|
||||
ownerID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
@@ -62,7 +81,17 @@ func (c *FolderController) ListChildren(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
result, err := c.folderService.ListChildren(folderID, ownerID)
|
||||
// 分页参数
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "50"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 || pageSize > 200 {
|
||||
pageSize = 50
|
||||
}
|
||||
|
||||
result, err := c.folderService.ListChildren(folderID, ownerID, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
|
||||
@@ -10,6 +10,24 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetSystemLogs 获取系统运行日志
|
||||
// GET /api/admin/monitor/logs?limit=200
|
||||
func (c *MonitorController) GetSystemLogs(ctx *gin.Context) {
|
||||
limit := 200
|
||||
if l, err := parseIntQuery(ctx, "limit"); err == nil && l > 0 {
|
||||
limit = l
|
||||
}
|
||||
if limit > 2000 {
|
||||
limit = 2000
|
||||
}
|
||||
|
||||
entries := utils.LogBuf.Get(limit)
|
||||
utils.Success(ctx, gin.H{
|
||||
"total": utils.LogBuf.Count(),
|
||||
"entries": entries,
|
||||
})
|
||||
}
|
||||
|
||||
// MonitorController 监控控制器
|
||||
type MonitorController struct {
|
||||
fileRepo *repository.FileRepository
|
||||
|
||||
374
server/controller/openapi_file_controller.go
Normal file
374
server/controller/openapi_file_controller.go
Normal file
@@ -0,0 +1,374 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"seeyon-filesystem/config"
|
||||
"seeyon-filesystem/dto"
|
||||
"seeyon-filesystem/middleware"
|
||||
"seeyon-filesystem/model"
|
||||
"seeyon-filesystem/service"
|
||||
"seeyon-filesystem/storage"
|
||||
"seeyon-filesystem/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// OpenAPIFileController 对外文件API控制器
|
||||
type OpenAPIFileController struct {
|
||||
fileService *service.FileService
|
||||
folderService *service.FolderService
|
||||
chunkService *service.ChunkUploadService
|
||||
}
|
||||
|
||||
func NewOpenAPIFileController() *OpenAPIFileController {
|
||||
return &OpenAPIFileController{
|
||||
fileService: service.NewFileService(),
|
||||
folderService: service.NewFolderService(),
|
||||
chunkService: service.NewChunkUploadService(),
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 1. 根据父文件夹ID分页查询 ==========
|
||||
|
||||
// ListByFolder 分页查询文件夹下的文件和子文件夹
|
||||
// GET /api/openapi/files?folder_id=0&page=1&page_size=20
|
||||
// 返回树状结构: 文件夹 + 文件
|
||||
func (c *OpenAPIFileController) ListByFolder(ctx *gin.Context) {
|
||||
userID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
folderIDStr := ctx.DefaultQuery("folder_id", "0")
|
||||
folderID, _ := strconv.ParseUint(folderIDStr, 10, 64)
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "50"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 || pageSize > 200 {
|
||||
pageSize = 50
|
||||
}
|
||||
|
||||
// 获取用户角色
|
||||
roleIDs := getUserRoleIDs(userID)
|
||||
|
||||
// 查询文件夹
|
||||
folders, err := getFoldersByParent(folderID, userID, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, "查询文件夹失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询文件
|
||||
files, totalFiles, err := getFilesByFolder(folderID, userID, roleIDs, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, "查询文件失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 组装树状结构
|
||||
result := dto.OpenAPIListResult{
|
||||
FolderID: folderID,
|
||||
TotalFiles: totalFiles,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
for _, f := range folders {
|
||||
childCount := getFolderChildCount(f.ID)
|
||||
result.Folders = append(result.Folders, dto.OpenAPIFolderVO{
|
||||
ID: dto.StringID(f.ID),
|
||||
Name: f.Name,
|
||||
ParentID: dto.StringID(f.ParentID),
|
||||
ChildCount: childCount,
|
||||
CreatedAt: f.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
result.Files = append(result.Files, dto.OpenAPIFileVO{
|
||||
ID: dto.StringID(f.ID),
|
||||
Name: f.Name,
|
||||
Extension: f.Extension,
|
||||
Size: f.Size,
|
||||
MD5: f.MD5,
|
||||
MimeType: f.MimeType,
|
||||
DownloadURL: getCDNOrPresignedURL(&f),
|
||||
CreatedAt: f.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ========== 2. 按名称搜索返回树状结构 ==========
|
||||
|
||||
// SearchTree 按文件名/文件夹名搜索, 返回树状结构
|
||||
// GET /api/openapi/files/search?keyword=报告&page=1&page_size=20
|
||||
func (c *OpenAPIFileController) SearchTree(ctx *gin.Context) {
|
||||
userID := middleware.GetCurrentUserID(ctx)
|
||||
keyword := ctx.Query("keyword")
|
||||
if keyword == "" {
|
||||
utils.BadRequest(ctx, "请输入搜索关键词")
|
||||
return
|
||||
}
|
||||
|
||||
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "50"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 || pageSize > 200 {
|
||||
pageSize = 50
|
||||
}
|
||||
|
||||
roleIDs := getUserRoleIDs(userID)
|
||||
|
||||
// 搜索文件
|
||||
files, total, err := searchFilesByName(userID, roleIDs, keyword, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, "搜索失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 搜索文件夹
|
||||
folders, err := searchFoldersByName(userID, keyword, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, "搜索失败")
|
||||
return
|
||||
}
|
||||
|
||||
result := dto.OpenAPISearchResult{
|
||||
Keyword: keyword,
|
||||
TotalFiles: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
for _, f := range folders {
|
||||
result.Folders = append(result.Folders, dto.OpenAPIFolderVO{
|
||||
ID: dto.StringID(f.ID),
|
||||
Name: f.Name,
|
||||
ParentID: dto.StringID(f.ParentID),
|
||||
CreatedAt: f.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
result.Files = append(result.Files, dto.OpenAPIFileVO{
|
||||
ID: dto.StringID(f.ID),
|
||||
Name: f.Name,
|
||||
Extension: f.Extension,
|
||||
Size: f.Size,
|
||||
MD5: f.MD5,
|
||||
MimeType: f.MimeType,
|
||||
DownloadURL: getCDNOrPresignedURL(&f),
|
||||
CreatedAt: f.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ========== 3. 分片上传/下载 ==========
|
||||
|
||||
// ChunkUploadInit 初始化分片上传
|
||||
// POST /api/openapi/files/upload/init
|
||||
func (c *OpenAPIFileController) ChunkUploadInit(ctx *gin.Context) {
|
||||
userID := middleware.GetCurrentUserID(ctx)
|
||||
|
||||
var req dto.ChunkUploadInitRequest
|
||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||
utils.BadRequest(ctx, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result, err := c.chunkService.InitUpload(req.FileName, req.FileSize, req.MD5, uint64(req.FolderID), userID, req.PolicyID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ChunkUpload 上传分片
|
||||
// PUT /api/openapi/files/upload/chunk/:uploadId/:index
|
||||
func (c *OpenAPIFileController) ChunkUpload(ctx *gin.Context) {
|
||||
uploadID := ctx.Param("uploadId")
|
||||
indexStr := ctx.Param("index")
|
||||
index, err := strconv.Atoi(indexStr)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "分片索引无效")
|
||||
return
|
||||
}
|
||||
|
||||
checksum := ctx.GetHeader("X-Checksum")
|
||||
|
||||
file, err := ctx.FormFile("chunk")
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "请上传分片文件")
|
||||
return
|
||||
}
|
||||
|
||||
reader, err := file.Open()
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "读取分片失败")
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
result, err := c.chunkService.UploadChunk(uploadID, index, reader, checksum)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ChunkMerge 合并分片
|
||||
// POST /api/openapi/files/upload/merge/:uploadId
|
||||
func (c *OpenAPIFileController) ChunkMerge(ctx *gin.Context) {
|
||||
uploadID := ctx.Param("uploadId")
|
||||
|
||||
result, err := c.chunkService.MergeChunks(uploadID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// ChunkProgress 查询上传进度
|
||||
// GET /api/openapi/files/upload/progress/:uploadId
|
||||
func (c *OpenAPIFileController) ChunkProgress(ctx *gin.Context) {
|
||||
uploadID := ctx.Param("uploadId")
|
||||
|
||||
result, err := c.chunkService.GetUploadProgress(uploadID)
|
||||
if err != nil {
|
||||
utils.NotFound(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.Success(ctx, result)
|
||||
}
|
||||
|
||||
// Download 下载文件
|
||||
// GET /api/openapi/files/:id/download
|
||||
func (c *OpenAPIFileController) Download(ctx *gin.Context) {
|
||||
userID := middleware.GetCurrentUserID(ctx)
|
||||
fileID, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
|
||||
reader, file, err := c.fileService.Download(fileID, userID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file.Name))
|
||||
ctx.Header("Content-Type", file.MimeType)
|
||||
ctx.Header("Content-Length", strconv.FormatInt(file.Size, 10))
|
||||
ctx.DataFromReader(http.StatusOK, file.Size, file.MimeType, reader, nil)
|
||||
}
|
||||
|
||||
// Preview 预览文件
|
||||
// GET /api/openapi/files/:id/preview
|
||||
func (c *OpenAPIFileController) Preview(ctx *gin.Context) {
|
||||
userID := middleware.GetCurrentUserID(ctx)
|
||||
fileID, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.BadRequest(ctx, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
|
||||
reader, file, err := c.fileService.Download(fileID, userID)
|
||||
if err != nil {
|
||||
utils.ServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", file.Name))
|
||||
ctx.Header("Content-Type", file.MimeType)
|
||||
ctx.Header("Content-Length", strconv.FormatInt(file.Size, 10))
|
||||
ctx.DataFromReader(http.StatusOK, file.Size, file.MimeType, reader, nil)
|
||||
}
|
||||
|
||||
// ========== 辅助函数 ==========
|
||||
|
||||
func getUserRoleIDs(userID uint64) []uint64 {
|
||||
var userRoles []model.UserRole
|
||||
config.DB.Where("user_id = ?", userID).Find(&userRoles)
|
||||
ids := make([]uint64, 0, len(userRoles))
|
||||
for _, ur := range userRoles {
|
||||
ids = append(ids, ur.RoleID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func getFoldersByParent(parentID, ownerID uint64, page, pageSize int) ([]model.Folder, error) {
|
||||
var folders []model.Folder
|
||||
err := config.DB.Where("parent_id = ? AND owner_id = ? AND status = 1", parentID, ownerID).
|
||||
Order("name ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&folders).Error
|
||||
return folders, err
|
||||
}
|
||||
|
||||
func getFilesByFolder(folderID, userID uint64, roleIDs []uint64, page, pageSize int) ([]model.File, int64, error) {
|
||||
var files []model.File
|
||||
query := config.DB.Where("folder_id = ? AND owner_id = ? AND status = 1", folderID, userID)
|
||||
var total int64
|
||||
query.Model(&model.File{}).Count(&total)
|
||||
err := query.Order("name ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&files).Error
|
||||
return files, total, err
|
||||
}
|
||||
|
||||
func getFolderChildCount(folderID uint64) int64 {
|
||||
var count int64
|
||||
config.DB.Model(&model.Folder{}).Where("parent_id = ? AND status = 1", folderID).Count(&count)
|
||||
return count
|
||||
}
|
||||
|
||||
func searchFilesByName(userID uint64, roleIDs []uint64, keyword string, page, pageSize int) ([]model.File, int64, error) {
|
||||
var files []model.File
|
||||
query := config.DB.Where("owner_id = ? AND status = 1 AND name LIKE ?", userID, "%"+keyword+"%")
|
||||
var total int64
|
||||
query.Model(&model.File{}).Count(&total)
|
||||
err := query.Order("created_at DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&files).Error
|
||||
return files, total, err
|
||||
}
|
||||
|
||||
func searchFoldersByName(ownerID uint64, keyword string, page, pageSize int) ([]model.Folder, error) {
|
||||
var folders []model.Folder
|
||||
err := config.DB.Where("owner_id = ? AND status = 1 AND name LIKE ?", ownerID, "%"+keyword+"%").
|
||||
Order("name ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&folders).Error
|
||||
return folders, err
|
||||
}
|
||||
|
||||
func getCDNOrPresignedURL(file *model.File) string {
|
||||
if file.StorageKey == "" {
|
||||
return ""
|
||||
}
|
||||
engine, err := storage.GetEngineByPolicyID(file.StoragePolicyID)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if localEngine, ok := engine.(*storage.LocalEngine); ok {
|
||||
return localEngine.GetURL(file.StorageKey)
|
||||
}
|
||||
if minioEngine, ok := engine.(*storage.MinIOEngine); ok {
|
||||
url, err := minioEngine.GetPresignedURL(file.StorageKey, 24*time.Hour)
|
||||
if err == nil {
|
||||
return url
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user