Files
tyc-server-v2/app/main/api/internal/logic/upload/serveuploadedfilelogic.go
2026-02-12 15:16:54 +08:00

67 lines
1.8 KiB
Go

package upload
import (
"context"
"os"
"path/filepath"
"strings"
"tyc-server/app/main/api/internal/svc"
"tyc-server/app/main/api/internal/types"
"tyc-server/common/xerr"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type ServeUploadedFileLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewServeUploadedFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ServeUploadedFileLogic {
return &ServeUploadedFileLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *ServeUploadedFileLogic) ServeUploadedFile(req *types.ServeUploadedFileReq) (resp *types.ServeUploadedFileResp, err error) {
fileName := strings.TrimSpace(req.FileName)
if fileName == "" {
return nil, errors.Wrap(xerr.NewErrMsg("缺少文件名"), "fileName empty")
}
// 只允许文件名,禁止路径穿越
if strings.Contains(fileName, "..") || filepath.Base(fileName) != fileName {
return nil, errors.Wrap(xerr.NewErrMsg("非法文件名"), fileName)
}
candidates := []string{
"data/uploads",
"../data/uploads",
"../../data/uploads",
"../../../data/uploads",
}
for _, c := range candidates {
abs, _ := filepath.Abs(c)
fullPath := filepath.Join(abs, fileName)
if info, err := os.Stat(fullPath); err == nil && !info.IsDir() {
contentType := "image/jpeg"
if strings.HasSuffix(strings.ToLower(fileName), ".png") {
contentType = "image/png"
} else if strings.HasSuffix(strings.ToLower(fileName), ".gif") {
contentType = "image/gif"
} else if strings.HasSuffix(strings.ToLower(fileName), ".webp") {
contentType = "image/webp"
}
return &types.ServeUploadedFileResp{
FilePath: fullPath,
ContentType: contentType,
}, nil
}
}
return nil, errors.Wrapf(xerr.NewErrMsg("文件不存在"), "fileName=%s", fileName)
}