mirror of https://github.com/cloudreve/Cloudreve
refactor(thumb): thumb logic for slave policy
parent
ae118c337e
commit
7cb5e68b78
|
@ -48,6 +48,12 @@ func Init(path string, statics fs.FS) {
|
||||||
model.Init()
|
model.Init()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"slave",
|
||||||
|
func() {
|
||||||
|
model.InitSlaveDefaults()
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"both",
|
"both",
|
||||||
func() {
|
func() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
|
@ -125,3 +126,9 @@ Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; verti
|
||||||
{Name: "wopi_max_size", Value: "52428800", Type: "wopi"},
|
{Name: "wopi_max_size", Value: "52428800", Type: "wopi"},
|
||||||
{Name: "wopi_session_timeout", Value: "36000", Type: "wopi"},
|
{Name: "wopi_session_timeout", Value: "36000", Type: "wopi"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InitSlaveDefaults() {
|
||||||
|
for _, setting := range defaultSettings {
|
||||||
|
cache.Set("setting_"+setting.Name, setting.Value, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -464,10 +464,5 @@ func (file *File) GetPosition() string {
|
||||||
// `True` does not guarantee the load request will success in next step, but the client
|
// `True` does not guarantee the load request will success in next step, but the client
|
||||||
// should try to load and fallback to default placeholder in case error returned.
|
// should try to load and fallback to default placeholder in case error returned.
|
||||||
func (file *File) ShouldLoadThumb() bool {
|
func (file *File) ShouldLoadThumb() bool {
|
||||||
switch file.GetPolicy().Type {
|
return file.MetadataSerialized[ThumbStatusMetadataKey] != ThumbStatusNotAvailable
|
||||||
case "local":
|
|
||||||
return file.MetadataSerialized[ThumbStatusMetadataKey] != ThumbStatusNotAvailable
|
|
||||||
default:
|
|
||||||
return file.PicInfo != "" && file.PicInfo != " " && file.PicInfo != "null,null"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||||
|
@ -68,18 +67,8 @@ type PolicyOption struct {
|
||||||
// Set this to `true` to force the request to use path-style addressing,
|
// Set this to `true` to force the request to use path-style addressing,
|
||||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY `
|
// i.e., `http://s3.amazonaws.com/BUCKET/KEY `
|
||||||
S3ForcePathStyle bool `json:"s3_path_style"`
|
S3ForcePathStyle bool `json:"s3_path_style"`
|
||||||
}
|
// File extensions that support thumbnail generation using native policy API.
|
||||||
|
ThumbExts []string `json:"thumb_exts,omitempty"`
|
||||||
// thumbSuffix 支持缩略图处理的文件扩展名
|
|
||||||
var thumbSuffix = map[string][]string{
|
|
||||||
"local": {},
|
|
||||||
"qiniu": {".psd", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".tiff", ".bmp"},
|
|
||||||
"oss": {".jpg", ".jpeg", ".png", ".gif", ".webp", ".tiff", ".bmp"},
|
|
||||||
"cos": {".jpg", ".jpeg", ".png", ".gif", ".webp", ".tiff", ".bmp"},
|
|
||||||
"upyun": {".svg", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".tiff", ".bmp"},
|
|
||||||
"s3": {},
|
|
||||||
"remote": {},
|
|
||||||
"onedrive": {"*"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -192,17 +181,6 @@ func (policy *Policy) IsDirectlyPreview() bool {
|
||||||
return policy.Type == "local"
|
return policy.Type == "local"
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsThumbExist 给定文件名,返回此存储策略下是否可能存在缩略图
|
|
||||||
func (policy *Policy) IsThumbExist(name string) bool {
|
|
||||||
if list, ok := thumbSuffix[policy.Type]; ok {
|
|
||||||
if len(list) == 1 && list[0] == "*" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return util.ContainsString(list, strings.ToLower(filepath.Ext(name)))
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTransitUpload 返回此策略上传给定size文件时是否需要服务端中转
|
// IsTransitUpload 返回此策略上传给定size文件时是否需要服务端中转
|
||||||
func (policy *Policy) IsTransitUpload(size uint64) bool {
|
func (policy *Policy) IsTransitUpload(size uint64) bool {
|
||||||
return policy.Type == "local"
|
return policy.Type == "local"
|
||||||
|
|
|
@ -11,7 +11,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrorThumbNotExist = fmt.Errorf("thumb not exist")
|
ErrorThumbNotExist = fmt.Errorf("thumb not exist")
|
||||||
|
ErrorThumbNotSupported = fmt.Errorf("thumb not supported")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler 存储策略适配器
|
// Handler 存储策略适配器
|
||||||
|
@ -28,6 +29,9 @@ type Handler interface {
|
||||||
|
|
||||||
// 获取缩略图,可直接在ContentResponse中返回文件数据流,也可指
|
// 获取缩略图,可直接在ContentResponse中返回文件数据流,也可指
|
||||||
// 定为重定向
|
// 定为重定向
|
||||||
|
// 如果缩略图不存在, 且需要 Cloudreve 代理生成并上传,应返回 ErrorThumbNotExist,生
|
||||||
|
// 成的缩略图文件存储规则与本机策略一致。
|
||||||
|
// 如果不支持此文件的缩略图,并且不希望后续继续请求此缩略图,应返回 ErrorThumbNotSupported
|
||||||
Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error)
|
Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error)
|
||||||
|
|
||||||
// 获取外链/下载地址,
|
// 获取外链/下载地址,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
||||||
|
@ -196,13 +197,18 @@ func (handler Driver) Delete(ctx context.Context, files []string) ([]string, err
|
||||||
|
|
||||||
// Thumb 获取文件缩略图
|
// Thumb 获取文件缩略图
|
||||||
func (handler Driver) Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error) {
|
func (handler Driver) Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error) {
|
||||||
if file.MetadataSerialized[model.ThumbStatusMetadataKey] == model.ThumbStatusNotExist {
|
// Quick check thumb existence on master.
|
||||||
|
if conf.SystemConfig.Mode == "master" && file.MetadataSerialized[model.ThumbStatusMetadataKey] == model.ThumbStatusNotExist {
|
||||||
// Tell invoker to generate a thumb
|
// Tell invoker to generate a thumb
|
||||||
return nil, driver.ErrorThumbNotExist
|
return nil, driver.ErrorThumbNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbFile, err := handler.Get(ctx, file.SourceName+model.GetSettingByNameWithDefault("thumb_file_suffix", "._thumb"))
|
thumbFile, err := handler.Get(ctx, file.SourceName+model.GetSettingByNameWithDefault("thumb_file_suffix", "._thumb"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
err = fmt.Errorf("thumb not exist: %w (%w)", err, driver.ErrorThumbNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,18 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/driver"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/request"
|
"github.com/cloudreve/Cloudreve/v3/pkg/request"
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
||||||
|
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Driver 远程存储策略适配器
|
// Driver 远程存储策略适配器
|
||||||
|
@ -205,8 +208,18 @@ func (handler *Driver) Delete(ctx context.Context, files []string) ([]string, er
|
||||||
|
|
||||||
// Thumb 获取文件缩略图
|
// Thumb 获取文件缩略图
|
||||||
func (handler *Driver) Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error) {
|
func (handler *Driver) Thumb(ctx context.Context, file *model.File) (*response.ContentResponse, error) {
|
||||||
|
// quick check by extensions
|
||||||
|
supported := []string{"png", "jpg", "jpeg", "gif"}
|
||||||
|
if len(handler.Policy.OptionsSerialized.ThumbExts) > 0 {
|
||||||
|
supported = handler.Policy.OptionsSerialized.ThumbExts
|
||||||
|
}
|
||||||
|
|
||||||
|
if !util.IsInExtensionList(supported, file.Name) {
|
||||||
|
return nil, driver.ErrorThumbNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
sourcePath := base64.RawURLEncoding.EncodeToString([]byte(file.SourceName))
|
sourcePath := base64.RawURLEncoding.EncodeToString([]byte(file.SourceName))
|
||||||
thumbURL := handler.getAPIUrl("thumb") + "/" + sourcePath
|
thumbURL := fmt.Sprintf("%s/%s/%s", handler.getAPIUrl("thumb"), sourcePath, filepath.Ext(file.Name))
|
||||||
ttl := model.GetIntSetting("preview_timeout", 60)
|
ttl := model.GetIntSetting("preview_timeout", 60)
|
||||||
signedThumbURL, err := auth.SignURI(handler.AuthInstance, thumbURL, int64(ttl))
|
signedThumbURL, err := auth.SignURI(handler.AuthInstance, thumbURL, int64(ttl))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -64,10 +64,6 @@ func (fs *FileSystem) AddFile(ctx context.Context, parent *model.Folder, file fs
|
||||||
UploadSessionID: uploadInfo.UploadSessionID,
|
UploadSessionID: uploadInfo.UploadSessionID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if fs.Policy.IsThumbExist(uploadInfo.FileName) {
|
|
||||||
newFile.PicInfo = "1,1"
|
|
||||||
}
|
|
||||||
|
|
||||||
err = newFile.Create()
|
err = newFile.Create()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -97,9 +93,10 @@ func (fs *FileSystem) GetPhysicalFileContent(ctx context.Context, path string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preview 预览文件
|
// Preview 预览文件
|
||||||
// path - 文件虚拟路径
|
//
|
||||||
// isText - 是否为文本文件,文本文件会忽略重定向,直接由
|
// path - 文件虚拟路径
|
||||||
// 服务端拉取中转给用户,故会对文件大小进行限制
|
// isText - 是否为文本文件,文本文件会忽略重定向,直接由
|
||||||
|
// 服务端拉取中转给用户,故会对文件大小进行限制
|
||||||
func (fs *FileSystem) Preview(ctx context.Context, id uint, isText bool) (*response.ContentResponse, error) {
|
func (fs *FileSystem) Preview(ctx context.Context, id uint, isText bool) (*response.ContentResponse, error) {
|
||||||
err := fs.resetFileIDIfNotExist(ctx, id)
|
err := fs.resetFileIDIfNotExist(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -177,23 +177,12 @@ func GenericAfterUpdate(ctx context.Context, fs *FileSystem, newFile fsctx.FileH
|
||||||
// SlaveAfterUpload Slave模式下上传完成钩子
|
// SlaveAfterUpload Slave模式下上传完成钩子
|
||||||
func SlaveAfterUpload(session *serializer.UploadSession) Hook {
|
func SlaveAfterUpload(session *serializer.UploadSession) Hook {
|
||||||
return func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
return func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
||||||
fileInfo := fileHeader.Info()
|
|
||||||
|
|
||||||
// 构造一个model.File,用于生成缩略图
|
|
||||||
file := model.File{
|
|
||||||
Name: fileInfo.FileName,
|
|
||||||
SourceName: fileInfo.SavePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
if session.Callback == "" {
|
if session.Callback == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送回调请求
|
// 发送回调请求
|
||||||
callbackBody := serializer.UploadCallback{
|
callbackBody := serializer.UploadCallback{}
|
||||||
PicInfo: file.PicInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
return cluster.RemoteCallback(session.Callback, callbackBody)
|
return cluster.RemoteCallback(session.Callback, callbackBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,10 +257,6 @@ func HookPopPlaceholderToFile(picInfo string) Hook {
|
||||||
return func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
return func(ctx context.Context, fs *FileSystem, fileHeader fsctx.FileHeader) error {
|
||||||
fileInfo := fileHeader.Info()
|
fileInfo := fileHeader.Info()
|
||||||
fileModel := fileInfo.Model.(*model.File)
|
fileModel := fileInfo.Model.(*model.File)
|
||||||
if picInfo == "" && fs.Policy.IsThumbExist(fileInfo.FileName) {
|
|
||||||
picInfo = "1,1"
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileModel.PopChunkToFile(fileInfo.LastModified, picInfo)
|
return fileModel.PopChunkToFile(fileInfo.LastModified, picInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,9 @@ func (fs *FileSystem) GetThumb(ctx context.Context, id uint) (*response.ContentR
|
||||||
// Regenerate thumb if the thumb is not initialized yet
|
// Regenerate thumb if the thumb is not initialized yet
|
||||||
fs.GenerateThumbnail(ctx, &fs.FileTarget[0])
|
fs.GenerateThumbnail(ctx, &fs.FileTarget[0])
|
||||||
res, err = fs.Handler.Thumb(ctx, &fs.FileTarget[0])
|
res, err = fs.Handler.Thumb(ctx, &fs.FileTarget[0])
|
||||||
|
} else if errors.Is(err, driver.ErrorThumbNotSupported) {
|
||||||
|
// Policy handler explicitly indicates thumb not available
|
||||||
|
_ = updateThumbStatus(&fs.FileTarget[0], model.ThumbStatusNotAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil && conf.SystemConfig.Mode == "master" {
|
if err == nil && conf.SystemConfig.Mode == "master" {
|
||||||
|
@ -157,6 +160,10 @@ func updateThumbStatus(file *model.File, status string) error {
|
||||||
model.ThumbStatusMetadataKey: status,
|
model.ThumbStatusMetadataKey: status,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
if file.MetadataSerialized == nil {
|
||||||
|
file.MetadataSerialized = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
file.MetadataSerialized[model.ThumbStatusMetadataKey] = status
|
file.MetadataSerialized[model.ThumbStatusMetadataKey] = status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package filesystem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||||
|
@ -63,20 +62,5 @@ func (fs *FileSystem) ValidateExtension(ctx context.Context, fileName string) bo
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsInExtensionList(fs.Policy.OptionsSerialized.FileType, fileName)
|
return util.IsInExtensionList(fs.Policy.OptionsSerialized.FileType, fileName)
|
||||||
}
|
|
||||||
|
|
||||||
// IsInExtensionList 返回文件的扩展名是否在给定的列表范围内
|
|
||||||
func IsInExtensionList(extList []string, fileName string) bool {
|
|
||||||
ext := strings.ToLower(filepath.Ext(fileName))
|
|
||||||
// 无扩展名时
|
|
||||||
if len(ext) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if util.ContainsString(extList, ext[1:]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,7 @@ func NewThumbFromFile(file io.Reader, name string) (*Thumb, error) {
|
||||||
var err error
|
var err error
|
||||||
var img image.Image
|
var img image.Image
|
||||||
switch ext[1:] {
|
switch ext[1:] {
|
||||||
case "jpg":
|
case "jpg", "jpeg":
|
||||||
img, err = jpeg.Decode(file)
|
|
||||||
case "jpeg":
|
|
||||||
img, err = jpeg.Decode(file)
|
img, err = jpeg.Decode(file)
|
||||||
case "gif":
|
case "gif":
|
||||||
img, err = gif.Decode(file)
|
img, err = gif.Decode(file)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -32,6 +33,21 @@ func ContainsUint(s []uint, e uint) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInExtensionList 返回文件的扩展名是否在给定的列表范围内
|
||||||
|
func IsInExtensionList(extList []string, fileName string) bool {
|
||||||
|
ext := strings.ToLower(filepath.Ext(fileName))
|
||||||
|
// 无扩展名时
|
||||||
|
if len(ext) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ContainsString(extList, ext[1:]) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ContainsString 返回list中是否包含
|
// ContainsString 返回list中是否包含
|
||||||
func ContainsString(s []string, e string) bool {
|
func ContainsString(s []string, e string) bool {
|
||||||
for _, a := range s {
|
for _, a := range s {
|
||||||
|
|
|
@ -64,7 +64,7 @@ func InitSlaveRouter() *gin.Engine {
|
||||||
// 预览 / 外链
|
// 预览 / 外链
|
||||||
v3.GET("source/:speed/:path/:name", controllers.SlavePreview)
|
v3.GET("source/:speed/:path/:name", controllers.SlavePreview)
|
||||||
// 缩略图
|
// 缩略图
|
||||||
v3.GET("thumb/:path", controllers.SlaveThumb)
|
v3.GET("thumb/:path/:ext", controllers.SlaveThumb)
|
||||||
// 删除文件
|
// 删除文件
|
||||||
v3.POST("delete", controllers.SlaveDelete)
|
v3.POST("delete", controllers.SlaveDelete)
|
||||||
// 列出文件
|
// 列出文件
|
||||||
|
|
|
@ -32,6 +32,7 @@ type SlaveDownloadService struct {
|
||||||
// SlaveFileService 从机单文件文件相关服务
|
// SlaveFileService 从机单文件文件相关服务
|
||||||
type SlaveFileService struct {
|
type SlaveFileService struct {
|
||||||
PathEncoded string `uri:"path" binding:"required"`
|
PathEncoded string `uri:"path" binding:"required"`
|
||||||
|
Ext string `uri:"ext"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SlaveFilesService 从机多文件相关服务
|
// SlaveFilesService 从机多文件相关服务
|
||||||
|
@ -132,7 +133,7 @@ func (service *SlaveFileService) Thumb(ctx context.Context, c *gin.Context) seri
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return serializer.Err(serializer.CodeFileNotFound, "", err)
|
return serializer.Err(serializer.CodeFileNotFound, "", err)
|
||||||
}
|
}
|
||||||
fs.FileTarget = []model.File{{SourceName: string(fileSource), PicInfo: "1,1"}}
|
fs.FileTarget = []model.File{{SourceName: string(fileSource), Name: fmt.Sprintf("%s.%s", fileSource, service.Ext), PicInfo: "1,1"}}
|
||||||
|
|
||||||
// 获取缩略图
|
// 获取缩略图
|
||||||
resp, err := fs.GetThumb(ctx, 0)
|
resp, err := fs.GetThumb(ctx, 0)
|
||||||
|
|
Loading…
Reference in New Issue