github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/service/share/manage.go (about)

     1  package share
     2  
     3  import (
     4  	"net/url"
     5  	"time"
     6  
     7  	model "github.com/cloudreve/Cloudreve/v3/models"
     8  	"github.com/cloudreve/Cloudreve/v3/pkg/hashid"
     9  	"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
    10  	"github.com/gin-gonic/gin"
    11  )
    12  
    13  // ShareCreateService 创建新分享服务
    14  type ShareCreateService struct {
    15  	SourceID        string `json:"id" binding:"required"`
    16  	IsDir           bool   `json:"is_dir"`
    17  	Password        string `json:"password" binding:"max=255"`
    18  	RemainDownloads int    `json:"downloads"`
    19  	Expire          int    `json:"expire"`
    20  	Preview         bool   `json:"preview"`
    21  }
    22  
    23  // ShareUpdateService 分享更新服务
    24  type ShareUpdateService struct {
    25  	Prop  string `json:"prop" binding:"required,eq=password|eq=preview_enabled"`
    26  	Value string `json:"value" binding:"max=255"`
    27  }
    28  
    29  // Delete 删除分享
    30  func (service *Service) Delete(c *gin.Context, user *model.User) serializer.Response {
    31  	share := model.GetShareByHashID(c.Param("id"))
    32  	if share == nil || share.Creator().ID != user.ID {
    33  		return serializer.Err(serializer.CodeShareLinkNotFound, "", nil)
    34  	}
    35  
    36  	if err := share.Delete(); err != nil {
    37  		return serializer.DBErr("Failed to delete share record", err)
    38  	}
    39  
    40  	return serializer.Response{}
    41  }
    42  
    43  // Update 更新分享属性
    44  func (service *ShareUpdateService) Update(c *gin.Context) serializer.Response {
    45  	shareCtx, _ := c.Get("share")
    46  	share := shareCtx.(*model.Share)
    47  
    48  	switch service.Prop {
    49  	case "password":
    50  		err := share.Update(map[string]interface{}{"password": service.Value})
    51  		if err != nil {
    52  			return serializer.DBErr("Failed to update share record", err)
    53  		}
    54  	case "preview_enabled":
    55  		value := service.Value == "true"
    56  		err := share.Update(map[string]interface{}{"preview_enabled": value})
    57  		if err != nil {
    58  			return serializer.DBErr("Failed to update share record", err)
    59  		}
    60  		return serializer.Response{
    61  			Data: value,
    62  		}
    63  	}
    64  	return serializer.Response{
    65  		Data: service.Value,
    66  	}
    67  }
    68  
    69  // Create 创建新分享
    70  func (service *ShareCreateService) Create(c *gin.Context) serializer.Response {
    71  	userCtx, _ := c.Get("user")
    72  	user := userCtx.(*model.User)
    73  
    74  	// 是否拥有权限
    75  	if !user.Group.ShareEnabled {
    76  		return serializer.Err(serializer.CodeGroupNotAllowed, "", nil)
    77  	}
    78  
    79  	// 源对象真实ID
    80  	var (
    81  		sourceID   uint
    82  		sourceName string
    83  		err        error
    84  	)
    85  	if service.IsDir {
    86  		sourceID, err = hashid.DecodeHashID(service.SourceID, hashid.FolderID)
    87  	} else {
    88  		sourceID, err = hashid.DecodeHashID(service.SourceID, hashid.FileID)
    89  	}
    90  	if err != nil {
    91  		return serializer.Err(serializer.CodeNotFound, "", nil)
    92  	}
    93  
    94  	// 对象是否存在
    95  	exist := true
    96  	if service.IsDir {
    97  		folder, err := model.GetFoldersByIDs([]uint{sourceID}, user.ID)
    98  		if err != nil || len(folder) == 0 {
    99  			exist = false
   100  		} else {
   101  			sourceName = folder[0].Name
   102  		}
   103  	} else {
   104  		file, err := model.GetFilesByIDs([]uint{sourceID}, user.ID)
   105  		if err != nil || len(file) == 0 {
   106  			exist = false
   107  		} else {
   108  			sourceName = file[0].Name
   109  		}
   110  	}
   111  	if !exist {
   112  		return serializer.Err(serializer.CodeNotFound, "", nil)
   113  	}
   114  
   115  	newShare := model.Share{
   116  		Password:        service.Password,
   117  		IsDir:           service.IsDir,
   118  		UserID:          user.ID,
   119  		SourceID:        sourceID,
   120  		RemainDownloads: -1,
   121  		PreviewEnabled:  service.Preview,
   122  		SourceName:      sourceName,
   123  	}
   124  
   125  	// 如果开启了自动过期
   126  	if service.RemainDownloads > 0 {
   127  		expires := time.Now().Add(time.Duration(service.Expire) * time.Second)
   128  		newShare.RemainDownloads = service.RemainDownloads
   129  		newShare.Expires = &expires
   130  	}
   131  
   132  	// 创建分享
   133  	id, err := newShare.Create()
   134  	if err != nil {
   135  		return serializer.DBErr("Failed to create share link record", err)
   136  	}
   137  
   138  	// 获取分享的唯一id
   139  	uid := hashid.HashID(id, hashid.ShareID)
   140  	// 最终得到分享链接
   141  	siteURL := model.GetSiteURL()
   142  	sharePath, _ := url.Parse("/s/" + uid)
   143  	shareURL := siteURL.ResolveReference(sharePath)
   144  
   145  	return serializer.Response{
   146  		Code: 0,
   147  		Data: shareURL.String(),
   148  	}
   149  
   150  }