From 75bc4038db8d630485ffdf65a735961dddff58dd Mon Sep 17 00:00:00 2001 From: martin <406615373@qq.com> Date: Sat, 25 Jul 2026 20:10:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E8=B6=8A=E6=9D=83=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/logic/admin/data_governance.go | 2 +- internal/logic/admin/file.go | 6 +-- internal/logic/common/storage.go | 39 ++++++++++++++------ internal/logic/common/storage_task_result.go | 4 +- internal/logic/task/data_tasks.go | 2 +- internal/logic/task/sync_image_worker.go | 2 +- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/internal/logic/admin/data_governance.go b/internal/logic/admin/data_governance.go index 851b2e5..c1148ca 100644 --- a/internal/logic/admin/data_governance.go +++ b/internal/logic/admin/data_governance.go @@ -185,7 +185,7 @@ func deleteExpiredFiles(ctx context.Context, fileSvc *common.FileService, cutoff for _, f := range batch { if fileSvc != nil { // FileService.Delete 删对象(失败仅告警)后删行;返回硬错误表示行未删。 - if err := fileSvc.Delete(ctx, f.ID); err != nil { + if err := fileSvc.Delete(ctx, f.ID, 0); err != nil { g.Log().Warningf(ctx, "file retention: delete file %d failed: %v", f.ID, err) continue } diff --git a/internal/logic/admin/file.go b/internal/logic/admin/file.go index 9ce857b..314c569 100644 --- a/internal/logic/admin/file.go +++ b/internal/logic/admin/file.go @@ -174,9 +174,9 @@ func (s *sAdmin) FileDownload(ctx context.Context, req *v1.FileDownloadReq) (*v1 } var url string if req.Variant == "thumb" { - url, err = svc.GetThumbnailURL(ctx, req.Id, req.Width) + url, err = svc.GetThumbnailURL(ctx, req.Id, req.Width, 0) } else { - url, err = svc.GetDownloadURL(ctx, req.Id) + url, err = svc.GetDownloadURL(ctx, req.Id, 0) } if err != nil { return nil, err @@ -198,7 +198,7 @@ func (s *sAdmin) FileDelete(ctx context.Context, req *v1.FileDeleteReq) (*v1.Fil if err != nil { return nil, err } - if err := svc.Delete(ctx, req.Id); err != nil { + if err := svc.Delete(ctx, req.Id, 0); err != nil { return nil, err } return &v1.FileDeleteRes{}, nil diff --git a/internal/logic/common/storage.go b/internal/logic/common/storage.go index ea80396..e81eb3d 100644 --- a/internal/logic/common/storage.go +++ b/internal/logic/common/storage.go @@ -176,11 +176,16 @@ func (s *FileService) serveURL(fileID int64, thumb bool, width int) string { // // 对象存储走预签名 URL(OSS/S3/COS 直接访问桶);local provider 不支持预签名, // 返回应用层 serve 端点的相对 URL(由 handler 鉴权后流式返回内容)。 -func (s *FileService) GetDownloadURL(ctx context.Context, fileID int64) (string, error) { +// +// tenantID 用于跨租户隔离——传入该文件所属租户 ID,查询条件自动追加 tenant_id 过滤。 +// 管理后台等跨租户场景传入 0 表示不做 tenant 过滤(仅按 id 查询)。 +func (s *FileService) GetDownloadURL(ctx context.Context, fileID int64, tenantID int64) (string, error) { var record *FileRecord - err := dao.FilFiles.Ctx(ctx). - Where("id", fileID). - Scan(&record) + q := dao.FilFiles.Ctx(ctx).Where("id", fileID) + if tenantID > 0 { + q = q.Where("tenant_id", tenantID) + } + err := q.Scan(&record) if err != nil { return "", gerror.Wrapf(err, "query file %d", fileID) } @@ -198,11 +203,16 @@ func (s *FileService) GetDownloadURL(ctx context.Context, fileID int64) (string, // 非图片文件(以及不支持原生图片处理的 provider)回退到原图对象。 // // local provider 无服务端图片处理能力,返回原图的 serve URL(前端 CSS 缩放)。 -func (s *FileService) GetThumbnailURL(ctx context.Context, fileID int64, width int) (string, error) { +// +// tenantID 用于跨租户隔离——传入该文件所属租户 ID,查询条件自动追加 tenant_id 过滤。 +// 管理后台等跨租户场景传入 0 表示不做 tenant 过滤(仅按 id 查询)。 +func (s *FileService) GetThumbnailURL(ctx context.Context, fileID int64, width int, tenantID int64) (string, error) { var record *FileRecord - err := dao.FilFiles.Ctx(ctx). - Where("id", fileID). - Scan(&record) + q := dao.FilFiles.Ctx(ctx).Where("id", fileID) + if tenantID > 0 { + q = q.Where("tenant_id", tenantID) + } + err := q.Scan(&record) if err != nil { return "", gerror.Wrapf(err, "query file %d", fileID) } @@ -225,11 +235,16 @@ func (s *FileService) GetThumbnailURL(ctx context.Context, fileID int64, width i } // Delete 从存储中删除文件并删除其元数据记录。 -func (s *FileService) Delete(ctx context.Context, fileID int64) error { +// +// tenantID 用于跨租户隔离——传入该文件所属租户 ID,查询条件自动追加 tenant_id 过滤。 +// 管理后台的保留期清理等跨租户场景传入 0 表示不做 tenant 过滤(仅按 id 查询)。 +func (s *FileService) Delete(ctx context.Context, fileID int64, tenantID int64) error { var record *FileRecord - err := dao.FilFiles.Ctx(ctx). - Where("id", fileID). - Scan(&record) + q := dao.FilFiles.Ctx(ctx).Where("id", fileID) + if tenantID > 0 { + q = q.Where("tenant_id", tenantID) + } + err := q.Scan(&record) if err != nil { return gerror.Wrapf(err, "query file %d", fileID) } diff --git a/internal/logic/common/storage_task_result.go b/internal/logic/common/storage_task_result.go index e587286..f93df8e 100644 --- a/internal/logic/common/storage_task_result.go +++ b/internal/logic/common/storage_task_result.go @@ -51,10 +51,10 @@ func TaskResultImageURLs(ctx context.Context, tenantID int64, publicTaskID strin if thumbWidth <= 0 { thumbWidth = 600 } - if u, e := svc.GetThumbnailURL(ctx, rec.ID, thumbWidth); e == nil { + if u, e := svc.GetThumbnailURL(ctx, rec.ID, thumbWidth, tenantID); e == nil { thumbURL = u } - if u, e := svc.GetDownloadURL(ctx, rec.ID); e == nil { + if u, e := svc.GetDownloadURL(ctx, rec.ID, tenantID); e == nil { originalURL = u } return thumbURL, originalURL diff --git a/internal/logic/task/data_tasks.go b/internal/logic/task/data_tasks.go index c9b1926..83ac0c5 100644 --- a/internal/logic/task/data_tasks.go +++ b/internal/logic/task/data_tasks.go @@ -128,7 +128,7 @@ func handleDataExport(ctx context.Context, payload json.RawMessage) (any, error) } // 下载链接:local 返回应用层 serve 相对 URL,OSS 返回预签名 URL(前端按是否 http 分支)。 - downloadURL, err := svc.GetDownloadURL(ctx, rec.ID) + downloadURL, err := svc.GetDownloadURL(ctx, rec.ID, p.TenantID) if err != nil { g.Log().Warningf(ctx, "data export: get download url for tenant %d: %v", p.TenantID, err) } diff --git a/internal/logic/task/sync_image_worker.go b/internal/logic/task/sync_image_worker.go index 220d00a..5bcba84 100644 --- a/internal/logic/task/sync_image_worker.go +++ b/internal/logic/task/sync_image_worker.go @@ -751,7 +751,7 @@ func rehostImage(ctx context.Context, job *SyncImageJob, data []byte, contentTyp if err != nil { return "", err } - return fs.GetDownloadURL(ctx, rec.ID) + return fs.GetDownloadURL(ctx, rec.ID, job.TenantID) } // syncImageDownloadClient 用于从上游返回的图片 URL 下载**已生成好的**图片做 re-host。