You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.0 KiB
151 lines
4.0 KiB
package share
|
|
|
|
import (
|
|
"net/url"
|
|
"time"
|
|
|
|
model "github.com/cloudreve/Cloudreve/v3/models"
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/hashid"
|
|
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ShareCreateService 创建新分享服务
|
|
type ShareCreateService struct {
|
|
SourceID string `json:"id" binding:"required"`
|
|
IsDir bool `json:"is_dir"`
|
|
Password string `json:"password" binding:"max=255"`
|
|
RemainDownloads int `json:"downloads"`
|
|
Expire int `json:"expire"`
|
|
Preview bool `json:"preview"`
|
|
}
|
|
|
|
// ShareUpdateService 分享更新服务
|
|
type ShareUpdateService struct {
|
|
Prop string `json:"prop" binding:"required,eq=password|eq=preview_enabled"`
|
|
Value string `json:"value" binding:"max=255"`
|
|
}
|
|
|
|
// Delete 删除分享
|
|
func (service *Service) Delete(c *gin.Context, user *model.User) serializer.Response {
|
|
share := model.GetShareByHashID(c.Param("id"))
|
|
if share == nil || share.Creator().ID != user.ID {
|
|
return serializer.Err(serializer.CodeNotFound, "分享不存在", nil)
|
|
}
|
|
|
|
if err := share.Delete(); err != nil {
|
|
return serializer.Err(serializer.CodeDBError, "分享删除失败", err)
|
|
}
|
|
|
|
return serializer.Response{}
|
|
}
|
|
|
|
// Update 更新分享属性
|
|
func (service *ShareUpdateService) Update(c *gin.Context) serializer.Response {
|
|
shareCtx, _ := c.Get("share")
|
|
share := shareCtx.(*model.Share)
|
|
|
|
switch service.Prop {
|
|
case "password":
|
|
err := share.Update(map[string]interface{}{"password": service.Value})
|
|
if err != nil {
|
|
return serializer.Err(serializer.CodeDBError, "无法更新分享密码", err)
|
|
}
|
|
case "preview_enabled":
|
|
value := service.Value == "true"
|
|
err := share.Update(map[string]interface{}{"preview_enabled": value})
|
|
if err != nil {
|
|
return serializer.Err(serializer.CodeDBError, "无法更新分享属性", err)
|
|
}
|
|
return serializer.Response{
|
|
Data: value,
|
|
}
|
|
}
|
|
return serializer.Response{
|
|
Data: service.Value,
|
|
}
|
|
}
|
|
|
|
// Create 创建新分享
|
|
func (service *ShareCreateService) Create(c *gin.Context) serializer.Response {
|
|
userCtx, _ := c.Get("user")
|
|
user := userCtx.(*model.User)
|
|
|
|
// 是否拥有权限
|
|
if !user.Group.ShareEnabled {
|
|
return serializer.Err(serializer.CodeNoPermissionErr, "您无权创建分享链接", nil)
|
|
}
|
|
|
|
// 源对象真实ID
|
|
var (
|
|
sourceID uint
|
|
sourceName string
|
|
err error
|
|
)
|
|
if service.IsDir {
|
|
sourceID, err = hashid.DecodeHashID(service.SourceID, hashid.FolderID)
|
|
} else {
|
|
sourceID, err = hashid.DecodeHashID(service.SourceID, hashid.FileID)
|
|
}
|
|
if err != nil {
|
|
return serializer.Err(serializer.CodeNotFound, "原始资源不存在", nil)
|
|
}
|
|
|
|
// 对象是否存在
|
|
exist := true
|
|
if service.IsDir {
|
|
folder, err := model.GetFoldersByIDs([]uint{sourceID}, user.ID)
|
|
if err != nil || len(folder) == 0 {
|
|
exist = false
|
|
} else {
|
|
sourceName = folder[0].Name
|
|
}
|
|
} else {
|
|
file, err := model.GetFilesByIDs([]uint{sourceID}, user.ID)
|
|
if err != nil || len(file) == 0 {
|
|
exist = false
|
|
} else {
|
|
sourceName = file[0].Name
|
|
}
|
|
}
|
|
if !exist {
|
|
return serializer.Err(serializer.CodeNotFound, "原始资源不存在", nil)
|
|
}
|
|
|
|
newShare := model.Share{
|
|
Password: service.Password,
|
|
IsDir: service.IsDir,
|
|
UserID: user.ID,
|
|
SourceID: sourceID,
|
|
RemainDownloads: -1,
|
|
PreviewEnabled: service.Preview,
|
|
SourceName: sourceName,
|
|
}
|
|
|
|
// 如果开启了自动过期
|
|
if service.RemainDownloads > 0 {
|
|
expires := time.Now().Add(time.Duration(service.Expire) * time.Second)
|
|
newShare.RemainDownloads = service.RemainDownloads
|
|
newShare.Expires = &expires
|
|
}
|
|
|
|
// 创建分享
|
|
id, err := newShare.Create()
|
|
if err != nil {
|
|
return serializer.Err(serializer.CodeDBError, "分享链接创建失败", err)
|
|
}
|
|
|
|
// 获取分享的唯一id
|
|
uid := hashid.HashID(id, hashid.ShareID)
|
|
// 最终得到分享链接
|
|
siteURL := model.GetSiteURL()
|
|
sharePath, _ := url.Parse("/s/" + uid)
|
|
shareURL := siteURL.ResolveReference(sharePath)
|
|
|
|
return serializer.Response{
|
|
Code: 0,
|
|
Data: shareURL.String(),
|
|
}
|
|
|
|
}
|